From 3502336b13c868cfdc5679672c1a039b746fded6 Mon Sep 17 00:00:00 2001 From: Anthony Johnson Date: Sat, 25 Feb 2017 12:14:41 -0800 Subject: [PATCH] Add tests for xrefs on Python and JavaScript domains These are just the passing test cases for the domains currently. I am going to patch up issues with nesting on both domains to start, so these are the test cases I'll be testing against. I'll see about addressing the other core domains, or at very least the cpp domain, with similar tests if this looks okay. So far, these tests only test against methods/functions for the basic nesting structure. More complete tests will test additional domain roles. Refs #662 --- tests/roots/test-domain-js/conf.py | 5 ++ tests/roots/test-domain-js/index.rst | 6 ++ tests/roots/test-domain-js/roles.rst | 48 ++++++++++ tests/roots/test-domain-py/conf.py | 5 ++ tests/roots/test-domain-py/index.rst | 7 ++ tests/roots/test-domain-py/module.rst | 31 +++++++ tests/roots/test-domain-py/roles.rst | 48 ++++++++++ tests/test_domain_js.py | 87 ++++++++++++++++++ tests/test_domain_py.py | 122 +++++++++++++++++++++++++- 9 files changed, 358 insertions(+), 1 deletion(-) create mode 100644 tests/roots/test-domain-js/conf.py create mode 100644 tests/roots/test-domain-js/index.rst create mode 100644 tests/roots/test-domain-js/roles.rst create mode 100644 tests/roots/test-domain-py/conf.py create mode 100644 tests/roots/test-domain-py/index.rst create mode 100644 tests/roots/test-domain-py/module.rst create mode 100644 tests/roots/test-domain-py/roles.rst create mode 100644 tests/test_domain_js.py diff --git a/tests/roots/test-domain-js/conf.py b/tests/roots/test-domain-js/conf.py new file mode 100644 index 000000000..c46e40773 --- /dev/null +++ b/tests/roots/test-domain-js/conf.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- + +master_doc = 'index' +html_theme = 'classic' +exclude_patterns = ['_build'] diff --git a/tests/roots/test-domain-js/index.rst b/tests/roots/test-domain-js/index.rst new file mode 100644 index 000000000..59ae7f862 --- /dev/null +++ b/tests/roots/test-domain-js/index.rst @@ -0,0 +1,6 @@ +test-domain-js +============== + +.. toctree:: + + roles diff --git a/tests/roots/test-domain-js/roles.rst b/tests/roots/test-domain-js/roles.rst new file mode 100644 index 000000000..4b6acf184 --- /dev/null +++ b/tests/roots/test-domain-js/roles.rst @@ -0,0 +1,48 @@ +roles +===== + +.. js:class:: TopLevel + +.. js:function:: top_level + +* :js:class:`TopLevel` +* :js:func:`top_level` + + +.. js:class:: NestedParentA + + * Link to :js:func:`child_1` + + .. js:function:: child_1() + + * Link to :js:func:`NestedChildA.subchild_2` + * Link to :js:func:`child_2` + * Link to :any:`any_child` + + .. js:function:: any_child() + + * Link to :js:class:`NestedChildA` + + .. js:class:: NestedChildA + + .. js:function:: subchild_1() + + * Link to :js:func:`subchild_2` + + .. js:function:: subchild_2() + + Link to :js:func:`NestedParentA.child_1` + + .. js:function:: child_2() + + Link to :js:func:`NestedChildA.subchild_1` + +.. js:class:: NestedParentB + + * Link to :js:func:`child_1` + + .. js:function:: child_1() + + * Link to :js:class:`NestedParentB` + +* :js:class:`NestedParentA.NestedChildA` diff --git a/tests/roots/test-domain-py/conf.py b/tests/roots/test-domain-py/conf.py new file mode 100644 index 000000000..c46e40773 --- /dev/null +++ b/tests/roots/test-domain-py/conf.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- + +master_doc = 'index' +html_theme = 'classic' +exclude_patterns = ['_build'] diff --git a/tests/roots/test-domain-py/index.rst b/tests/roots/test-domain-py/index.rst new file mode 100644 index 000000000..35a0c1927 --- /dev/null +++ b/tests/roots/test-domain-py/index.rst @@ -0,0 +1,7 @@ +test-domain-py +============== + +.. toctree:: + + roles + module diff --git a/tests/roots/test-domain-py/module.rst b/tests/roots/test-domain-py/module.rst new file mode 100644 index 000000000..f3f138639 --- /dev/null +++ b/tests/roots/test-domain-py/module.rst @@ -0,0 +1,31 @@ +module +====== + +.. py:module:: module_a.submodule + +* Link to :py:class:`ModTopLevel` + +.. py:class:: ModTopLevel + + * Link to :py:meth:`mod_child_1` + * Link to :py:meth:`ModTopLevel.mod_child_1` + +.. py:method:: ModTopLevel.mod_child_1 + + * Link to :py:meth:`mod_child_2` + +.. py:method:: ModTopLevel.mod_child_2 + + * Link to :py:meth:`module_a.submodule.ModTopLevel.mod_child_1` + +.. py:currentmodule:: None + +.. py:class:: ModNoModule + +.. py:module:: module_b.submodule + +* Link to :py:class:`ModTopLevel` + +.. py:class:: ModTopLevel + + * Link to :py:class:`ModNoModule` diff --git a/tests/roots/test-domain-py/roles.rst b/tests/roots/test-domain-py/roles.rst new file mode 100644 index 000000000..6bff2d2ca --- /dev/null +++ b/tests/roots/test-domain-py/roles.rst @@ -0,0 +1,48 @@ +roles +===== + +.. py:class:: TopLevel + +.. py:method:: top_level + +* :py:class:`TopLevel` +* :py:meth:`top_level` + + +.. py:class:: NestedParentA + + * Link to :py:meth:`child_1` + + .. py:method:: child_1() + + * Link to :py:meth:`NestedChildA.subchild_2` + * Link to :py:meth:`child_2` + * Link to :any:`any_child` + + .. py:method:: any_child() + + * Link to :py:class:`NestedChildA` + + .. py:class:: NestedChildA + + .. py:method:: subchild_1() + + * Link to :py:meth:`subchild_2` + + .. py:method:: subchild_2() + + Link to :py:meth:`NestedParentA.child_1` + + .. py:method:: child_2() + + Link to :py:meth:`NestedChildA.subchild_1` + +.. py:class:: NestedParentB + + * Link to :py:meth:`child_1` + + .. py:method:: child_1() + + * Link to :py:class:`NestedParentB` + +* :py:class:`NestedParentA.NestedChildA` diff --git a/tests/test_domain_js.py b/tests/test_domain_js.py new file mode 100644 index 000000000..d913edd46 --- /dev/null +++ b/tests/test_domain_js.py @@ -0,0 +1,87 @@ +# -*- coding: utf-8 -*- +""" + test_domain_js + ~~~~~~~~~~~~~~ + + Tests the JavaScript Domain + + :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import pytest +from sphinx import addnodes + +from util import assert_node + + +@pytest.mark.sphinx('dummy', testroot='domain-js') +def test_domain_js_xrefs(app, status, warning): + """Domain objects have correct prefixes when looking up xrefs""" + app.builder.build_all() + + def assert_refnode(node, class_name, target, reftype=None, + domain='js'): + attributes = { + 'refdomain': domain, + 'reftarget': target, + } + if reftype is not None: + attributes['reftype'] = reftype + if class_name is not False: + attributes['js:class'] = class_name + assert_node(node, **attributes) + + doctree = app.env.get_doctree('roles') + refnodes = list(doctree.traverse(addnodes.pending_xref)) + assert_refnode(refnodes[0], False, u'TopLevel', u'class') + assert_refnode(refnodes[1], False, u'top_level', u'func') + assert_refnode(refnodes[2], False, u'child_1', u'func') + assert_refnode(refnodes[3], False, u'NestedChildA.subchild_2', u'func') + assert_refnode(refnodes[4], False, u'child_2', u'func') + assert_refnode(refnodes[5], False, u'any_child', domain='') + assert_refnode(refnodes[6], False, u'NestedChildA', u'class') + assert_refnode(refnodes[7], False, u'subchild_2', u'func') + assert_refnode(refnodes[8], False, u'NestedParentA.child_1', u'func') + assert_refnode(refnodes[9], False, u'NestedChildA.subchild_1', u'func') + assert_refnode(refnodes[10], False, u'child_1', u'func') + assert_refnode(refnodes[11], False, u'NestedParentB', u'class') + assert_refnode(refnodes[12], False, u'NestedParentA.NestedChildA', u'class') + assert len(refnodes) == 13 + + +@pytest.mark.sphinx('dummy', testroot='domain-js') +def test_domain_js_objects(app, status, warning): + app.builder.build_all() + + objects = app.env.domains['js'].data['objects'] + + assert objects['TopLevel'] == ('roles', 'class') + assert objects['top_level'] == ('roles', 'function') + assert objects['NestedParentA'] == ('roles', 'class') + assert objects['child_1'] == ('roles', 'function') + assert objects['any_child'] == ('roles', 'function') + assert objects['NestedChildA'] == ('roles', 'class') + assert objects['subchild_1'] == ('roles', 'function') + assert objects['subchild_2'] == ('roles', 'function') + assert objects['child_2'] == ('roles', 'function') + assert objects['NestedParentB'] == ('roles', 'class') + + +@pytest.mark.sphinx('dummy', testroot='domain-js') +def test_domain_js_find_obj(app, status, warning): + + def find_obj(prefix, obj_name, obj_type, searchmode=0): + return app.env.domains['js'].find_obj( + app.env, prefix, obj_name, obj_type, searchmode) + + app.builder.build_all() + + assert (find_obj(None, u'NONEXISTANT', u'class') == + (None, None)) + assert (find_obj(None, u'TopLevel', u'class') == + (u'TopLevel', (u'roles', u'class'))) + assert (find_obj(None, u'NestedParentA.NestedChildA', u'class') == + (None, None)) + assert (find_obj(None, u'subchild_2', u'func') == + (u'subchild_2', (u'roles', u'function'))) diff --git a/tests/test_domain_py.py b/tests/test_domain_py.py index 568038cfd..f290bfff3 100644 --- a/tests/test_domain_py.py +++ b/tests/test_domain_py.py @@ -9,11 +9,13 @@ :license: BSD, see LICENSE for details. """ +import pytest from six import text_type - from sphinx import addnodes from sphinx.domains.python import py_sig_re, _pseudo_parse_arglist +from util import assert_node + def parse(sig): m = py_sig_re.match(sig) @@ -44,3 +46,121 @@ def test_function_signatures(): rv = parse('func(a=[][, b=None])') assert text_type(rv) == u'a=[], [b=None]' + + +@pytest.mark.sphinx('dummy', testroot='domain-py') +def test_domain_py_xrefs(app, status, warning): + """Domain objects have correct prefixes when looking up xrefs""" + app.builder.build_all() + + def assert_refnode(node, module_name, class_name, target, reftype=None, + domain='py'): + attributes = { + 'refdomain': domain, + 'reftarget': target, + } + if reftype is not None: + attributes['reftype'] = reftype + if module_name is not False: + attributes['py:module'] = module_name + if class_name is not False: + attributes['py:class'] = class_name + assert_node(node, **attributes) + + doctree = app.env.get_doctree('roles') + refnodes = list(doctree.traverse(addnodes.pending_xref)) + assert_refnode(refnodes[0], None, None, u'TopLevel', u'class') + assert_refnode(refnodes[1], None, None, u'top_level', u'meth') + assert_refnode(refnodes[2], None, u'NestedParentA', u'child_1', u'meth') + assert_refnode(refnodes[3], None, u'NestedParentA', + u'NestedChildA.subchild_2', u'meth') + assert_refnode(refnodes[4], None, u'NestedParentA', u'child_2', u'meth') + assert_refnode(refnodes[5], False, u'NestedParentA', u'any_child', domain='') + assert_refnode(refnodes[6], None, u'NestedParentA', u'NestedChildA', + u'class') + assert_refnode(refnodes[7], None, u'NestedParentA.NestedChildA', + u'subchild_2', u'meth') + assert_refnode(refnodes[8], None, u'NestedParentA.NestedChildA', + u'NestedParentA.child_1', u'meth') + assert_refnode(refnodes[9], None, None, u'NestedChildA.subchild_1', + u'meth') + assert_refnode(refnodes[10], None, u'NestedParentB', u'child_1', u'meth') + assert_refnode(refnodes[11], None, u'NestedParentB', u'NestedParentB', + u'class') + assert_refnode(refnodes[12], None, None, u'NestedParentA.NestedChildA', + u'class') + assert len(refnodes) == 13 + + doctree = app.env.get_doctree('module') + refnodes = list(doctree.traverse(addnodes.pending_xref)) + assert_refnode(refnodes[0], 'module_a.submodule', None, + 'ModTopLevel', 'class') + assert_refnode(refnodes[1], 'module_a.submodule', 'ModTopLevel', + 'mod_child_1', 'meth') + assert_refnode(refnodes[2], 'module_a.submodule', 'ModTopLevel', + 'ModTopLevel.mod_child_1', 'meth') + assert_refnode(refnodes[3], 'module_a.submodule', 'ModTopLevel', + 'mod_child_2', 'meth') + assert_refnode(refnodes[4], 'module_a.submodule', 'ModTopLevel', + 'module_a.submodule.ModTopLevel.mod_child_1', 'meth') + assert_refnode(refnodes[5], 'module_b.submodule', None, + 'ModTopLevel', 'class') + assert_refnode(refnodes[6], 'module_b.submodule', 'ModTopLevel', + 'ModNoModule', 'class') + assert len(refnodes) == 7 + + +@pytest.mark.sphinx('dummy', testroot='domain-py') +def test_domain_py_objects(app, status, warning): + app.builder.build_all() + + modules = app.env.domains['py'].data['modules'] + objects = app.env.domains['py'].data['objects'] + + assert 'module_a.submodule' in modules + assert 'module_a.submodule' in objects + assert 'module_b.submodule' in modules + assert 'module_b.submodule' in objects + + assert objects['module_a.submodule.ModTopLevel'] == ('module', 'class') + assert objects['module_a.submodule.ModTopLevel.mod_child_1'] == ('module', 'method') + assert objects['module_a.submodule.ModTopLevel.mod_child_2'] == ('module', 'method') + assert objects['ModNoModule'] == ('module', 'class') + assert objects['module_b.submodule.ModTopLevel'] == ('module', 'class') + + assert objects['TopLevel'] == ('roles', 'class') + assert objects['top_level'] == ('roles', 'method') + assert objects['NestedParentA'] == ('roles', 'class') + assert objects['NestedParentA.child_1'] == ('roles', 'method') + assert objects['NestedParentA.any_child'] == ('roles', 'method') + assert objects['NestedParentA.NestedChildA'] == ('roles', 'class') + assert objects['NestedParentA.NestedChildA.subchild_1'] == ('roles', 'method') + assert objects['NestedParentA.NestedChildA.subchild_2'] == ('roles', 'method') + assert objects['child_2'] == ('roles', 'method') + assert objects['NestedParentB'] == ('roles', 'class') + assert objects['NestedParentB.child_1'] == ('roles', 'method') + + +@pytest.mark.sphinx('dummy', testroot='domain-py') +def test_domain_py_find_obj(app, status, warning): + + def find_obj(modname, prefix, obj_name, obj_type, searchmode=0): + return app.env.domains['py'].find_obj( + app.env, modname, prefix, obj_name, obj_type, searchmode) + + app.builder.build_all() + + assert (find_obj(None, None, u'NONEXISTANT', u'class') == + []) + assert (find_obj(None, None, u'NestedParentA', u'class') == + [(u'NestedParentA', (u'roles', u'class'))]) + assert (find_obj(None, None, u'NestedParentA.NestedChildA', u'class') == + [(u'NestedParentA.NestedChildA', (u'roles', u'class'))]) + assert (find_obj(None, 'NestedParentA', u'NestedChildA', u'class') == + [(u'NestedParentA.NestedChildA', (u'roles', u'class'))]) + assert (find_obj(None, None, u'NestedParentA.NestedChildA.subchild_1', u'meth') == + [(u'NestedParentA.NestedChildA.subchild_1', (u'roles', u'method'))]) + assert (find_obj(None, u'NestedParentA', u'NestedChildA.subchild_1', u'meth') == + [(u'NestedParentA.NestedChildA.subchild_1', (u'roles', u'method'))]) + assert (find_obj(None, u'NestedParentA.NestedChildA', u'subchild_1', u'meth') == + [(u'NestedParentA.NestedChildA.subchild_1', (u'roles', u'method'))])