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()