github.com/apache/beam/sdks/v2@v2.48.2/python/apache_beam/dataframe/doctests_test.py (about)

     1  #
     2  # Licensed to the Apache Software Foundation (ASF) under one or more
     3  # contributor license agreements.  See the NOTICE file distributed with
     4  # this work for additional information regarding copyright ownership.
     5  # The ASF licenses this file to You under the Apache License, Version 2.0
     6  # (the "License"); you may not use this file except in compliance with
     7  # the License.  You may obtain a copy of the License at
     8  #
     9  #    http://www.apache.org/licenses/LICENSE-2.0
    10  #
    11  # Unless required by applicable law or agreed to in writing, software
    12  # distributed under the License is distributed on an "AS IS" BASIS,
    13  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  # See the License for the specific language governing permissions and
    15  # limitations under the License.
    16  
    17  import doctest
    18  import os
    19  import tempfile
    20  import unittest
    21  
    22  from apache_beam.dataframe import doctests
    23  
    24  SAMPLE_DOCTEST = '''
    25  >>> df = pd.DataFrame({'Animal': ['Falcon', 'Falcon',
    26  ...                               'Parrot', 'Parrot'],
    27  ...                    'Max Speed': [380., 370., 24., 26.]})
    28  >>> df
    29     Animal  Max Speed
    30  0  Falcon      380.0
    31  1  Falcon      370.0
    32  2  Parrot       24.0
    33  3  Parrot       26.0
    34  >>> df.groupby(['Animal']).mean()
    35          Max Speed
    36  Animal
    37  Falcon      375.0
    38  Parrot       25.0
    39  '''
    40  
    41  CHECK_USES_DEFERRED_DATAFRAMES = '''
    42  >>> type(pd).__name__
    43  'FakePandasObject'
    44  
    45  >>> type(pd.DataFrame([]))
    46  <class 'apache_beam.dataframe.frames.DeferredDataFrame'>
    47  
    48  >>> type(pd.DataFrame.from_dict({'a': [1, 2], 'b': [3, 4]}))
    49  <class 'apache_beam.dataframe.frames.DeferredDataFrame'>
    50  
    51  >>> pd.Index(range(10))
    52  RangeIndex(start=0, stop=10, step=1)
    53  '''
    54  
    55  WONT_IMPLEMENT_RAISING_TESTS = '''
    56  >>> import apache_beam
    57  >>> raise apache_beam.dataframe.frame_base.WontImplementError('anything')
    58  ignored exception
    59  >>> pd.Series(range(10)).__array__()
    60  ignored result
    61  '''
    62  
    63  ERROR_RAISING_NAME_ERROR_TESTS = '''
    64  >>> import apache_beam
    65  >>> raise %s('anything')
    66  ignored exception
    67  >>> raise NameError
    68  ignored exception
    69  >>> undefined_name
    70  ignored exception
    71  >>> 2 + 2
    72  4
    73  >>> raise NameError
    74  failed exception
    75  '''
    76  
    77  WONT_IMPLEMENT_RAISING_NAME_ERROR_TESTS = ERROR_RAISING_NAME_ERROR_TESTS % (
    78      'apache_beam.dataframe.frame_base.WontImplementError', )
    79  
    80  NOT_IMPLEMENTED_RAISING_TESTS = '''
    81  >>> import apache_beam
    82  >>> raise NotImplementedError('anything')
    83  ignored exception
    84  '''
    85  
    86  NOT_IMPLEMENTED_RAISING_NAME_ERROR_TESTS = ERROR_RAISING_NAME_ERROR_TESTS % (
    87      'NotImplementedError', )
    88  
    89  FAILED_ASSIGNMENT = '''
    90  >>> def foo(): raise NotImplementedError()
    91  >>> res = 'old_value'
    92  >>> res = foo()
    93  >>> print(res)
    94  ignored NameError
    95  '''
    96  
    97  RST_IPYTHON = '''
    98  Here is an example
    99  .. ipython::
   100  
   101      2 + 2
   102  
   103  some multi-line examples
   104  
   105  .. ipython::
   106  
   107      def foo(x):
   108          return x * x
   109      foo(4)
   110      foo(
   111          4
   112      )
   113  
   114      In [100]: def foo(x):
   115         ....:     return x * x * x
   116         ....:
   117      foo(5)
   118  
   119  history is preserved
   120  
   121      foo(3)
   122      foo(4)
   123  
   124  and finally an example with pandas
   125  
   126  .. ipython::
   127  
   128      pd.Series([1, 2, 3]).max()
   129  
   130  
   131  This one should be skipped:
   132  
   133  .. ipython::
   134  
   135     @verbatim
   136     not run or tested
   137  
   138  and someting that'll fail (due to fake vs. real pandas)
   139  
   140  .. ipython::
   141  
   142     type(pd)
   143  '''
   144  
   145  
   146  class DoctestTest(unittest.TestCase):
   147    def test_good(self):
   148      result = doctests.teststring(SAMPLE_DOCTEST, report=False)
   149      self.assertEqual(result.attempted, 3)
   150      self.assertEqual(result.failed, 0)
   151  
   152    def test_failure(self):
   153      result = doctests.teststring(
   154          SAMPLE_DOCTEST.replace('25.0', '25.00001'), report=False)
   155      self.assertEqual(result.attempted, 3)
   156      self.assertEqual(result.failed, 1)
   157  
   158    def test_uses_beam_dataframes(self):
   159      result = doctests.teststring(CHECK_USES_DEFERRED_DATAFRAMES, report=False)
   160      self.assertNotEqual(result.attempted, 0)
   161      self.assertEqual(result.failed, 0)
   162  
   163    def test_file(self):
   164      with tempfile.TemporaryDirectory() as dir:
   165        filename = os.path.join(dir, 'tests.py')
   166        with open(filename, 'w') as fout:
   167          fout.write(SAMPLE_DOCTEST)
   168        result = doctests.testfile(filename, module_relative=False, report=False)
   169      self.assertEqual(result.attempted, 3)
   170      self.assertEqual(result.failed, 0)
   171  
   172    def test_file_uses_beam_dataframes(self):
   173      with tempfile.TemporaryDirectory() as dir:
   174        filename = os.path.join(dir, 'tests.py')
   175        with open(filename, 'w') as fout:
   176          fout.write(CHECK_USES_DEFERRED_DATAFRAMES)
   177        result = doctests.testfile(filename, module_relative=False, report=False)
   178      self.assertNotEqual(result.attempted, 0)
   179      self.assertEqual(result.failed, 0)
   180  
   181    def test_wont_implement(self):
   182      result = doctests.teststring(
   183          WONT_IMPLEMENT_RAISING_TESTS,
   184          optionflags=doctest.ELLIPSIS,
   185          wont_implement_ok=True)
   186      self.assertNotEqual(result.attempted, 0)
   187      self.assertEqual(result.failed, 0)
   188  
   189      result = doctests.teststring(
   190          WONT_IMPLEMENT_RAISING_TESTS,
   191          optionflags=doctest.IGNORE_EXCEPTION_DETAIL,
   192          wont_implement_ok=True)
   193      self.assertNotEqual(result.attempted, 0)
   194      self.assertEqual(result.failed, 0)
   195  
   196    def test_wont_implement_followed_by_name_error(self):
   197      result = doctests.teststring(
   198          WONT_IMPLEMENT_RAISING_NAME_ERROR_TESTS,
   199          optionflags=doctest.ELLIPSIS,
   200          wont_implement_ok=True)
   201      self.assertEqual(result.attempted, 6)
   202      self.assertEqual(result.failed, 1)  # Only the very last one.
   203  
   204    def test_not_implemented(self):
   205      result = doctests.teststring(
   206          NOT_IMPLEMENTED_RAISING_TESTS,
   207          optionflags=doctest.ELLIPSIS,
   208          not_implemented_ok=True)
   209      self.assertNotEqual(result.attempted, 0)
   210      self.assertEqual(result.failed, 0)
   211  
   212      result = doctests.teststring(
   213          NOT_IMPLEMENTED_RAISING_TESTS,
   214          optionflags=doctest.IGNORE_EXCEPTION_DETAIL,
   215          not_implemented_ok=True)
   216      self.assertNotEqual(result.attempted, 0)
   217      self.assertEqual(result.failed, 0)
   218  
   219    def test_not_implemented_followed_by_name_error(self):
   220      result = doctests.teststring(
   221          NOT_IMPLEMENTED_RAISING_NAME_ERROR_TESTS,
   222          optionflags=doctest.ELLIPSIS,
   223          not_implemented_ok=True)
   224      self.assertEqual(result.attempted, 6)
   225      self.assertEqual(result.failed, 1)  # Only the very last one.
   226  
   227    def test_failed_assignment(self):
   228      result = doctests.teststring(
   229          FAILED_ASSIGNMENT,
   230          optionflags=doctest.ELLIPSIS,
   231          not_implemented_ok=True)
   232      self.assertNotEqual(result.attempted, 0)
   233      self.assertEqual(result.failed, 0)
   234  
   235    def test_rst_ipython(self):
   236      try:
   237        # pylint: disable=unused-import
   238        import IPython
   239      except ImportError:
   240        raise unittest.SkipTest('IPython not available')
   241      result = doctests.test_rst_ipython(RST_IPYTHON, 'test_rst_ipython')
   242      self.assertEqual(result.attempted, 8)
   243      self.assertEqual(result.failed, 1)  # Only the very last one.
   244  
   245  
   246  if __name__ == '__main__':
   247    unittest.main()