blob: 1adff65c0d0ff095de32e21081bc859851a31be8 [file] [log] [blame]
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import doctest
import os
import tempfile
import unittest
from apache_beam.dataframe import doctests
SAMPLE_DOCTEST = '''
>>> df = pd.DataFrame({'Animal': ['Falcon', 'Falcon',
... 'Parrot', 'Parrot'],
... 'Max Speed': [380., 370., 24., 26.]})
>>> df
Animal Max Speed
0 Falcon 380.0
1 Falcon 370.0
2 Parrot 24.0
3 Parrot 26.0
>>> df.groupby(['Animal']).mean()
Max Speed
Animal
Falcon 375.0
Parrot 25.0
'''
CHECK_USES_DEFERRED_DATAFRAMES = '''
>>> type(pd).__name__
'FakePandasObject'
>>> type(pd.DataFrame([]))
<class 'apache_beam.dataframe.frames.DeferredDataFrame'>
>>> type(pd.DataFrame.from_dict({'a': [1, 2], 'b': [3, 4]}))
<class 'apache_beam.dataframe.frames.DeferredDataFrame'>
>>> pd.Index(range(10))
RangeIndex(start=0, stop=10, step=1)
'''
WONT_IMPLEMENT_RAISING_TESTS = '''
>>> import apache_beam
>>> raise apache_beam.dataframe.frame_base.WontImplementError('anything')
ignored exception
>>> pd.Series(range(10)).__array__()
ignored result
'''
ERROR_RAISING_NAME_ERROR_TESTS = '''
>>> import apache_beam
>>> raise %s('anything')
ignored exception
>>> raise NameError
ignored exception
>>> undefined_name
ignored exception
>>> 2 + 2
4
>>> raise NameError
failed exception
'''
WONT_IMPLEMENT_RAISING_NAME_ERROR_TESTS = ERROR_RAISING_NAME_ERROR_TESTS % (
'apache_beam.dataframe.frame_base.WontImplementError', )
NOT_IMPLEMENTED_RAISING_TESTS = '''
>>> import apache_beam
>>> raise NotImplementedError('anything')
ignored exception
'''
NOT_IMPLEMENTED_RAISING_NAME_ERROR_TESTS = ERROR_RAISING_NAME_ERROR_TESTS % (
'NotImplementedError', )
FAILED_ASSIGNMENT = '''
>>> def foo(): raise NotImplementedError()
>>> res = 'old_value'
>>> res = foo()
>>> print(res)
ignored NameError
'''
RST_IPYTHON = '''
Here is an example
.. ipython::
2 + 2
some multi-line examples
.. ipython::
def foo(x):
return x * x
foo(4)
foo(
4
)
In [100]: def foo(x):
....: return x * x * x
....:
foo(5)
history is preserved
foo(3)
foo(4)
and finally an example with pandas
.. ipython::
pd.Series([1, 2, 3]).max()
This one should be skipped:
.. ipython::
@verbatim
not run or tested
and someting that'll fail (due to fake vs. real pandas)
.. ipython::
type(pd)
'''
class DoctestTest(unittest.TestCase):
def test_good(self):
result = doctests.teststring(SAMPLE_DOCTEST, report=False)
self.assertEqual(result.attempted, 3)
self.assertEqual(result.failed, 0)
def test_failure(self):
result = doctests.teststring(
SAMPLE_DOCTEST.replace('25.0', '25.00001'), report=False)
self.assertEqual(result.attempted, 3)
self.assertEqual(result.failed, 1)
def test_uses_beam_dataframes(self):
result = doctests.teststring(CHECK_USES_DEFERRED_DATAFRAMES, report=False)
self.assertNotEqual(result.attempted, 0)
self.assertEqual(result.failed, 0)
def test_file(self):
with tempfile.TemporaryDirectory() as dir:
filename = os.path.join(dir, 'tests.py')
with open(filename, 'w') as fout:
fout.write(SAMPLE_DOCTEST)
result = doctests.testfile(filename, module_relative=False, report=False)
self.assertEqual(result.attempted, 3)
self.assertEqual(result.failed, 0)
def test_file_uses_beam_dataframes(self):
with tempfile.TemporaryDirectory() as dir:
filename = os.path.join(dir, 'tests.py')
with open(filename, 'w') as fout:
fout.write(CHECK_USES_DEFERRED_DATAFRAMES)
result = doctests.testfile(filename, module_relative=False, report=False)
self.assertNotEqual(result.attempted, 0)
self.assertEqual(result.failed, 0)
def test_wont_implement(self):
result = doctests.teststring(
WONT_IMPLEMENT_RAISING_TESTS,
optionflags=doctest.ELLIPSIS,
wont_implement_ok=True)
self.assertNotEqual(result.attempted, 0)
self.assertEqual(result.failed, 0)
result = doctests.teststring(
WONT_IMPLEMENT_RAISING_TESTS,
optionflags=doctest.IGNORE_EXCEPTION_DETAIL,
wont_implement_ok=True)
self.assertNotEqual(result.attempted, 0)
self.assertEqual(result.failed, 0)
def test_wont_implement_followed_by_name_error(self):
result = doctests.teststring(
WONT_IMPLEMENT_RAISING_NAME_ERROR_TESTS,
optionflags=doctest.ELLIPSIS,
wont_implement_ok=True)
self.assertEqual(result.attempted, 6)
self.assertEqual(result.failed, 1) # Only the very last one.
def test_not_implemented(self):
result = doctests.teststring(
NOT_IMPLEMENTED_RAISING_TESTS,
optionflags=doctest.ELLIPSIS,
not_implemented_ok=True)
self.assertNotEqual(result.attempted, 0)
self.assertEqual(result.failed, 0)
result = doctests.teststring(
NOT_IMPLEMENTED_RAISING_TESTS,
optionflags=doctest.IGNORE_EXCEPTION_DETAIL,
not_implemented_ok=True)
self.assertNotEqual(result.attempted, 0)
self.assertEqual(result.failed, 0)
def test_not_implemented_followed_by_name_error(self):
result = doctests.teststring(
NOT_IMPLEMENTED_RAISING_NAME_ERROR_TESTS,
optionflags=doctest.ELLIPSIS,
not_implemented_ok=True)
self.assertEqual(result.attempted, 6)
self.assertEqual(result.failed, 1) # Only the very last one.
def test_failed_assignment(self):
result = doctests.teststring(
FAILED_ASSIGNMENT,
optionflags=doctest.ELLIPSIS,
not_implemented_ok=True)
self.assertNotEqual(result.attempted, 0)
self.assertEqual(result.failed, 0)
def test_rst_ipython(self):
try:
import IPython
except ImportError:
raise unittest.SkipTest('IPython not available')
result = doctests.test_rst_ipython(RST_IPYTHON, 'test_rst_ipython')
self.assertEqual(result.attempted, 8)
self.assertEqual(result.failed, 1) # Only the very last one.
if __name__ == '__main__':
unittest.main()