diff options
Diffstat (limited to 'tests/test_autodoc.py')
-rw-r--r-- | tests/test_autodoc.py | 132 |
1 files changed, 84 insertions, 48 deletions
diff --git a/tests/test_autodoc.py b/tests/test_autodoc.py index 7e48d92fa..feaab19f4 100644 --- a/tests/test_autodoc.py +++ b/tests/test_autodoc.py @@ -17,10 +17,9 @@ from warnings import catch_warnings import pytest from docutils.statemachine import ViewList -from six import PY3 from sphinx.ext.autodoc import ( - AutoDirective, ModuleLevelDocumenter, cut_lines, between, ALL, + ModuleLevelDocumenter, cut_lines, between, ALL, merge_autodoc_default_flags, Options ) from sphinx.ext.autodoc.directive import DocumenterBridge, process_documenter_options @@ -30,17 +29,13 @@ from sphinx.util.docutils import LoggingReporter app = None -if PY3: - ROGER_METHOD = ' .. py:classmethod:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)' -else: - ROGER_METHOD = ' .. py:classmethod:: Class.roger(a, e=5, f=6)' - IS_PYPY = platform.python_implementation() == 'PyPy' def do_autodoc(app, objtype, name, options=None): if options is None: options = {} + app.env.temp_data.setdefault('docname', 'index') # set dummy docname doccls = app.registry.documenters[objtype] docoptions = process_documenter_options(doccls, app.config, options) bridge = DocumenterBridge(app.env, LoggingReporter(''), docoptions, 1) @@ -112,7 +107,7 @@ def setup_test(): yield - AutoDirective._special_attrgetters.clear() + app.registry.autodoc_attrgettrs.clear() processed_docstrings = [] @@ -216,7 +211,7 @@ def test_format_signature(): class D: pass - class E(object): + class E: pass # no signature for classes without __init__ for C in (D, E): @@ -226,7 +221,7 @@ def test_format_signature(): def __init__(self, a, b=None): pass - class G(F, object): + class G(F): pass for C in (F, G): assert formatsig('class', 'C', C, None, None) == '(a, b=None)' @@ -243,7 +238,7 @@ def test_format_signature(): some docstring for __init__. ''' - class G2(F2, object): + class G2(F2): pass assert formatsig('class', 'F2', F2, None, None) == \ @@ -291,13 +286,13 @@ def test_format_signature(): @pytest.mark.usefixtures('setup_test') def test_get_doc(): - def getdocl(objtype, obj, encoding=None): + def getdocl(objtype, obj): inst = app.registry.documenters[objtype](directive, 'tmp') inst.object = obj inst.objpath = [obj.__name__] inst.doc_as_attr = False inst.format_signature() # handle docstring signatures! - ds = inst.get_doc(encoding) + ds = inst.get_doc() # for testing purposes, concat them and strip the empty line at the end res = sum(ds, [])[:-1] print(res) @@ -399,7 +394,7 @@ def test_get_doc(): assert getdocl('class', E) == ['Class docstring', '', 'Init docstring'] # class does not have __init__ method - class F(object): + class F: """Class docstring""" # docstring in the __init__ method of base class will be discard @@ -413,7 +408,7 @@ def test_get_doc(): assert getdocl('class', F) == ['Class docstring'] # class has __init__ method with no docstring - class G(object): + class G: """Class docstring""" def __init__(self): pass @@ -566,7 +561,7 @@ def test_attrgetter_using(): getattr_spy.append((obj, name)) return None return getattr(obj, name, *defargs) - AutoDirective._special_attrgetters[type] = special_getattr + app.add_autodoc_attrgetter(type, special_getattr) del getattr_spy[:] inst = app.registry.documenters[objtype](directive, name) @@ -722,7 +717,7 @@ def test_autodoc_undoc_members(app): ' .. py:method:: Class.meth()', ' .. py:classmethod:: Class.moore(a, e, f) -> happiness', ' .. py:attribute:: Class.prop', - ROGER_METHOD, + ' .. py:classmethod:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)', ' .. py:attribute:: Class.skipattr', ' .. py:method:: Class.skipmeth()', ' .. py:attribute:: Class.udocattr', @@ -752,7 +747,7 @@ def test_autodoc_imported_members(app): "imported-members": None, "ignore-module-all": None} actual = do_autodoc(app, 'module', 'target', options) - assert '.. py:function:: add_documenter(cls)' in actual + assert '.. py:function:: save_traceback(app)' in actual @pytest.mark.sphinx('html', testroot='ext-autodoc') @@ -802,7 +797,7 @@ def test_autodoc_special_members(app): ' .. py:method:: Class.meth()', ' .. py:classmethod:: Class.moore(a, e, f) -> happiness', ' .. py:attribute:: Class.prop', - ROGER_METHOD, + ' .. py:classmethod:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)', ' .. py:attribute:: Class.skipattr', ' .. py:method:: Class.skipmeth()', ' .. py:attribute:: Class.udocattr', @@ -875,11 +870,6 @@ def test_autodoc_subclass_of_builtin_class(app): @pytest.mark.sphinx('html', testroot='ext-autodoc') def test_autodoc_inner_class(app): - if PY3: - builtins = ' alias of :class:`builtins.dict`' - else: - builtins = ' alias of :class:`__builtin__.dict`' - options = {"members": None} actual = do_autodoc(app, 'class', 'target.Outer', options) assert list(actual) == [ @@ -905,7 +895,7 @@ def test_autodoc_inner_class(app): ' .. py:attribute:: Outer.factory', ' :module: target', ' ', - builtins + ' alias of :class:`builtins.dict`' ] actual = do_autodoc(app, 'class', 'target.Outer.Inner', options) @@ -974,7 +964,7 @@ def test_autodoc_member_order(app): ' .. py:attribute:: Class.docattr', ' .. py:attribute:: Class.udocattr', ' .. py:attribute:: Class.mdocattr', - ROGER_METHOD, + ' .. py:classmethod:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)', ' .. py:classmethod:: Class.moore(a, e, f) -> happiness', ' .. py:attribute:: Class.inst_attr_inline', ' .. py:attribute:: Class.inst_attr_comment', @@ -993,7 +983,7 @@ def test_autodoc_member_order(app): ' .. py:method:: Class.excludemeth()', ' .. py:method:: Class.meth()', ' .. py:classmethod:: Class.moore(a, e, f) -> happiness', - ROGER_METHOD, + ' .. py:classmethod:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)', ' .. py:method:: Class.skipmeth()', ' .. py:method:: Class.undocmeth()', ' .. py:attribute:: Class._private_inst_attr', @@ -1028,7 +1018,7 @@ def test_autodoc_member_order(app): ' .. py:method:: Class.meth()', ' .. py:classmethod:: Class.moore(a, e, f) -> happiness', ' .. py:attribute:: Class.prop', - ROGER_METHOD, + ' .. py:classmethod:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)', ' .. py:attribute:: Class.skipattr', ' .. py:method:: Class.skipmeth()', ' .. py:attribute:: Class.udocattr', @@ -1359,47 +1349,56 @@ def test_autofunction_for_callable(app): ] -@pytest.mark.sphinx('html', testroot='root') -def test_mocked_module_imports(app): +@pytest.mark.sphinx('html', testroot='ext-autodoc') +def test_mocked_module_imports(app, warning): + # no autodoc_mock_imports options = {"members": 'TestAutodoc,decoratedFunction'} - actual = do_autodoc(app, 'module', 'autodoc_missing_imports', options) + actual = do_autodoc(app, 'module', 'target.need_mocks', options) + assert list(actual) == [] + assert "autodoc: failed to import module 'need_mocks'" in warning.getvalue() + + # with autodoc_mock_imports + app.config.autodoc_mock_imports = [ + 'missing_module', + 'missing_package1', + 'missing_package2', + 'missing_package3', + 'sphinx.missing_module4', + ] + + warning.truncate(0) + actual = do_autodoc(app, 'module', 'target.need_mocks', options) assert list(actual) == [ '', - '.. py:module:: autodoc_missing_imports', + '.. py:module:: target.need_mocks', '', '', '.. py:class:: TestAutodoc', - ' :module: autodoc_missing_imports', + ' :module: target.need_mocks', '', ' TestAutodoc docstring.', ' ', ' ', ' .. py:method:: TestAutodoc.decoratedMethod()', - ' :module: autodoc_missing_imports', + ' :module: target.need_mocks', ' ', ' TestAutodoc::decoratedMethod docstring', ' ', '', '.. py:function:: decoratedFunction()', - ' :module: autodoc_missing_imports', + ' :module: target.need_mocks', '', ' decoratedFunction docstring', ' ' ] + assert warning.getvalue() == '' @pytest.mark.usefixtures('setup_test') def test_partialfunction(): - def call_autodoc(objtype, name): - inst = app.registry.documenters[objtype](directive, name) - inst.generate() - result = list(directive.result) - del directive.result[:] - return result - - options.members = ALL - #options.undoc_members = True - expected = [ + options = {"members": None} + actual = do_autodoc(app, 'module', 'target.partialfunction', options) + assert list(actual) == [ '', '.. py:module:: target.partialfunction', '', @@ -1423,11 +1422,25 @@ def test_partialfunction(): ' ' ] - assert call_autodoc('module', 'target.partialfunction') == expected + +@pytest.mark.usefixtures('setup_test') +def test_coroutine(): + options = {"members": None} + actual = do_autodoc(app, 'class', 'target.coroutine.AsyncClass', options) + assert list(actual) == [ + '', + '.. py:class:: AsyncClass', + ' :module: target.coroutine', + '', + ' ', + ' .. py:method:: AsyncClass.do_coroutine()', + ' :module: target.coroutine', + ' ', + ' A documented coroutine function', + ' ' + ] -@pytest.mark.skipif(sys.version_info < (3, 4), - reason='functools.partialmethod is available on py34 or above') @pytest.mark.sphinx('html', testroot='ext-autodoc') def test_partialmethod(app): expected = [ @@ -1566,6 +1579,29 @@ def test_autodoc_default_options_with_values(app): assert ' .. py:attribute:: EnumCls.val3' not in actual assert ' .. py:attribute:: EnumCls.val4' not in actual + # with :member-order: + app.config.autodoc_default_options = { + 'members': None, + 'member-order': 'bysource', + } + actual = do_autodoc(app, 'class', 'target.Class') + assert list(filter(lambda l: '::' in l, actual)) == [ + '.. py:class:: Class(arg)', + ' .. py:attribute:: Class.descr', + ' .. py:method:: Class.meth()', + ' .. py:method:: Class.skipmeth()', + ' .. py:method:: Class.excludemeth()', + ' .. py:attribute:: Class.attr', + ' .. py:attribute:: Class.prop', + ' .. py:attribute:: Class.docattr', + ' .. py:attribute:: Class.udocattr', + ' .. py:attribute:: Class.mdocattr', + ' .. py:classmethod:: Class.moore(a, e, f) -> happiness', + ' .. py:attribute:: Class.inst_attr_inline', + ' .. py:attribute:: Class.inst_attr_comment', + ' .. py:attribute:: Class.inst_attr_string', + ] + # with :special-members: app.config.autodoc_default_options = { 'special-members': '__init__,__iter__', |