diff options
author | Takeshi KOMIYA <i.tkomiya@gmail.com> | 2018-01-08 20:19:36 +0900 |
---|---|---|
committer | Takeshi KOMIYA <i.tkomiya@gmail.com> | 2018-01-08 20:19:36 +0900 |
commit | 326d7e64cedb5280a9cf51a90c00266e1dab9e7b (patch) | |
tree | 0ce4e7845e09aa822da027fbe6401174458c47d9 /tests | |
parent | 7a194f52960fe5ace04ef7daa72563e6d3bf094f (diff) | |
parent | 3965b1f023bbac932d0dfbf414386f0667ec002a (diff) | |
download | sphinx-git-326d7e64cedb5280a9cf51a90c00266e1dab9e7b.tar.gz |
Merge branch 'master' into dont_emit_system_message_on_autodoc_warning
Diffstat (limited to 'tests')
96 files changed, 1350 insertions, 741 deletions
diff --git a/tests/conftest.py b/tests/conftest.py index 28dbd6ed4..9fb06edab 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3,18 +3,51 @@ pytest config for sphinx/tests ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ import os +import shutil +import sys +import warnings import pytest from sphinx.testing.path import path pytest_plugins = 'sphinx.testing.fixtures' +# Exclude 'roots' dirs for pytest test collector +collect_ignore = ['roots'] + +# Disable Python version-specific +if sys.version_info < (3, 5): + collect_ignore += ['py35'] + @pytest.fixture(scope='session') def rootdir(): return path(os.path.dirname(__file__) or '.').abspath() / 'roots' + + +def pytest_report_header(config): + return 'Running Sphinx test suite (with Python %s)...' % ( + sys.version.split()[0]) + + +def _initialize_test_directory(session): + testroot = os.path.join(str(session.config.rootdir), 'tests') + tempdir = os.path.abspath(os.getenv('SPHINX_TEST_TEMPDIR', + os.path.join(testroot, 'build'))) + os.environ['SPHINX_TEST_TEMPDIR'] = tempdir + + print('Temporary files will be placed in %s.' % tempdir) + + if os.path.exists(tempdir): + shutil.rmtree(tempdir) + + os.makedirs(tempdir) + + +def pytest_sessionstart(session): + _initialize_test_directory(session) diff --git a/tests/py35/test_autodoc_py35.py b/tests/py35/test_autodoc_py35.py index 9a94dbd27..439ebd67a 100644 --- a/tests/py35/test_autodoc_py35.py +++ b/tests/py35/test_autodoc_py35.py @@ -6,7 +6,7 @@ Test the autodoc extension. This tests mainly the Documenters; the auto directives are tested in a test source file translated by test_build. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -108,14 +108,14 @@ def test_generate(): logging.setup(app, app._status, app._warning) def assert_warns(warn_str, objtype, name, **kw): - inst = AutoDirective._registry[objtype](directive, name) + inst = app.registry.documenters[objtype](directive, name) inst.generate(**kw) assert len(directive.result) == 0, directive.result assert warn_str in app._warning.getvalue() app._warning.truncate(0) def assert_works(objtype, name, **kw): - inst = AutoDirective._registry[objtype](directive, name) + inst = app.registry.documenters[objtype](directive, name) inst.generate(**kw) assert directive.result # print '\n'.join(directive.result) @@ -129,7 +129,7 @@ def test_generate(): assert set(processed_docstrings) | set(processed_signatures) == set(items) def assert_result_contains(item, objtype, name, **kw): - inst = AutoDirective._registry[objtype](directive, name) + inst = app.registry.documenters[objtype](directive, name) inst.generate(**kw) # print '\n'.join(directive.result) assert app._warning.getvalue() == '' @@ -137,7 +137,7 @@ def test_generate(): del directive.result[:] def assert_order(items, objtype, name, member_order, **kw): - inst = AutoDirective._registry[objtype](directive, name) + inst = app.registry.documenters[objtype](directive, name) inst.options.member_order = member_order inst.generate(**kw) assert app._warning.getvalue() == '' diff --git a/tests/roots/test-apidoc-toc/mypackage/__init__.py b/tests/roots/test-apidoc-toc/mypackage/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/roots/test-apidoc-toc/mypackage/__init__.py diff --git a/tests/roots/test-apidoc-toc/mypackage/main.py b/tests/roots/test-apidoc-toc/mypackage/main.py new file mode 100755 index 000000000..5d3da04b9 --- /dev/null +++ b/tests/roots/test-apidoc-toc/mypackage/main.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python +import os + +import mod_resource + +import mod_something + + +if __name__ == "__main__": + print("Hello, world! -> something returns: {}".format(mod_something.something())) + + res_path = \ + os.path.join(os.path.dirname(mod_resource.__file__), 'resource.txt') + with open(res_path) as f: + text = f.read() + print("From mod_resource:resource.txt -> {}".format(text)) diff --git a/tests/roots/test-apidoc-toc/mypackage/no_init/foo.py b/tests/roots/test-apidoc-toc/mypackage/no_init/foo.py new file mode 100644 index 000000000..ce059b276 --- /dev/null +++ b/tests/roots/test-apidoc-toc/mypackage/no_init/foo.py @@ -0,0 +1 @@ +MESSAGE="There's no __init__.py in this folder, hence we should be left out" diff --git a/tests/roots/test-apidoc-toc/mypackage/resource/__init__.py b/tests/roots/test-apidoc-toc/mypackage/resource/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/roots/test-apidoc-toc/mypackage/resource/__init__.py diff --git a/tests/roots/test-apidoc-toc/mypackage/resource/resource.txt b/tests/roots/test-apidoc-toc/mypackage/resource/resource.txt new file mode 100644 index 000000000..5b64c924d --- /dev/null +++ b/tests/roots/test-apidoc-toc/mypackage/resource/resource.txt @@ -0,0 +1 @@ +This is a text resource to be included in this otherwise empty module. No python contents here.
\ No newline at end of file diff --git a/tests/roots/test-apidoc-toc/mypackage/something/__init__.py b/tests/roots/test-apidoc-toc/mypackage/something/__init__.py new file mode 100644 index 000000000..259184ba3 --- /dev/null +++ b/tests/roots/test-apidoc-toc/mypackage/something/__init__.py @@ -0,0 +1 @@ +"Subpackage Something"
\ No newline at end of file diff --git a/tests/roots/test-domain-cpp/index.rst b/tests/roots/test-domain-cpp/index.rst index 618e51037..2df5ec848 100644 --- a/tests/roots/test-domain-cpp/index.rst +++ b/tests/roots/test-domain-cpp/index.rst @@ -28,14 +28,20 @@ directives An unscoped enum. + .. cpp:enumerator:: A + .. cpp:enum-class:: MyScopedEnum A scoped enum. + .. cpp:enumerator:: B + .. cpp:enum-struct:: protected MyScopedVisibilityEnum : std::underlying_type<MySpecificEnum>::type A scoped enum with non-default visibility, and with a specified underlying type. + .. cpp:enumerator:: B + .. cpp:function:: void paren_1(int, float) .. cpp:function:: void paren_2(int, float) diff --git a/tests/roots/test-ext-autodoc/target/__init__.py b/tests/roots/test-ext-autodoc/target/__init__.py new file mode 100644 index 000000000..bd00bf183 --- /dev/null +++ b/tests/roots/test-ext-autodoc/target/__init__.py @@ -0,0 +1,225 @@ +# -*- coding: utf-8 -*- + +import enum +from six import StringIO, add_metaclass +from sphinx.ext.autodoc import add_documenter # NOQA + + +__all__ = ['Class'] + +#: documentation for the integer +integer = 1 + + +def raises(exc, func, *args, **kwds): + """Raise AssertionError if ``func(*args, **kwds)`` does not raise *exc*.""" + pass + + +class CustomEx(Exception): + """My custom exception.""" + + def f(self): + """Exception method.""" + + +class CustomDataDescriptor(object): + """Descriptor class docstring.""" + + def __init__(self, doc): + self.__doc__ = doc + + def __get__(self, obj, type=None): + if obj is None: + return self + return 42 + + def meth(self): + """Function.""" + return "The Answer" + + +class CustomDataDescriptorMeta(type): + """Descriptor metaclass docstring.""" + + +@add_metaclass(CustomDataDescriptorMeta) +class CustomDataDescriptor2(CustomDataDescriptor): + """Descriptor class with custom metaclass docstring.""" + + +def _funky_classmethod(name, b, c, d, docstring=None): + """Generates a classmethod for a class from a template by filling out + some arguments.""" + def template(cls, a, b, c, d=4, e=5, f=6): + return a, b, c, d, e, f + from functools import partial + function = partial(template, b=b, c=c, d=d) + function.__name__ = name + function.__doc__ = docstring + return classmethod(function) + + +class Base(object): + def inheritedmeth(self): + """Inherited function.""" + + +class Derived(Base): + def inheritedmeth(self): + # no docstring here + pass + + +class Class(Base): + """Class to document.""" + + descr = CustomDataDescriptor("Descriptor instance docstring.") + + def meth(self): + """Function.""" + + def undocmeth(self): + pass + + def skipmeth(self): + """Method that should be skipped.""" + + def excludemeth(self): + """Method that should be excluded.""" + + # should not be documented + skipattr = 'foo' + + #: should be documented -- süß + attr = 'bar' + + @property + def prop(self): + """Property.""" + + docattr = 'baz' + """should likewise be documented -- süß""" + + udocattr = 'quux' + u"""should be documented as well - süß""" + + # initialized to any class imported from another module + mdocattr = StringIO() + """should be documented as well - süß""" + + roger = _funky_classmethod("roger", 2, 3, 4) + + moore = _funky_classmethod("moore", 9, 8, 7, + docstring="moore(a, e, f) -> happiness") + + def __init__(self, arg): + self.inst_attr_inline = None #: an inline documented instance attr + #: a documented instance attribute + self.inst_attr_comment = None + self.inst_attr_string = None + """a documented instance attribute""" + self._private_inst_attr = None #: a private instance attribute + + def __special1__(self): + """documented special method""" + + def __special2__(self): + # undocumented special method + pass + + +class CustomDict(dict): + """Docstring.""" + + +def function(foo, *args, **kwds): + """ + Return spam. + """ + pass + + +class Outer(object): + """Foo""" + + class Inner(object): + """Foo""" + + def meth(self): + """Foo""" + + # should be documented as an alias + factory = dict + + +class DocstringSig(object): + def meth(self): + """meth(FOO, BAR=1) -> BAZ +First line of docstring + + rest of docstring + """ + + def meth2(self): + """First line, no signature + Second line followed by indentation:: + + indented line + """ + + @property + def prop1(self): + """DocstringSig.prop1(self) + First line of docstring + """ + return 123 + + @property + def prop2(self): + """First line of docstring + Second line of docstring + """ + return 456 + + +class StrRepr(str): + def __repr__(self): + return self + + +class AttCls(object): + a1 = StrRepr('hello\nworld') + a2 = None + + +class InstAttCls(object): + """Class with documented class and instance attributes.""" + + #: Doc comment for class attribute InstAttCls.ca1. + #: It can have multiple lines. + ca1 = 'a' + + ca2 = 'b' #: Doc comment for InstAttCls.ca2. One line only. + + ca3 = 'c' + """Docstring for class attribute InstAttCls.ca3.""" + + def __init__(self): + #: Doc comment for instance attribute InstAttCls.ia1 + self.ia1 = 'd' + + self.ia2 = 'e' + """Docstring for instance attribute InstAttCls.ia2.""" + + +class EnumCls(enum.Enum): + """ + this is enum class + """ + + #: doc for val1 + val1 = 12 + val2 = 23 #: doc for val2 + val3 = 34 + """doc for val3""" diff --git a/tests/roots/test-ext-math/index.rst b/tests/roots/test-ext-math/index.rst index 9d16824f6..4237b73ff 100644 --- a/tests/roots/test-ext-math/index.rst +++ b/tests/roots/test-ext-math/index.rst @@ -2,8 +2,10 @@ Test Math ========= .. toctree:: + :numbered: 1 math + page .. math:: a^2+b^2=c^2 diff --git a/tests/roots/test-ext-math/page.rst b/tests/roots/test-ext-math/page.rst new file mode 100644 index 000000000..ef8040910 --- /dev/null +++ b/tests/roots/test-ext-math/page.rst @@ -0,0 +1,9 @@ +Test multiple pages +=================== + +.. math:: + :label: bar + + a = b + 1 + +Referencing equations :eq:`foo` and :eq:`bar`. diff --git a/tests/roots/test-ext-todo/index.rst b/tests/roots/test-ext-todo/index.rst index 6b95f73fd..781473d6a 100644 --- a/tests/roots/test-ext-todo/index.rst +++ b/tests/roots/test-ext-todo/index.rst @@ -7,3 +7,5 @@ test for sphinx.ext.todo bar .. todolist:: + +.. todolist:: diff --git a/tests/roots/test-extensions/conf.py b/tests/roots/test-extensions/conf.py new file mode 100644 index 000000000..9a3cbc844 --- /dev/null +++ b/tests/roots/test-extensions/conf.py @@ -0,0 +1,4 @@ +import os +import sys + +sys.path.insert(0, os.path.abspath('.')) diff --git a/tests/roots/test-extensions/read_parallel.py b/tests/roots/test-extensions/read_parallel.py new file mode 100644 index 000000000..a3e052f95 --- /dev/null +++ b/tests/roots/test-extensions/read_parallel.py @@ -0,0 +1,4 @@ +def setup(app): + return { + 'parallel_read_safe': True + } diff --git a/tests/roots/test-extensions/read_serial.py b/tests/roots/test-extensions/read_serial.py new file mode 100644 index 000000000..c55570a5c --- /dev/null +++ b/tests/roots/test-extensions/read_serial.py @@ -0,0 +1,4 @@ +def setup(app): + return { + 'parallel_read_safe': False + } diff --git a/tests/roots/test-extensions/write_parallel.py b/tests/roots/test-extensions/write_parallel.py new file mode 100644 index 000000000..ebc48ef9b --- /dev/null +++ b/tests/roots/test-extensions/write_parallel.py @@ -0,0 +1,4 @@ +def setup(app): + return { + 'parallel_write_safe': True, + } diff --git a/tests/roots/test-extensions/write_serial.py b/tests/roots/test-extensions/write_serial.py new file mode 100644 index 000000000..75494ce77 --- /dev/null +++ b/tests/roots/test-extensions/write_serial.py @@ -0,0 +1,4 @@ +def setup(app): + return { + 'parallel_write_safe': False + } diff --git a/tests/roots/test-latex-numfig/conf.py b/tests/roots/test-latex-numfig/conf.py new file mode 100644 index 000000000..506186b26 --- /dev/null +++ b/tests/roots/test-latex-numfig/conf.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- + +master_doc = 'index' + +extensions = ['sphinx.ext.imgmath'] # for math_numfig + +latex_documents = [ + ('indexmanual', 'SphinxManual.tex', 'Test numfig manual', + 'Sphinx', 'manual'), + ('indexhowto', 'SphinxHowTo.tex', 'Test numfig howto', + 'Sphinx', 'howto'), +] diff --git a/tests/roots/test-latex-numfig/index.rst b/tests/roots/test-latex-numfig/index.rst new file mode 100644 index 000000000..6b8b9688c --- /dev/null +++ b/tests/roots/test-latex-numfig/index.rst @@ -0,0 +1,9 @@ +================= +test-latex-numfig +================= + +.. toctree:: + :numbered: + + indexmanual + indexhowto diff --git a/tests/roots/test-latex-numfig/indexhowto.rst b/tests/roots/test-latex-numfig/indexhowto.rst new file mode 100644 index 000000000..4749f1ecd --- /dev/null +++ b/tests/roots/test-latex-numfig/indexhowto.rst @@ -0,0 +1,10 @@ +======================= +test-latex-numfig-howto +======================= + +This is a part +============== + +This is a section +----------------- + diff --git a/tests/roots/test-latex-numfig/indexmanual.rst b/tests/roots/test-latex-numfig/indexmanual.rst new file mode 100644 index 000000000..8bab4fbfd --- /dev/null +++ b/tests/roots/test-latex-numfig/indexmanual.rst @@ -0,0 +1,13 @@ +======================== +test-latex-numfig-manual +======================== + +First part +========== + +This is chapter +--------------- + +This is section +~~~~~~~~~~~~~~~ + diff --git a/tests/roots/test-root/autodoc.txt b/tests/roots/test-root/autodoc.txt index aa0dffba1..3c83ebf6e 100644 --- a/tests/roots/test-root/autodoc.txt +++ b/tests/roots/test-root/autodoc.txt @@ -5,7 +5,7 @@ Just testing a few autodoc possibilities... .. automodule:: util -.. automodule:: test_autodoc +.. automodule:: autodoc_target :members: .. autofunction:: function @@ -34,7 +34,7 @@ Just testing a few autodoc possibilities... .. autoclass:: MarkupError -.. currentmodule:: test_autodoc +.. currentmodule:: autodoc_target .. autoclass:: InstAttCls :members: diff --git a/tests/roots/test-root/autodoc_target.py b/tests/roots/test-root/autodoc_target.py new file mode 100644 index 000000000..bd00bf183 --- /dev/null +++ b/tests/roots/test-root/autodoc_target.py @@ -0,0 +1,225 @@ +# -*- coding: utf-8 -*- + +import enum +from six import StringIO, add_metaclass +from sphinx.ext.autodoc import add_documenter # NOQA + + +__all__ = ['Class'] + +#: documentation for the integer +integer = 1 + + +def raises(exc, func, *args, **kwds): + """Raise AssertionError if ``func(*args, **kwds)`` does not raise *exc*.""" + pass + + +class CustomEx(Exception): + """My custom exception.""" + + def f(self): + """Exception method.""" + + +class CustomDataDescriptor(object): + """Descriptor class docstring.""" + + def __init__(self, doc): + self.__doc__ = doc + + def __get__(self, obj, type=None): + if obj is None: + return self + return 42 + + def meth(self): + """Function.""" + return "The Answer" + + +class CustomDataDescriptorMeta(type): + """Descriptor metaclass docstring.""" + + +@add_metaclass(CustomDataDescriptorMeta) +class CustomDataDescriptor2(CustomDataDescriptor): + """Descriptor class with custom metaclass docstring.""" + + +def _funky_classmethod(name, b, c, d, docstring=None): + """Generates a classmethod for a class from a template by filling out + some arguments.""" + def template(cls, a, b, c, d=4, e=5, f=6): + return a, b, c, d, e, f + from functools import partial + function = partial(template, b=b, c=c, d=d) + function.__name__ = name + function.__doc__ = docstring + return classmethod(function) + + +class Base(object): + def inheritedmeth(self): + """Inherited function.""" + + +class Derived(Base): + def inheritedmeth(self): + # no docstring here + pass + + +class Class(Base): + """Class to document.""" + + descr = CustomDataDescriptor("Descriptor instance docstring.") + + def meth(self): + """Function.""" + + def undocmeth(self): + pass + + def skipmeth(self): + """Method that should be skipped.""" + + def excludemeth(self): + """Method that should be excluded.""" + + # should not be documented + skipattr = 'foo' + + #: should be documented -- süß + attr = 'bar' + + @property + def prop(self): + """Property.""" + + docattr = 'baz' + """should likewise be documented -- süß""" + + udocattr = 'quux' + u"""should be documented as well - süß""" + + # initialized to any class imported from another module + mdocattr = StringIO() + """should be documented as well - süß""" + + roger = _funky_classmethod("roger", 2, 3, 4) + + moore = _funky_classmethod("moore", 9, 8, 7, + docstring="moore(a, e, f) -> happiness") + + def __init__(self, arg): + self.inst_attr_inline = None #: an inline documented instance attr + #: a documented instance attribute + self.inst_attr_comment = None + self.inst_attr_string = None + """a documented instance attribute""" + self._private_inst_attr = None #: a private instance attribute + + def __special1__(self): + """documented special method""" + + def __special2__(self): + # undocumented special method + pass + + +class CustomDict(dict): + """Docstring.""" + + +def function(foo, *args, **kwds): + """ + Return spam. + """ + pass + + +class Outer(object): + """Foo""" + + class Inner(object): + """Foo""" + + def meth(self): + """Foo""" + + # should be documented as an alias + factory = dict + + +class DocstringSig(object): + def meth(self): + """meth(FOO, BAR=1) -> BAZ +First line of docstring + + rest of docstring + """ + + def meth2(self): + """First line, no signature + Second line followed by indentation:: + + indented line + """ + + @property + def prop1(self): + """DocstringSig.prop1(self) + First line of docstring + """ + return 123 + + @property + def prop2(self): + """First line of docstring + Second line of docstring + """ + return 456 + + +class StrRepr(str): + def __repr__(self): + return self + + +class AttCls(object): + a1 = StrRepr('hello\nworld') + a2 = None + + +class InstAttCls(object): + """Class with documented class and instance attributes.""" + + #: Doc comment for class attribute InstAttCls.ca1. + #: It can have multiple lines. + ca1 = 'a' + + ca2 = 'b' #: Doc comment for InstAttCls.ca2. One line only. + + ca3 = 'c' + """Docstring for class attribute InstAttCls.ca3.""" + + def __init__(self): + #: Doc comment for instance attribute InstAttCls.ia1 + self.ia1 = 'd' + + self.ia2 = 'e' + """Docstring for instance attribute InstAttCls.ia2.""" + + +class EnumCls(enum.Enum): + """ + this is enum class + """ + + #: doc for val1 + val1 = 12 + val2 = 23 #: doc for val2 + val3 = 34 + """doc for val3""" diff --git a/tests/run.py b/tests/run.py deleted file mode 100755 index a8439ba02..000000000 --- a/tests/run.py +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -""" - Sphinx unit test driver - ~~~~~~~~~~~~~~~~~~~~~~~ - - This script runs the Sphinx unit test suite. - - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. - :license: BSD, see LICENSE for details. -""" -from __future__ import print_function - -import os -import sys -import warnings -import traceback -import shutil - -testroot = os.path.dirname(__file__) or '.' -sys.path.insert(0, os.path.abspath(os.path.join(testroot, os.path.pardir))) - -# filter warnings of test dependencies -warnings.filterwarnings('ignore', category=DeprecationWarning, module='site') # virtualenv -warnings.filterwarnings('ignore', category=ImportWarning, module='backports') -warnings.filterwarnings('ignore', category=ImportWarning, module='pkgutil') -warnings.filterwarnings('ignore', category=ImportWarning, module='pytest_cov') -warnings.filterwarnings('ignore', category=PendingDeprecationWarning, module=r'_pytest\..*') - -# check dependencies before testing -print('Checking dependencies...') -for modname in ('pytest', 'mock', 'six', 'docutils', 'jinja2', 'pygments', - 'snowballstemmer', 'babel', 'html5lib'): - try: - __import__(modname) - except ImportError as err: - if modname == 'mock' and sys.version_info[0] == 3: - continue - traceback.print_exc() - print('The %r package is needed to run the Sphinx test suite.' % modname) - sys.exit(1) - -# find a temp dir for testing and clean it up now -os.environ['SPHINX_TEST_TEMPDIR'] = \ - os.path.abspath(os.path.join(testroot, 'build')) \ - if 'SPHINX_TEST_TEMPDIR' not in os.environ \ - else os.path.abspath(os.environ['SPHINX_TEST_TEMPDIR']) - -tempdir = os.environ['SPHINX_TEST_TEMPDIR'] -print('Temporary files will be placed in %s.' % tempdir) -if os.path.exists(tempdir): - shutil.rmtree(tempdir) -os.makedirs(tempdir) - -print('Running Sphinx test suite (with Python %s)...' % sys.version.split()[0]) -sys.stdout.flush() - -# exclude 'roots' dirs for pytest test collector -ignore_paths = [ - os.path.relpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), sub)) - for sub in ('roots',) -] -args = sys.argv[1:] -for ignore_path in ignore_paths: - args.extend(['--ignore', ignore_path]) - -import pytest # NOQA -sys.exit(pytest.main(args)) diff --git a/tests/test_api_translator.py b/tests/test_api_translator.py index 35b24732b..4e4230ba3 100644 --- a/tests/test_api_translator.py +++ b/tests/test_api_translator.py @@ -5,7 +5,7 @@ Test the Sphinx API for translator. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_application.py b/tests/test_application.py index 785a78878..12b6bbe60 100644 --- a/tests/test_application.py +++ b/tests/test_application.py @@ -5,13 +5,14 @@ Test the Sphinx class. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ from docutils import nodes from sphinx.application import ExtensionError from sphinx.domains import Domain +from sphinx.util import logging from sphinx.testing.util import strip_escseq import pytest @@ -86,3 +87,38 @@ def test_add_source_parser(app, status, warning): assert set(app.registry.get_source_parsers().keys()) == set(['*', '.md', '.test']) assert app.registry.get_source_parsers()['.md'].__name__ == 'DummyMarkdownParser' assert app.registry.get_source_parsers()['.test'].__name__ == 'TestSourceParser' + + +@pytest.mark.sphinx(testroot='extensions') +def test_add_is_parallel_allowed(app, status, warning): + logging.setup(app, status, warning) + + assert app.is_parallel_allowed('read') is True + assert app.is_parallel_allowed('write') is True + assert warning.getvalue() == '' + + app.setup_extension('read_parallel') + assert app.is_parallel_allowed('read') is True + assert app.is_parallel_allowed('write') is True + assert warning.getvalue() == '' + app.extensions.pop('read_parallel') + + app.setup_extension('write_parallel') + assert app.is_parallel_allowed('read') is False + assert app.is_parallel_allowed('write') is True + assert 'the write_parallel extension does not declare' in warning.getvalue() + app.extensions.pop('write_parallel') + warning.truncate(0) # reset warnings + + app.setup_extension('read_serial') + assert app.is_parallel_allowed('read') is False + assert app.is_parallel_allowed('write') is True + assert warning.getvalue() == '' + app.extensions.pop('read_serial') + + app.setup_extension('write_serial') + assert app.is_parallel_allowed('read') is False + assert app.is_parallel_allowed('write') is False + assert 'the write_serial extension does not declare' in warning.getvalue() + app.extensions.pop('write_serial') + warning.truncate(0) # reset warnings diff --git a/tests/test_autodoc.py b/tests/test_autodoc.py index 4ab58d891..d9c94bc0d 100644 --- a/tests/test_autodoc.py +++ b/tests/test_autodoc.py @@ -6,17 +6,16 @@ Test the autodoc extension. This tests mainly the Documenters; the auto directives are tested in a test source file translated by test_build. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ +import sys from six import PY3 from sphinx.testing.util import SphinxTestApp, Struct # NOQA import pytest -import enum -from six import StringIO, add_metaclass from docutils.statemachine import ViewList from sphinx.ext.autodoc import AutoDirective, add_documenter, \ @@ -28,18 +27,23 @@ app = None @pytest.fixture(scope='module', autouse=True) def setup_module(rootdir, sphinx_test_tempdir): - global app - srcdir = sphinx_test_tempdir / 'autodoc-root' - if not srcdir.exists(): - (rootdir/'test-root').copytree(srcdir) - app = SphinxTestApp(srcdir=srcdir) - app.builder.env.app = app - app.builder.env.temp_data['docname'] = 'dummy' - app.connect('autodoc-process-docstring', process_docstring) - app.connect('autodoc-process-signature', process_signature) - app.connect('autodoc-skip-member', skip_member) - yield - app.cleanup() + try: + global app + srcdir = sphinx_test_tempdir / 'autodoc-root' + if not srcdir.exists(): + (rootdir / 'test-root').copytree(srcdir) + testroot = rootdir / 'test-ext-autodoc' + sys.path.append(testroot) + app = SphinxTestApp(srcdir=srcdir) + app.builder.env.app = app + app.builder.env.temp_data['docname'] = 'dummy' + app.connect('autodoc-process-docstring', process_docstring) + app.connect('autodoc-process-signature', process_signature) + app.connect('autodoc-skip-member', skip_member) + yield + finally: + app.cleanup() + sys.path.remove(testroot) directive = options = None @@ -65,6 +69,7 @@ def setup_test(): members = [], member_order = 'alphabetic', exclude_members = set(), + ignore_module_all = False, ) directive = Struct( @@ -115,7 +120,7 @@ def test_parse_name(): logging.setup(app, app._status, app._warning) def verify(objtype, name, result): - inst = AutoDirective._registry[objtype](directive, name) + inst = app.registry.documenters[objtype](directive, name) assert inst.parse_name() assert (inst.modname, inst.objpath, inst.args, inst.retann) == result @@ -157,7 +162,7 @@ def test_parse_name(): @pytest.mark.usefixtures('setup_test') def test_format_signature(): def formatsig(objtype, name, obj, args, retann): - inst = AutoDirective._registry[objtype](directive, name) + inst = app.registry.documenters[objtype](directive, name) inst.fullname = name inst.doc_as_attr = False # for class objtype inst.object = obj @@ -262,7 +267,7 @@ def test_format_signature(): @pytest.mark.usefixtures('setup_test') def test_get_doc(): def getdocl(objtype, obj, encoding=None): - inst = AutoDirective._registry[objtype](directive, 'tmp') + inst = app.registry.documenters[objtype](directive, 'tmp') inst.object = obj inst.objpath = [obj.__name__] inst.doc_as_attr = False @@ -417,7 +422,7 @@ def test_get_doc(): # class has __init__ method without docstring and # __new__ method with docstring # class docstring: depends on config value which one is taken - class I: + class I: # NOQA """Class docstring""" def __new__(cls): """New docstring""" @@ -428,6 +433,8 @@ def test_get_doc(): directive.env.config.autoclass_content = 'both' assert getdocl('class', I) == ['Class docstring', '', 'New docstring'] + from target import Base, Derived + # NOTE: inspect.getdoc seems not to work with locally defined classes directive.env.config.autodoc_inherit_docstrings = False assert getdocl('method', Base.inheritedmeth) == ['Inherited function.'] @@ -439,7 +446,7 @@ def test_get_doc(): @pytest.mark.usefixtures('setup_test') def test_docstring_processing(): def process(objtype, name, obj): - inst = AutoDirective._registry[objtype](directive, name) + inst = app.registry.documenters[objtype](directive, name) inst.object = obj inst.fullname = name return list(inst.process_doc(inst.get_doc())) @@ -496,7 +503,7 @@ def test_docstring_property_processing(): def genarate_docstring(objtype, name, **kw): del processed_docstrings[:] del processed_signatures[:] - inst = AutoDirective._registry[objtype](directive, name) + inst = app.registry.documenters[objtype](directive, name) inst.generate(**kw) results = list(directive.result) docstrings = inst.get_doc()[0] @@ -505,24 +512,24 @@ def test_docstring_property_processing(): directive.env.config.autodoc_docstring_signature = False results, docstrings = \ - genarate_docstring('attribute', 'test_autodoc.DocstringSig.prop1') + genarate_docstring('attribute', 'target.DocstringSig.prop1') assert '.. py:attribute:: DocstringSig.prop1' in results assert 'First line of docstring' in docstrings assert 'DocstringSig.prop1(self)' in docstrings results, docstrings = \ - genarate_docstring('attribute', 'test_autodoc.DocstringSig.prop2') + genarate_docstring('attribute', 'target.DocstringSig.prop2') assert '.. py:attribute:: DocstringSig.prop2' in results assert 'First line of docstring' in docstrings assert 'Second line of docstring' in docstrings directive.env.config.autodoc_docstring_signature = True results, docstrings = \ - genarate_docstring('attribute', 'test_autodoc.DocstringSig.prop1') + genarate_docstring('attribute', 'target.DocstringSig.prop1') assert '.. py:attribute:: DocstringSig.prop1' in results assert 'First line of docstring' in docstrings assert 'DocstringSig.prop1(self)' not in docstrings results, docstrings = \ - genarate_docstring('attribute', 'test_autodoc.DocstringSig.prop2') + genarate_docstring('attribute', 'target.DocstringSig.prop2') assert '.. py:attribute:: DocstringSig.prop2' in results assert 'First line of docstring' in docstrings assert 'Second line of docstring' in docstrings @@ -548,7 +555,7 @@ def test_new_documenter(): def assert_result_contains(item, objtype, name, **kw): app._warning.truncate(0) - inst = AutoDirective._registry[objtype](directive, name) + inst = app.registry.documenters[objtype](directive, name) inst.generate(**kw) # print '\n'.join(directive.result) assert app._warning.getvalue() == '' @@ -556,11 +563,13 @@ def test_new_documenter(): del directive.result[:] options.members = ['integer'] - assert_result_contains('.. py:data:: integer', 'module', 'test_autodoc') + assert_result_contains('.. py:data:: integer', 'module', 'target') @pytest.mark.usefixtures('setup_test') def test_attrgetter_using(): + from target import Class + def assert_getter_works(objtype, name, obj, attrs=[], **kw): getattr_spy = [] @@ -572,7 +581,7 @@ def test_attrgetter_using(): AutoDirective._special_attrgetters[type] = special_getattr del getattr_spy[:] - inst = AutoDirective._registry[objtype](directive, name) + inst = app.registry.documenters[objtype](directive, name) inst.generate(**kw) hooked_members = [s[1] for s in getattr_spy] @@ -585,10 +594,10 @@ def test_attrgetter_using(): options.members = ALL options.inherited_members = False - assert_getter_works('class', 'test_autodoc.Class', Class, ['meth']) + assert_getter_works('class', 'target.Class', Class, ['meth']) options.inherited_members = True - assert_getter_works('class', 'test_autodoc.Class', Class, ['meth', 'inheritedmeth']) + assert_getter_works('class', 'target.Class', Class, ['meth', 'inheritedmeth']) @pytest.mark.usefixtures('setup_test') @@ -596,7 +605,7 @@ def test_generate(): logging.setup(app, app._status, app._warning) def assert_warns(warn_str, objtype, name, **kw): - inst = AutoDirective._registry[objtype](directive, name) + inst = app.registry.documenters[objtype](directive, name) inst.generate(**kw) assert len(directive.result) == 0, directive.result @@ -604,7 +613,7 @@ def test_generate(): app._warning.truncate(0) def assert_works(objtype, name, **kw): - inst = AutoDirective._registry[objtype](directive, name) + inst = app.registry.documenters[objtype](directive, name) inst.generate(**kw) assert directive.result # print '\n'.join(directive.result) @@ -618,7 +627,7 @@ def test_generate(): assert set(processed_docstrings) | set(processed_signatures) == set(items) def assert_result_contains(item, objtype, name, **kw): - inst = AutoDirective._registry[objtype](directive, name) + inst = app.registry.documenters[objtype](directive, name) inst.generate(**kw) # print '\n'.join(directive.result) assert app._warning.getvalue() == '' @@ -626,7 +635,7 @@ def test_generate(): del directive.result[:] def assert_order(items, objtype, name, member_order, **kw): - inst = AutoDirective._registry[objtype](directive, name) + inst = app.registry.documenters[objtype](directive, name) inst.options.member_order = member_order inst.generate(**kw) assert app._warning.getvalue() == '' @@ -657,11 +666,11 @@ def test_generate(): assert_warns("failed to import function 'foobar' from module 'util'", 'function', 'util.foobar', more_content=None) # method missing - assert_warns("failed to import method 'Class.foobar' from module 'test_autodoc';", - 'method', 'test_autodoc.Class.foobar', more_content=None) + assert_warns("failed to import method 'Class.foobar' from module 'target';", + 'method', 'target.Class.foobar', more_content=None) # test auto and given content mixing - directive.env.ref_context['py:module'] = 'test_autodoc' + directive.env.ref_context['py:module'] = 'target' assert_result_contains(' Function.', 'method', 'Class.meth') add_content = ViewList() add_content.append('Content.', '', 0) @@ -676,72 +685,77 @@ def test_generate(): assert len(directive.result) == 0 # assert that exceptions can be documented - assert_works('exception', 'test_autodoc.CustomEx', all_members=True) - assert_works('exception', 'test_autodoc.CustomEx') + assert_works('exception', 'target.CustomEx', all_members=True) + assert_works('exception', 'target.CustomEx') # test diverse inclusion settings for members - should = [('class', 'test_autodoc.Class')] + should = [('class', 'target.Class')] assert_processes(should, 'class', 'Class') - should.extend([('method', 'test_autodoc.Class.meth')]) + should.extend([('method', 'target.Class.meth')]) options.members = ['meth'] options.exclude_members = set(['excludemeth']) assert_processes(should, 'class', 'Class') - should.extend([('attribute', 'test_autodoc.Class.prop'), - ('attribute', 'test_autodoc.Class.descr'), - ('attribute', 'test_autodoc.Class.attr'), - ('attribute', 'test_autodoc.Class.docattr'), - ('attribute', 'test_autodoc.Class.udocattr'), - ('attribute', 'test_autodoc.Class.mdocattr'), - ('attribute', 'test_autodoc.Class.inst_attr_comment'), - ('attribute', 'test_autodoc.Class.inst_attr_inline'), - ('attribute', 'test_autodoc.Class.inst_attr_string'), - ('method', 'test_autodoc.Class.moore'), + should.extend([('attribute', 'target.Class.prop'), + ('attribute', 'target.Class.descr'), + ('attribute', 'target.Class.attr'), + ('attribute', 'target.Class.docattr'), + ('attribute', 'target.Class.udocattr'), + ('attribute', 'target.Class.mdocattr'), + ('attribute', 'target.Class.inst_attr_comment'), + ('attribute', 'target.Class.inst_attr_inline'), + ('attribute', 'target.Class.inst_attr_string'), + ('method', 'target.Class.moore'), ]) options.members = ALL assert_processes(should, 'class', 'Class') options.undoc_members = True - should.extend((('attribute', 'test_autodoc.Class.skipattr'), - ('method', 'test_autodoc.Class.undocmeth'), - ('method', 'test_autodoc.Class.roger'))) + should.extend((('attribute', 'target.Class.skipattr'), + ('method', 'target.Class.undocmeth'), + ('method', 'target.Class.roger'))) assert_processes(should, 'class', 'Class') options.inherited_members = True - should.append(('method', 'test_autodoc.Class.inheritedmeth')) + should.append(('method', 'target.Class.inheritedmeth')) assert_processes(should, 'class', 'Class') # test special members options.special_members = ['__special1__'] - should.append(('method', 'test_autodoc.Class.__special1__')) + should.append(('method', 'target.Class.__special1__')) assert_processes(should, 'class', 'Class') options.special_members = ALL - should.append(('method', 'test_autodoc.Class.__special2__')) + should.append(('method', 'target.Class.__special2__')) assert_processes(should, 'class', 'Class') options.special_members = False options.members = [] # test module flags - assert_result_contains('.. py:module:: test_autodoc', - 'module', 'test_autodoc') + assert_result_contains('.. py:module:: target', + 'module', 'target') options.synopsis = 'Synopsis' - assert_result_contains(' :synopsis: Synopsis', 'module', 'test_autodoc') + assert_result_contains(' :synopsis: Synopsis', 'module', 'target') options.deprecated = True - assert_result_contains(' :deprecated:', 'module', 'test_autodoc') + assert_result_contains(' :deprecated:', 'module', 'target') options.platform = 'Platform' - assert_result_contains(' :platform: Platform', 'module', 'test_autodoc') + assert_result_contains(' :platform: Platform', 'module', 'target') # test if __all__ is respected for modules options.members = ALL - assert_result_contains('.. py:class:: Class(arg)', 'module', 'test_autodoc') + assert_result_contains('.. py:class:: Class(arg)', 'module', 'target') try: assert_result_contains('.. py:exception:: CustomEx', - 'module', 'test_autodoc') + 'module', 'target') except AssertionError: pass else: assert False, 'documented CustomEx which is not in __all__' + # test ignore-module-all + options.ignore_module_all = True + assert_result_contains('.. py:class:: Class(arg)', 'module', 'target') + assert_result_contains('.. py:exception:: CustomEx', 'module', 'target') + # test noindex flag options.members = [] options.noindex = True - assert_result_contains(' :noindex:', 'module', 'test_autodoc') + assert_result_contains(' :noindex:', 'module', 'target') assert_result_contains(' :noindex:', 'class', 'Base') # okay, now let's get serious about mixing Python and C signature stuff @@ -749,14 +763,14 @@ def test_generate(): all_members=True) # test inner class handling - assert_processes([('class', 'test_autodoc.Outer'), - ('class', 'test_autodoc.Outer.Inner'), - ('method', 'test_autodoc.Outer.Inner.meth')], + assert_processes([('class', 'target.Outer'), + ('class', 'target.Outer.Inner'), + ('method', 'target.Outer.Inner.meth')], 'class', 'Outer', all_members=True) # test descriptor docstrings assert_result_contains(' Descriptor instance docstring.', - 'attribute', 'test_autodoc.Class.descr') + 'attribute', 'target.Class.descr') # test generation for C modules (which have no source file) directive.env.ref_context['py:module'] = 'time' @@ -764,7 +778,7 @@ def test_generate(): assert_processes([('function', 'time.asctime')], 'function', 'asctime') # test autodoc_member_order == 'source' - directive.env.ref_context['py:module'] = 'test_autodoc' + directive.env.ref_context['py:module'] = 'target' options.private_members = True if PY3: roger_line = ' .. py:classmethod:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)' @@ -790,7 +804,7 @@ def test_generate(): del directive.env.ref_context['py:module'] # test attribute initialized to class instance from other module - directive.env.temp_data['autodoc:class'] = 'test_autodoc.Class' + directive.env.temp_data['autodoc:class'] = 'target.Class' assert_result_contains(u' should be documented as well - s\xfc\xdf', 'attribute', 'mdocattr') del directive.env.temp_data['autodoc:class'] @@ -798,25 +812,25 @@ def test_generate(): # test autodoc_docstring_signature assert_result_contains( '.. py:method:: DocstringSig.meth(FOO, BAR=1) -> BAZ', 'method', - 'test_autodoc.DocstringSig.meth') + 'target.DocstringSig.meth') assert_result_contains( - ' rest of docstring', 'method', 'test_autodoc.DocstringSig.meth') + ' rest of docstring', 'method', 'target.DocstringSig.meth') assert_result_contains( '.. py:method:: DocstringSig.meth2()', 'method', - 'test_autodoc.DocstringSig.meth2') + 'target.DocstringSig.meth2') assert_result_contains( ' indented line', 'method', - 'test_autodoc.DocstringSig.meth2') + 'target.DocstringSig.meth2') assert_result_contains( '.. py:classmethod:: Class.moore(a, e, f) -> happiness', 'method', - 'test_autodoc.Class.moore') + 'target.Class.moore') # test new attribute documenter behavior - directive.env.ref_context['py:module'] = 'test_autodoc' + directive.env.ref_context['py:module'] = 'target' options.undoc_members = True - assert_processes([('class', 'test_autodoc.AttCls'), - ('attribute', 'test_autodoc.AttCls.a1'), - ('attribute', 'test_autodoc.AttCls.a2'), + assert_processes([('class', 'target.AttCls'), + ('attribute', 'target.AttCls.a1'), + ('attribute', 'target.AttCls.a2'), ], 'class', 'AttCls') assert_result_contains( ' :annotation: = hello world', 'attribute', 'AttCls.a1') @@ -826,40 +840,40 @@ def test_generate(): # test explicit members with instance attributes del directive.env.temp_data['autodoc:class'] del directive.env.temp_data['autodoc:module'] - directive.env.ref_context['py:module'] = 'test_autodoc' + directive.env.ref_context['py:module'] = 'target' options.inherited_members = False options.undoc_members = False options.members = ALL assert_processes([ - ('class', 'test_autodoc.InstAttCls'), - ('attribute', 'test_autodoc.InstAttCls.ca1'), - ('attribute', 'test_autodoc.InstAttCls.ca2'), - ('attribute', 'test_autodoc.InstAttCls.ca3'), - ('attribute', 'test_autodoc.InstAttCls.ia1'), - ('attribute', 'test_autodoc.InstAttCls.ia2'), + ('class', 'target.InstAttCls'), + ('attribute', 'target.InstAttCls.ca1'), + ('attribute', 'target.InstAttCls.ca2'), + ('attribute', 'target.InstAttCls.ca3'), + ('attribute', 'target.InstAttCls.ia1'), + ('attribute', 'target.InstAttCls.ia2'), ], 'class', 'InstAttCls') del directive.env.temp_data['autodoc:class'] del directive.env.temp_data['autodoc:module'] options.members = ['ca1', 'ia1'] assert_processes([ - ('class', 'test_autodoc.InstAttCls'), - ('attribute', 'test_autodoc.InstAttCls.ca1'), - ('attribute', 'test_autodoc.InstAttCls.ia1'), + ('class', 'target.InstAttCls'), + ('attribute', 'target.InstAttCls.ca1'), + ('attribute', 'target.InstAttCls.ia1'), ], 'class', 'InstAttCls') del directive.env.temp_data['autodoc:class'] del directive.env.temp_data['autodoc:module'] del directive.env.ref_context['py:module'] # test members with enum attributes - directive.env.ref_context['py:module'] = 'test_autodoc' + directive.env.ref_context['py:module'] = 'target' options.inherited_members = False options.undoc_members = False options.members = ALL assert_processes([ - ('class', 'test_autodoc.EnumCls'), - ('attribute', 'test_autodoc.EnumCls.val1'), - ('attribute', 'test_autodoc.EnumCls.val2'), - ('attribute', 'test_autodoc.EnumCls.val3'), + ('class', 'target.EnumCls'), + ('attribute', 'target.EnumCls.val1'), + ('attribute', 'target.EnumCls.val2'), + ('attribute', 'target.EnumCls.val3'), ], 'class', 'EnumCls') assert_result_contains( ' :annotation: = 12', 'attribute', 'EnumCls.val1') @@ -873,11 +887,11 @@ def test_generate(): # test descriptor class documentation options.members = ['CustomDataDescriptor', 'CustomDataDescriptor2'] assert_result_contains('.. py:class:: CustomDataDescriptor(doc)', - 'module', 'test_autodoc') + 'module', 'target') assert_result_contains(' .. py:method:: CustomDataDescriptor.meth()', - 'module', 'test_autodoc') + 'module', 'target') assert_result_contains('.. py:class:: CustomDataDescriptor2(doc)', - 'module', 'test_autodoc') + 'module', 'target') # test mocked module imports options.members = ['TestAutodoc'] @@ -889,224 +903,3 @@ def test_generate(): options.members = ['decoratedFunction'] assert_result_contains('.. py:function:: decoratedFunction()', 'module', 'autodoc_missing_imports') - - -# --- generate fodder ------------ -__all__ = ['Class'] - -#: documentation for the integer -integer = 1 - - -def raises(exc, func, *args, **kwds): - """Raise AssertionError if ``func(*args, **kwds)`` does not raise *exc*.""" - pass - - -class CustomEx(Exception): - """My custom exception.""" - - def f(self): - """Exception method.""" - - -class CustomDataDescriptor(object): - """Descriptor class docstring.""" - - def __init__(self, doc): - self.__doc__ = doc - - def __get__(self, obj, type=None): - if obj is None: - return self - return 42 - - def meth(self): - """Function.""" - return "The Answer" - - -class CustomDataDescriptorMeta(type): - """Descriptor metaclass docstring.""" - - -@add_metaclass(CustomDataDescriptorMeta) -class CustomDataDescriptor2(CustomDataDescriptor): - """Descriptor class with custom metaclass docstring.""" - - -def _funky_classmethod(name, b, c, d, docstring=None): - """Generates a classmethod for a class from a template by filling out - some arguments.""" - def template(cls, a, b, c, d=4, e=5, f=6): - return a, b, c, d, e, f - from functools import partial - function = partial(template, b=b, c=c, d=d) - function.__name__ = name - function.__doc__ = docstring - return classmethod(function) - - -class Base(object): - def inheritedmeth(self): - """Inherited function.""" - - -class Derived(Base): - def inheritedmeth(self): - # no docstring here - pass - - -class Class(Base): - """Class to document.""" - - descr = CustomDataDescriptor("Descriptor instance docstring.") - - def meth(self): - """Function.""" - - def undocmeth(self): - pass - - def skipmeth(self): - """Method that should be skipped.""" - - def excludemeth(self): - """Method that should be excluded.""" - - # should not be documented - skipattr = 'foo' - - #: should be documented -- süß - attr = 'bar' - - @property - def prop(self): - """Property.""" - - docattr = 'baz' - """should likewise be documented -- süß""" - - udocattr = 'quux' - u"""should be documented as well - süß""" - - # initialized to any class imported from another module - mdocattr = StringIO() - """should be documented as well - süß""" - - roger = _funky_classmethod("roger", 2, 3, 4) - - moore = _funky_classmethod("moore", 9, 8, 7, - docstring="moore(a, e, f) -> happiness") - - def __init__(self, arg): - self.inst_attr_inline = None #: an inline documented instance attr - #: a documented instance attribute - self.inst_attr_comment = None - self.inst_attr_string = None - """a documented instance attribute""" - self._private_inst_attr = None #: a private instance attribute - - def __special1__(self): - """documented special method""" - - def __special2__(self): - # undocumented special method - pass - - -class CustomDict(dict): - """Docstring.""" - - -def function(foo, *args, **kwds): - """ - Return spam. - """ - pass - - -class Outer(object): - """Foo""" - - class Inner(object): - """Foo""" - - def meth(self): - """Foo""" - - # should be documented as an alias - factory = dict - - -class DocstringSig(object): - def meth(self): - """meth(FOO, BAR=1) -> BAZ -First line of docstring - - rest of docstring - """ - - def meth2(self): - """First line, no signature - Second line followed by indentation:: - - indented line - """ - - @property - def prop1(self): - """DocstringSig.prop1(self) - First line of docstring - """ - return 123 - - @property - def prop2(self): - """First line of docstring - Second line of docstring - """ - return 456 - - -class StrRepr(str): - def __repr__(self): - return self - - -class AttCls(object): - a1 = StrRepr('hello\nworld') - a2 = None - - -class InstAttCls(object): - """Class with documented class and instance attributes.""" - - #: Doc comment for class attribute InstAttCls.ca1. - #: It can have multiple lines. - ca1 = 'a' - - ca2 = 'b' #: Doc comment for InstAttCls.ca2. One line only. - - ca3 = 'c' - """Docstring for class attribute InstAttCls.ca3.""" - - def __init__(self): - #: Doc comment for instance attribute InstAttCls.ia1 - self.ia1 = 'd' - - self.ia2 = 'e' - """Docstring for instance attribute InstAttCls.ia2.""" - - -class EnumCls(enum.Enum): - """ - this is enum class - """ - - #: doc for val1 - val1 = 12 - val2 = 23 #: doc for val2 - val3 = 34 - """doc for val3""" diff --git a/tests/test_build.py b/tests/test_build.py index 387e308a8..df0458aa3 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -5,7 +5,7 @@ Test all builders. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -34,8 +34,8 @@ def nonascii_srcdir(request, rootdir, sphinx_test_tempdir): basedir = sphinx_test_tempdir / request.node.originalname # Windows with versions prior to 3.2 (I think) doesn't support unicode on system path # so we force a non-unicode path in that case - if sys.platform == "win32" and \ - not (sys.version_info.major >= 3 and sys.version_info.minor >= 2): + if (sys.platform == "win32" and + not (sys.version_info.major >= 3 and sys.version_info.minor >= 2)): return basedir / 'all' try: srcdir = basedir / test_name diff --git a/tests/test_build_applehelp.py b/tests/test_build_applehelp.py index 4418cb265..31d4ca4df 100644 --- a/tests/test_build_applehelp.py +++ b/tests/test_build_applehelp.py @@ -7,7 +7,7 @@ test the HTML itself; that's already handled by :file:`test_build_html.py`. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_build_epub.py b/tests/test_build_epub.py index 397547734..e5d86b0ed 100644 --- a/tests/test_build_epub.py +++ b/tests/test_build_epub.py @@ -245,5 +245,3 @@ def test_epub_writing_mode(app): # vertical / writing-mode (CSS) css = (app.outdir / '_static' / 'epub.css').text() assert 'writing-mode: vertical-rl;' in css - - diff --git a/tests/test_build_gettext.py b/tests/test_build_gettext.py index f256140fe..c14013f9a 100644 --- a/tests/test_build_gettext.py +++ b/tests/test_build_gettext.py @@ -5,7 +5,7 @@ Test the build process with gettext builder with the test root. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ from __future__ import print_function diff --git a/tests/test_build_html.py b/tests/test_build_html.py index b4fec18ba..8265c8471 100644 --- a/tests/test_build_html.py +++ b/tests/test_build_html.py @@ -5,7 +5,7 @@ Test the HTML builder and check output against XPath. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -15,7 +15,6 @@ from itertools import cycle, chain from six import PY3 -from sphinx import __display_version__ from sphinx.util.inventory import InventoryFile from sphinx.testing.util import remove_unicode_literals, strip_escseq import xml.etree.cElementTree as ElementTree @@ -182,8 +181,8 @@ def test_html_warnings(app, warning): r'-| |-'), ], 'autodoc.html': [ - (".//dt[@id='test_autodoc.Class']", ''), - (".//dt[@id='test_autodoc.function']/em", r'\*\*kwds'), + (".//dt[@id='autodoc_target.Class']", ''), + (".//dt[@id='autodoc_target.function']/em", r'\*\*kwds'), (".//dd/p", r'Return spam\.'), ], 'extapi.html': [ diff --git a/tests/test_build_html5.py b/tests/test_build_html5.py index 39b064b1c..4ac70be51 100644 --- a/tests/test_build_html5.py +++ b/tests/test_build_html5.py @@ -10,7 +10,7 @@ https://github.com/sphinx-doc/sphinx/pull/2805/files - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -90,8 +90,8 @@ def cached_etree_parse(): r'-| |-'), ], 'autodoc.html': [ - (".//dt[@id='test_autodoc.Class']", ''), - (".//dt[@id='test_autodoc.function']/em", r'\*\*kwds'), + (".//dt[@id='autodoc_target.Class']", ''), + (".//dt[@id='autodoc_target.function']/em", r'\*\*kwds'), (".//dd/p", r'Return spam\.'), ], 'extapi.html': [ diff --git a/tests/test_build_latex.py b/tests/test_build_latex.py index b78bcf637..ab91d7a48 100644 --- a/tests/test_build_latex.py +++ b/tests/test_build_latex.py @@ -5,7 +5,7 @@ Test the build process with LaTeX builder with the test root. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ from __future__ import print_function @@ -335,6 +335,56 @@ def test_numref_with_language_ja(app, status, warning): '\\nameref{\\detokenize{foo:foo}}}') in result +@pytest.mark.sphinx('latex', testroot='latex-numfig') +def test_latex_obey_numfig_is_false(app, status, warning): + app.builder.build_all() + + result = (app.outdir / 'SphinxManual.tex').text(encoding='utf8') + assert '\\usepackage{sphinx}' in result + + result = (app.outdir / 'SphinxHowTo.tex').text(encoding='utf8') + assert '\\usepackage{sphinx}' in result + + +@pytest.mark.sphinx( + 'latex', testroot='latex-numfig', + confoverrides={'numfig': True, 'numfig_secnum_depth': 0}) +def test_latex_obey_numfig_secnum_depth_is_zero(app, status, warning): + app.builder.build_all() + + result = (app.outdir / 'SphinxManual.tex').text(encoding='utf8') + assert '\\usepackage[,nonumfigreset,mathnumfig]{sphinx}' in result + + result = (app.outdir / 'SphinxHowTo.tex').text(encoding='utf8') + assert '\\usepackage[,nonumfigreset,mathnumfig]{sphinx}' in result + + +@pytest.mark.sphinx( + 'latex', testroot='latex-numfig', + confoverrides={'numfig': True, 'numfig_secnum_depth': 2}) +def test_latex_obey_numfig_secnum_depth_is_two(app, status, warning): + app.builder.build_all() + + result = (app.outdir / 'SphinxManual.tex').text(encoding='utf8') + assert '\\usepackage[,numfigreset=2,mathnumfig]{sphinx}' in result + + result = (app.outdir / 'SphinxHowTo.tex').text(encoding='utf8') + assert '\\usepackage[,numfigreset=3,mathnumfig]{sphinx}' in result + + +@pytest.mark.sphinx( + 'latex', testroot='latex-numfig', + confoverrides={'numfig': True, 'math_numfig': False}) +def test_latex_obey_numfig_but_math_numfig_false(app, status, warning): + app.builder.build_all() + + result = (app.outdir / 'SphinxManual.tex').text(encoding='utf8') + assert '\\usepackage[,numfigreset=1]{sphinx}' in result + + result = (app.outdir / 'SphinxHowTo.tex').text(encoding='utf8') + assert '\\usepackage[,numfigreset=2]{sphinx}' in result + + @pytest.mark.sphinx('latex') def test_latex_add_latex_package(app, status, warning): app.add_latex_package('foo') @@ -712,19 +762,16 @@ def test_latex_logo_if_not_found(app, status, warning): assert isinstance(exc, SphinxError) -@pytest.mark.sphinx('latex', testroot='toctree-maxdepth', - confoverrides={'latex_documents': [ - ('index', 'SphinxTests.tex', 'Sphinx Tests Documentation', - 'Georg Brandl', 'manual'), - ]}) +@pytest.mark.sphinx('latex', testroot='toctree-maxdepth') def test_toctree_maxdepth_manual(app, status, warning): app.builder.build_all() - result = (app.outdir / 'SphinxTests.tex').text(encoding='utf8') + result = (app.outdir / 'Python.tex').text(encoding='utf8') print(result) print(status.getvalue()) print(warning.getvalue()) assert '\\setcounter{tocdepth}{1}' in result assert '\\setcounter{secnumdepth}' not in result + assert '\\chapter{Foo}' in result @pytest.mark.sphinx( @@ -741,6 +788,7 @@ def test_toctree_maxdepth_howto(app, status, warning): print(warning.getvalue()) assert '\\setcounter{tocdepth}{2}' in result assert '\\setcounter{secnumdepth}' not in result + assert '\\section{Foo}' in result @pytest.mark.sphinx( @@ -754,6 +802,7 @@ def test_toctree_not_found(app, status, warning): print(warning.getvalue()) assert '\\setcounter{tocdepth}' not in result assert '\\setcounter{secnumdepth}' not in result + assert '\\chapter{Foo A}' in result @pytest.mark.sphinx( @@ -804,6 +853,26 @@ def test_latex_toplevel_sectioning_is_part(app, status, warning): print(status.getvalue()) print(warning.getvalue()) assert '\\part{Foo}' in result + assert '\\chapter{Foo A}' in result + assert '\\chapter{Foo B}' in result + + +@pytest.mark.sphinx( + 'latex', testroot='toctree-maxdepth', + confoverrides={'latex_toplevel_sectioning': 'part', + 'latex_documents': [ + ('index', 'Python.tex', 'Sphinx Tests Documentation', + 'Georg Brandl', 'howto') + ]}) +def test_latex_toplevel_sectioning_is_part_with_howto(app, status, warning): + app.builder.build_all() + result = (app.outdir / 'Python.tex').text(encoding='utf8') + print(result) + print(status.getvalue()) + print(warning.getvalue()) + assert '\\part{Foo}' in result + assert '\\section{Foo A}' in result + assert '\\section{Foo B}' in result @pytest.mark.sphinx( @@ -820,6 +889,22 @@ def test_latex_toplevel_sectioning_is_chapter(app, status, warning): @pytest.mark.sphinx( 'latex', testroot='toctree-maxdepth', + confoverrides={'latex_toplevel_sectioning': 'chapter', + 'latex_documents': [ + ('index', 'Python.tex', 'Sphinx Tests Documentation', + 'Georg Brandl', 'howto') + ]}) +def test_latex_toplevel_sectioning_is_chapter_with_howto(app, status, warning): + app.builder.build_all() + result = (app.outdir / 'Python.tex').text(encoding='utf8') + print(result) + print(status.getvalue()) + print(warning.getvalue()) + assert '\\section{Foo}' in result + + +@pytest.mark.sphinx( + 'latex', testroot='toctree-maxdepth', confoverrides={'latex_toplevel_sectioning': 'section'}) def test_latex_toplevel_sectioning_is_section(app, status, warning): app.builder.build_all() diff --git a/tests/test_build_linkcheck.py b/tests/test_build_linkcheck.py index cc3d6e24f..839a15628 100644 --- a/tests/test_build_linkcheck.py +++ b/tests/test_build_linkcheck.py @@ -5,7 +5,7 @@ Test the build process with manpage builder with the test root. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ from __future__ import print_function diff --git a/tests/test_build_manpage.py b/tests/test_build_manpage.py index 953332c73..3448d6eeb 100644 --- a/tests/test_build_manpage.py +++ b/tests/test_build_manpage.py @@ -5,7 +5,7 @@ Test the build process with manpage builder with the test root. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ from __future__ import print_function diff --git a/tests/test_build_qthelp.py b/tests/test_build_qthelp.py index 3e4815fbe..de676e6e0 100644 --- a/tests/test_build_qthelp.py +++ b/tests/test_build_qthelp.py @@ -7,7 +7,7 @@ test the HTML itself; that's already handled by :file:`test_build_html.py`. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_build_texinfo.py b/tests/test_build_texinfo.py index c4238c659..114f194fe 100644 --- a/tests/test_build_texinfo.py +++ b/tests/test_build_texinfo.py @@ -5,7 +5,7 @@ Test the build process with Texinfo builder with the test root. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ from __future__ import print_function diff --git a/tests/test_build_text.py b/tests/test_build_text.py index 81e354ecd..9bfbe1206 100644 --- a/tests/test_build_text.py +++ b/tests/test_build_text.py @@ -5,7 +5,7 @@ Test the build process with Text builder with the test root. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ import pytest diff --git a/tests/test_catalogs.py b/tests/test_catalogs.py index b3e17a0a1..4bfbb18a3 100644 --- a/tests/test_catalogs.py +++ b/tests/test_catalogs.py @@ -5,7 +5,7 @@ Test the base build process. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ import shutil diff --git a/tests/test_config.py b/tests/test_config.py index 578f6e55c..3f38c7ab8 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -6,7 +6,7 @@ Test the sphinx.config.Config class and its handling in the Application class. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ from six import PY3, iteritems diff --git a/tests/test_correct_year.py b/tests/test_correct_year.py index a8058f08c..e7501bb6a 100644 --- a/tests/test_correct_year.py +++ b/tests/test_correct_year.py @@ -5,7 +5,7 @@ Test copyright year adjustment - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ import pytest diff --git a/tests/test_directive_code.py b/tests/test_directive_code.py index e3069061b..f62f44f13 100644 --- a/tests/test_directive_code.py +++ b/tests/test_directive_code.py @@ -5,7 +5,7 @@ Test the code-block directive. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_directive_only.py b/tests/test_directive_only.py index d8017f469..010eae384 100644 --- a/tests/test_directive_only.py +++ b/tests/test_directive_only.py @@ -5,7 +5,7 @@ Test the only directive with the test root. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_docutilsconf.py b/tests/test_docutilsconf.py index fd5cf7a61..91bf8fc95 100644 --- a/tests/test_docutilsconf.py +++ b/tests/test_docutilsconf.py @@ -5,7 +5,7 @@ Test docutils.conf support for several writers. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -72,7 +72,7 @@ def test_texinfo(app, status, warning): @pytest.mark.sphinx('html', testroot='docutilsconf', docutilsconf='[general]\nsource_link=true\n') -@pytest.mark.skip(sys.platform == "win32" and \ +@pytest.mark.skip(sys.platform == "win32" and not (sys.version_info.major >= 3 and sys.version_info.minor >= 2), reason="Python < 3.2 on Win32 doesn't handle non-ASCII paths right") def test_docutils_source_link_with_nonascii_file(app, status, warning): diff --git a/tests/test_domain_cpp.py b/tests/test_domain_cpp.py index f3f0037f5..3561e76ce 100644 --- a/tests/test_domain_cpp.py +++ b/tests/test_domain_cpp.py @@ -5,7 +5,7 @@ Tests the C++ Domain - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -25,6 +25,7 @@ def parse(name, string): cpp_id_attributes = ["id_attr"] cpp_paren_attributes = ["paren_attr"] parser = DefinitionParser(string, None, Config()) + parser.allowFallbackExpressionParsing = False ast = parser.parse_declaration(name) parser.assert_end() # The scopedness would usually have been set by CPPEnumObject @@ -100,13 +101,13 @@ def test_fundamental_types(): if t == "std::nullptr_t": id = "NSt9nullptr_tE" return "1f%s" % id - check("function", "void f(%s arg)" % t, {1: makeIdV1(), 2:makeIdV2()}) + check("function", "void f(%s arg)" % t, {1: makeIdV1(), 2: makeIdV2()}) def test_expressions(): def exprCheck(expr, id): ids = 'IE1CIA%s_1aE' - check('class', 'template<> C<a[%s]>' % expr, {2:ids % expr, 3:ids % id}) + check('class', 'template<> C<a[%s]>' % expr, {2: ids % expr, 3: ids % id}) # primary exprCheck('nullptr', 'LDnE') exprCheck('true', 'L1E') @@ -117,9 +118,9 @@ def test_expressions(): for i in ints: for u in unsignedSuffix: for l in longSuffix: - expr = i + u + l; + expr = i + u + l exprCheck(expr, 'L' + expr + 'E') - expr = i + l + u; + expr = i + l + u exprCheck(expr, 'L' + expr + 'E') for suffix in ['', 'f', 'F', 'l', 'L']: expr = '5.0' + suffix @@ -199,55 +200,64 @@ def test_expressions(): # a < expression that starts with something that could be a template exprCheck('A < 42', 'lt1AL42E') check('function', 'template<> void f(A<B, 2> &v)', - {2:"IE1fR1AI1BX2EE", 3:"IE1fR1AI1BXL2EEE"}) + {2: "IE1fR1AI1BX2EE", 3: "IE1fR1AI1BXL2EEE"}) exprCheck('A<1>::value', 'N1AIXL1EEE5valueE') - check('class', "template<int T = 42> A", {2:"I_iE1A"}) - check('enumerator', 'A = std::numeric_limits<unsigned long>::max()', {2:"1A"}) + check('class', "template<int T = 42> A", {2: "I_iE1A"}) + check('enumerator', 'A = std::numeric_limits<unsigned long>::max()', {2: "1A"}) + + exprCheck('operator()()', 'clclE') + exprCheck('operator()<int>()', 'clclIiEE') def test_type_definitions(): - check("type", "public bool b", {1:"b", 2:"1b"}, "bool b") - check("type", "bool A::b", {1:"A::b", 2:"N1A1bE"}) - check("type", "bool *b", {1:"b", 2:"1b"}) - check("type", "bool *const b", {1:"b", 2:"1b"}) - check("type", "bool *volatile const b", {1:"b", 2:"1b"}) - check("type", "bool *volatile const b", {1:"b", 2:"1b"}) - check("type", "bool *volatile const *b", {1:"b", 2:"1b"}) - check("type", "bool &b", {1:"b", 2:"1b"}) - check("type", "bool b[]", {1:"b", 2:"1b"}) - check("type", "std::pair<int, int> coord", {1:"coord", 2:"5coord"}) - check("type", "long long int foo", {1:"foo", 2:"3foo"}) + check("type", "public bool b", {1: "b", 2: "1b"}, "bool b") + check("type", "bool A::b", {1: "A::b", 2: "N1A1bE"}) + check("type", "bool *b", {1: "b", 2: "1b"}) + check("type", "bool *const b", {1: "b", 2: "1b"}) + check("type", "bool *volatile const b", {1: "b", 2: "1b"}) + check("type", "bool *volatile const b", {1: "b", 2: "1b"}) + check("type", "bool *volatile const *b", {1: "b", 2: "1b"}) + check("type", "bool &b", {1: "b", 2: "1b"}) + check("type", "bool b[]", {1: "b", 2: "1b"}) + check("type", "std::pair<int, int> coord", {1: "coord", 2: "5coord"}) + check("type", "long long int foo", {1: "foo", 2: "3foo"}) check("type", 'std::vector<std::pair<std::string, long long>> module::blah', - {1:"module::blah", 2:"N6module4blahE"}) - check("type", "std::function<void()> F", {1:"F", 2:"1F"}) - check("type", "std::function<R(A1, A2)> F", {1:"F", 2:"1F"}) - check("type", "std::function<R(A1, A2, A3)> F", {1:"F", 2:"1F"}) - check("type", "std::function<R(A1, A2, A3, As...)> F", {1:"F", 2:"1F"}) + {1: "module::blah", 2: "N6module4blahE"}) + check("type", "std::function<void()> F", {1: "F", 2: "1F"}) + check("type", "std::function<R(A1, A2)> F", {1: "F", 2: "1F"}) + check("type", "std::function<R(A1, A2, A3)> F", {1: "F", 2: "1F"}) + check("type", "std::function<R(A1, A2, A3, As...)> F", {1: "F", 2: "1F"}) check("type", "MyContainer::const_iterator", - {1:"MyContainer::const_iterator", 2:"N11MyContainer14const_iteratorE"}) + {1: "MyContainer::const_iterator", 2: "N11MyContainer14const_iteratorE"}) check("type", "public MyContainer::const_iterator", - {1:"MyContainer::const_iterator", 2:"N11MyContainer14const_iteratorE"}, + {1: "MyContainer::const_iterator", 2: "N11MyContainer14const_iteratorE"}, output="MyContainer::const_iterator") # test decl specs on right - check("type", "bool const b", {1:"b", 2:"1b"}) + check("type", "bool const b", {1: "b", 2: "1b"}) # test name in global scope - check("type", "bool ::B::b", {1:"B::b", 2:"N1B1bE"}) + check("type", "bool ::B::b", {1: "B::b", 2: "N1B1bE"}) - check('type', 'A = B', {2:'1A'}) - check('type', 'A = decltype(b)', {2:'1A'}) + check('type', 'A = B', {2: '1A'}) + check('type', 'A = decltype(b)', {2: '1A'}) # from breathe#267 (named function parameters for function pointers check('type', 'void (*gpio_callback_t)(struct device *port, uint32_t pin)', - {1:'gpio_callback_t', 2:'15gpio_callback_t'}) - check('type', 'void (*f)(std::function<void(int i)> g)', {1:'f', 2:'1f'}) + {1: 'gpio_callback_t', 2: '15gpio_callback_t'}) + check('type', 'void (*f)(std::function<void(int i)> g)', {1: 'f', 2: '1f'}) + + check('type', 'T = A::template B<int>::template C<double>', {2: '1T'}) + + check('type', 'T = Q<A::operator()>', {2: '1T'}) + check('type', 'T = Q<A::operator()<int>>', {2: '1T'}) + check('type', 'T = Q<A::operator bool>', {2: '1T'}) def test_concept_definitions(): check('concept', 'template<typename Param> A::B::Concept', - {2:'I0EN1A1B7ConceptE'}) + {2: 'I0EN1A1B7ConceptE'}) check('concept', 'template<typename A, typename B, typename ...C> Foo', - {2:'I00DpE3Foo'}) + {2: 'I00DpE3Foo'}) with pytest.raises(DefinitionError): parse('concept', 'Foo') with pytest.raises(DefinitionError): @@ -256,269 +266,270 @@ def test_concept_definitions(): def test_member_definitions(): check('member', ' const std::string & name = 42', - {1:"name__ssCR", 2:"4name"}, output='const std::string &name = 42') - check('member', ' const std::string & name', {1:"name__ssCR", 2:"4name"}, + {1: "name__ssCR", 2: "4name"}, output='const std::string &name = 42') + check('member', ' const std::string & name', {1: "name__ssCR", 2: "4name"}, output='const std::string &name') check('member', ' const std::string & name [ n ]', - {1:"name__ssCRA", 2:"4name"}, output='const std::string &name[n]') + {1: "name__ssCRA", 2: "4name"}, output='const std::string &name[n]') check('member', 'const std::vector< unsigned int, long> &name', - {1:"name__std::vector:unsigned-i.l:CR", 2:"4name"}, + {1: "name__std::vector:unsigned-i.l:CR", 2: "4name"}, output='const std::vector<unsigned int, long> &name') - check('member', 'module::myclass foo[n]', {1:"foo__module::myclassA", 2:"3foo"}) - check('member', 'int *const p', {1:'p__iPC', 2:'1p'}) - check('member', 'extern int myInt', {1:'myInt__i', 2:'5myInt'}) - check('member', 'thread_local int myInt', {1:'myInt__i', 2:'5myInt'}) - check('member', 'extern thread_local int myInt', {1:'myInt__i', 2:'5myInt'}) - check('member', 'thread_local extern int myInt', {1:'myInt__i', 2:'5myInt'}, + check('member', 'module::myclass foo[n]', {1: "foo__module::myclassA", 2: "3foo"}) + check('member', 'int *const p', {1: 'p__iPC', 2: '1p'}) + check('member', 'extern int myInt', {1: 'myInt__i', 2: '5myInt'}) + check('member', 'thread_local int myInt', {1: 'myInt__i', 2: '5myInt'}) + check('member', 'extern thread_local int myInt', {1: 'myInt__i', 2: '5myInt'}) + check('member', 'thread_local extern int myInt', {1: 'myInt__i', 2: '5myInt'}, 'extern thread_local int myInt') def test_function_definitions(): - check('function', 'operator bool() const', {1:"castto-b-operatorC", 2:"NKcvbEv"}) + check('function', 'operator bool() const', {1: "castto-b-operatorC", 2: "NKcvbEv"}) check('function', 'A::operator bool() const', - {1:"A::castto-b-operatorC", 2:"NK1AcvbEv"}) + {1: "A::castto-b-operatorC", 2: "NK1AcvbEv"}) check('function', 'A::operator bool() volatile const &', - {1:"A::castto-b-operatorVCR", 2:"NVKR1AcvbEv"}) + {1: "A::castto-b-operatorVCR", 2: "NVKR1AcvbEv"}) check('function', 'A::operator bool() volatile const &&', - {1:"A::castto-b-operatorVCO", 2:"NVKO1AcvbEv"}) + {1: "A::castto-b-operatorVCO", 2: "NVKO1AcvbEv"}) check('function', 'bool namespaced::theclass::method(arg1, arg2)', - {1:"namespaced::theclass::method__arg1.arg2", - 2:"N10namespaced8theclass6methodE4arg14arg2"}) + {1: "namespaced::theclass::method__arg1.arg2", + 2: "N10namespaced8theclass6methodE4arg14arg2"}) x = 'std::vector<std::pair<std::string, int>> &module::test(register int ' \ 'foo, bar, std::string baz = "foobar, blah, bleh") const = 0' - check('function', x, {1:"module::test__i.bar.ssC", - 2:"NK6module4testEi3barNSt6stringE"}) + check('function', x, {1: "module::test__i.bar.ssC", + 2: "NK6module4testEi3barNSt6stringE"}) check('function', 'void f(std::pair<A, B>)', - {1:"f__std::pair:A.B:", 2:"1fNSt4pairI1A1BEE"}) + {1: "f__std::pair:A.B:", 2: "1fNSt4pairI1A1BEE"}) check('function', 'explicit module::myclass::foo::foo()', - {1:"module::myclass::foo::foo", 2:"N6module7myclass3foo3fooEv"}) + {1: "module::myclass::foo::foo", 2: "N6module7myclass3foo3fooEv"}) check('function', 'module::myclass::foo::~foo()', - {1:"module::myclass::foo::~foo", 2:"N6module7myclass3fooD0Ev"}) + {1: "module::myclass::foo::~foo", 2: "N6module7myclass3fooD0Ev"}) check('function', 'int printf(const char *fmt, ...)', - {1:"printf__cCP.z", 2:"6printfPKcz"}) + {1: "printf__cCP.z", 2: "6printfPKcz"}) check('function', 'int foo(const unsigned int j)', - {1:"foo__unsigned-iC", 2:"3fooKj"}) + {1: "foo__unsigned-iC", 2: "3fooKj"}) check('function', 'int foo(const int *const ptr)', - {1:"foo__iCPC", 2:"3fooPCKi"}) + {1: "foo__iCPC", 2: "3fooPCKi"}) check('function', 'module::myclass::operator std::vector<std::string>()', - {1:"module::myclass::castto-std::vector:ss:-operator", - 2:"N6module7myclasscvNSt6vectorINSt6stringEEEEv"}) + {1: "module::myclass::castto-std::vector:ss:-operator", + 2: "N6module7myclasscvNSt6vectorINSt6stringEEEEv"}) check('function', 'void operator()(const boost::array<VertexID, 2> &v) const', - {1:"call-operator__boost::array:VertexID.2:CRC", - 2:"NKclERKN5boost5arrayI8VertexIDX2EEE", - 3:"NKclERKN5boost5arrayI8VertexIDXL2EEEE"}) + {1: "call-operator__boost::array:VertexID.2:CRC", + 2: "NKclERKN5boost5arrayI8VertexIDX2EEE", + 3: "NKclERKN5boost5arrayI8VertexIDXL2EEEE"}) check('function', 'void operator()(const boost::array<VertexID, 2, "foo, bar"> &v) const', - {1:'call-operator__boost::array:VertexID.2."foo,--bar":CRC', - 2:'NKclERKN5boost5arrayI8VertexIDX2EX"foo, bar"EEE', - 3:'NKclERKN5boost5arrayI8VertexIDXL2EEXLA9_KcEEEE'}) + {1: 'call-operator__boost::array:VertexID.2."foo,--bar":CRC', + 2: 'NKclERKN5boost5arrayI8VertexIDX2EX"foo, bar"EEE', + 3: 'NKclERKN5boost5arrayI8VertexIDXL2EEXLA9_KcEEEE'}) check('function', 'MyClass::MyClass(MyClass::MyClass&&)', - {1:"MyClass::MyClass__MyClass::MyClassRR", - 2:"N7MyClass7MyClassERRN7MyClass7MyClassE"}) - check('function', 'constexpr int get_value()', {1:"get_valueCE", 2:"9get_valuev"}) + {1: "MyClass::MyClass__MyClass::MyClassRR", + 2: "N7MyClass7MyClassERRN7MyClass7MyClassE"}) + check('function', 'constexpr int get_value()', {1: "get_valueCE", 2: "9get_valuev"}) check('function', 'static constexpr int get_value()', - {1:"get_valueCE", 2:"9get_valuev"}) + {1: "get_valueCE", 2: "9get_valuev"}) check('function', 'int get_value() const noexcept', - {1:"get_valueC", 2:"NK9get_valueEv"}) + {1: "get_valueC", 2: "NK9get_valueEv"}) check('function', 'int get_value() const noexcept = delete', - {1:"get_valueC", 2:"NK9get_valueEv"}) + {1: "get_valueC", 2: "NK9get_valueEv"}) check('function', 'int get_value() volatile const', - {1:"get_valueVC", 2:"NVK9get_valueEv"}) + {1: "get_valueVC", 2: "NVK9get_valueEv"}) check('function', 'MyClass::MyClass(MyClass::MyClass&&) = default', - {1:"MyClass::MyClass__MyClass::MyClassRR", - 2:"N7MyClass7MyClassERRN7MyClass7MyClassE"}) + {1: "MyClass::MyClass__MyClass::MyClassRR", + 2: "N7MyClass7MyClassERRN7MyClass7MyClassE"}) check('function', 'virtual MyClass::a_virtual_function() const override', - {1:"MyClass::a_virtual_functionC", 2:"NK7MyClass18a_virtual_functionEv"}) - check('function', 'A B() override', {1:"B", 2:"1Bv"}) - check('function', 'A B() final', {1:"B", 2:"1Bv"}) - check('function', 'A B() final override', {1:"B", 2:"1Bv"}) - check('function', 'A B() override final', {1:"B", 2:"1Bv"}, + {1: "MyClass::a_virtual_functionC", 2: "NK7MyClass18a_virtual_functionEv"}) + check('function', 'A B() override', {1: "B", 2: "1Bv"}) + check('function', 'A B() final', {1: "B", 2: "1Bv"}) + check('function', 'A B() final override', {1: "B", 2: "1Bv"}) + check('function', 'A B() override final', {1: "B", 2: "1Bv"}, output='A B() final override') check('function', 'MyClass::a_member_function() volatile', - {1:"MyClass::a_member_functionV", 2:"NV7MyClass17a_member_functionEv"}) + {1: "MyClass::a_member_functionV", 2: "NV7MyClass17a_member_functionEv"}) check('function', 'MyClass::a_member_function() volatile const', - {1:"MyClass::a_member_functionVC", 2:"NVK7MyClass17a_member_functionEv"}) + {1: "MyClass::a_member_functionVC", 2: "NVK7MyClass17a_member_functionEv"}) check('function', 'MyClass::a_member_function() &&', - {1:"MyClass::a_member_functionO", 2:"NO7MyClass17a_member_functionEv"}) + {1: "MyClass::a_member_functionO", 2: "NO7MyClass17a_member_functionEv"}) check('function', 'MyClass::a_member_function() &', - {1:"MyClass::a_member_functionR", 2:"NR7MyClass17a_member_functionEv"}) + {1: "MyClass::a_member_functionR", 2: "NR7MyClass17a_member_functionEv"}) check('function', 'MyClass::a_member_function() const &', - {1:"MyClass::a_member_functionCR", 2:"NKR7MyClass17a_member_functionEv"}) + {1: "MyClass::a_member_functionCR", 2: "NKR7MyClass17a_member_functionEv"}) check('function', 'int main(int argc, char *argv[])', - {1:"main__i.cPA", 2:"4mainiA_Pc"}) + {1: "main__i.cPA", 2: "4mainiA_Pc"}) check('function', 'MyClass &MyClass::operator++()', - {1:"MyClass::inc-operator", 2:"N7MyClassppEv"}) + {1: "MyClass::inc-operator", 2: "N7MyClassppEv"}) check('function', 'MyClass::pointer MyClass::operator->()', - {1:"MyClass::pointer-operator", 2:"N7MyClassptEv"}) + {1: "MyClass::pointer-operator", 2: "N7MyClassptEv"}) x = 'std::vector<std::pair<std::string, int>> &module::test(register int ' \ 'foo, bar[n], std::string baz = "foobar, blah, bleh") const = 0' - check('function', x, {1:"module::test__i.barA.ssC", - 2:"NK6module4testEiAn_3barNSt6stringE", - 3:"NK6module4testEiA1n_3barNSt6stringE"}) + check('function', x, {1: "module::test__i.barA.ssC", + 2: "NK6module4testEiAn_3barNSt6stringE", + 3: "NK6module4testEiA1n_3barNSt6stringE"}) check('function', 'int foo(Foo f = Foo(double(), std::make_pair(int(2), double(3.4))))', - {1:"foo__Foo", 2:"3foo3Foo"}) - check('function', 'int foo(A a = x(a))', {1:"foo__A", 2:"3foo1A"}) + {1: "foo__Foo", 2: "3foo3Foo"}) + check('function', 'int foo(A a = x(a))', {1: "foo__A", 2: "3foo1A"}) with pytest.raises(DefinitionError): parse('function', 'int foo(B b=x(a)') with pytest.raises(DefinitionError): parse('function', 'int foo)C c=x(a))') with pytest.raises(DefinitionError): parse('function', 'int foo(D d=x(a') - check('function', 'int foo(const A&... a)', {1:"foo__ACRDp", 2:"3fooDpRK1A"}) - check('function', 'virtual void f()', {1:"f", 2:"1fv"}) + check('function', 'int foo(const A&... a)', {1: "foo__ACRDp", 2: "3fooDpRK1A"}) + check('function', 'virtual void f()', {1: "f", 2: "1fv"}) # test for ::nestedName, from issue 1738 check("function", "result(int val, ::std::error_category const &cat)", - {1:"result__i.std::error_categoryCR", 2:"6resultiRNSt14error_categoryE"}) - check("function", "int *f()", {1:"f", 2:"1fv"}) + {1: "result__i.std::error_categoryCR", 2: "6resultiRNSt14error_categoryE"}) + check("function", "int *f()", {1: "f", 2: "1fv"}) # tests derived from issue #1753 (skip to keep sanity) - check("function", "f(int (&array)[10])", {2:"1fRA10_i", 3:"1fRAL10E_i"}) - check("function", "void f(int (&array)[10])", {2:"1fRA10_i", 3:"1fRAL10E_i"}) - check("function", "void f(float *q(double))", {2:"1fFPfdE"}) - check("function", "void f(float *(*q)(double))", {2:"1fPFPfdE"}) - check("function", "void f(float (*q)(double))", {2:"1fPFfdE"}) - check("function", "int (*f(double d))(float)", {1:"f__double", 2:"1fd"}) - check("function", "int (*f(bool b))[5]", {1:"f__b", 2:"1fb"}) + check("function", "f(int (&array)[10])", {2: "1fRA10_i", 3: "1fRAL10E_i"}) + check("function", "void f(int (&array)[10])", {2: "1fRA10_i", 3: "1fRAL10E_i"}) + check("function", "void f(float *q(double))", {2: "1fFPfdE"}) + check("function", "void f(float *(*q)(double))", {2: "1fPFPfdE"}) + check("function", "void f(float (*q)(double))", {2: "1fPFfdE"}) + check("function", "int (*f(double d))(float)", {1: "f__double", 2: "1fd"}) + check("function", "int (*f(bool b))[5]", {1: "f__b", 2: "1fb"}) check("function", "int (*A::f(double d) const)(float)", - {1:"A::f__doubleC", 2:"NK1A1fEd"}) + {1: "A::f__doubleC", 2: "NK1A1fEd"}) check("function", "void f(std::shared_ptr<int(double)> ptr)", - {2:"1fNSt10shared_ptrIFidEEE"}) - check("function", "void f(int *const p)", {1:"f__iPC", 2:"1fPCi"}) - check("function", "void f(int *volatile const p)", {1:"f__iPVC", 2:"1fPVCi"}) + {2: "1fNSt10shared_ptrIFidEEE"}) + check("function", "void f(int *const p)", {1: "f__iPC", 2: "1fPCi"}) + check("function", "void f(int *volatile const p)", {1: "f__iPVC", 2: "1fPVCi"}) - check('function', 'extern int f()', {1:'f', 2:'1fv'}) + check('function', 'extern int f()', {1: 'f', 2: '1fv'}) - check('function', 'decltype(auto) f()', {1: 'f', 2:"1fv"}) + check('function', 'decltype(auto) f()', {1: 'f', 2: "1fv"}) # TODO: make tests for functions in a template, e.g., Test<int&&()> # such that the id generation for function type types is correct. check('function', 'friend std::ostream &f(std::ostream&, int)', - {1:'f__osR.i', 2:'1fRNSt7ostreamEi'}) + {1: 'f__osR.i', 2: '1fRNSt7ostreamEi'}) # from breathe#223 - check('function', 'void f(struct E e)', {1:'f__E', 2:'1f1E'}) - check('function', 'void f(class E e)', {1:'f__E', 2:'1f1E'}) - check('function', 'void f(typename E e)', {1:'f__E', 2:'1f1E'}) - check('function', 'void f(enum E e)', {1:'f__E', 2:'1f1E'}) - check('function', 'void f(union E e)', {1:'f__E', 2:'1f1E'}) + check('function', 'void f(struct E e)', {1: 'f__E', 2: '1f1E'}) + check('function', 'void f(class E e)', {1: 'f__E', 2: '1f1E'}) + check('function', 'void f(typename E e)', {1: 'f__E', 2: '1f1E'}) + check('function', 'void f(enum E e)', {1: 'f__E', 2: '1f1E'}) + check('function', 'void f(union E e)', {1: 'f__E', 2: '1f1E'}) # pointer to member (function) - check('function', 'void f(int C::*)', {2:'1fM1Ci'}) - check('function', 'void f(int C::* p)', {2:'1fM1Ci'}) - check('function', 'void f(int ::C::* p)', {2:'1fM1Ci'}) - check('function', 'void f(int C::* const)', {2:'1fKM1Ci'}) - check('function', 'void f(int C::* const&)', {2:'1fRKM1Ci'}) - check('function', 'void f(int C::* volatile)', {2:'1fVM1Ci'}) - check('function', 'void f(int C::* const volatile)', {2:'1fVKM1Ci'}, + check('function', 'void f(int C::*)', {2: '1fM1Ci'}) + check('function', 'void f(int C::* p)', {2: '1fM1Ci'}) + check('function', 'void f(int ::C::* p)', {2: '1fM1Ci'}) + check('function', 'void f(int C::* const)', {2: '1fKM1Ci'}) + check('function', 'void f(int C::* const&)', {2: '1fRKM1Ci'}) + check('function', 'void f(int C::* volatile)', {2: '1fVM1Ci'}) + check('function', 'void f(int C::* const volatile)', {2: '1fVKM1Ci'}, output='void f(int C::* volatile const)') - check('function', 'void f(int C::* volatile const)', {2:'1fVKM1Ci'}) - check('function', 'void f(int (C::*)(float, double))', {2:'1fM1CFifdE'}) - check('function', 'void f(int (C::* p)(float, double))', {2:'1fM1CFifdE'}) - check('function', 'void f(int (::C::* p)(float, double))', {2:'1fM1CFifdE'}) - check('function', 'void f(void (C::*)() const &)', {2:'1fM1CKRFvvE'}) - check('function', 'int C::* f(int, double)', {2:'1fid'}) - check('function', 'void f(int C::* *)', {2:'1fPM1Ci'}) + check('function', 'void f(int C::* volatile const)', {2: '1fVKM1Ci'}) + check('function', 'void f(int (C::*)(float, double))', {2: '1fM1CFifdE'}) + check('function', 'void f(int (C::* p)(float, double))', {2: '1fM1CFifdE'}) + check('function', 'void f(int (::C::* p)(float, double))', {2: '1fM1CFifdE'}) + check('function', 'void f(void (C::*)() const &)', {2: '1fM1CKRFvvE'}) + check('function', 'int C::* f(int, double)', {2: '1fid'}) + check('function', 'void f(int C::* *)', {2: '1fPM1Ci'}) def test_operators(): check('function', 'void operator new [ ] ()', - {1:"new-array-operator", 2:"nav"}, output='void operator new[]()') + {1: "new-array-operator", 2: "nav"}, output='void operator new[]()') check('function', 'void operator delete ()', - {1:"delete-operator", 2:"dlv"}, output='void operator delete()') + {1: "delete-operator", 2: "dlv"}, output='void operator delete()') check('function', 'operator bool() const', - {1:"castto-b-operatorC", 2:"NKcvbEv"}, output='operator bool() const') + {1: "castto-b-operatorC", 2: "NKcvbEv"}, output='operator bool() const') check('function', 'void operator * ()', - {1:"mul-operator", 2:"mlv"}, output='void operator*()') + {1: "mul-operator", 2: "mlv"}, output='void operator*()') check('function', 'void operator - ()', - {1:"sub-operator", 2:"miv"}, output='void operator-()') + {1: "sub-operator", 2: "miv"}, output='void operator-()') check('function', 'void operator + ()', - {1:"add-operator", 2:"plv"}, output='void operator+()') + {1: "add-operator", 2: "plv"}, output='void operator+()') check('function', 'void operator = ()', - {1:"assign-operator", 2:"aSv"}, output='void operator=()') + {1: "assign-operator", 2: "aSv"}, output='void operator=()') check('function', 'void operator / ()', - {1:"div-operator", 2:"dvv"}, output='void operator/()') + {1: "div-operator", 2: "dvv"}, output='void operator/()') check('function', 'void operator % ()', - {1:"mod-operator", 2:"rmv"}, output='void operator%()') + {1: "mod-operator", 2: "rmv"}, output='void operator%()') check('function', 'void operator ! ()', - {1:"not-operator", 2:"ntv"}, output='void operator!()') + {1: "not-operator", 2: "ntv"}, output='void operator!()') check('function', 'void operator "" _udl()', - {2:'li4_udlv'}, output='void operator""_udl()') + {2: 'li4_udlv'}, output='void operator""_udl()') def test_class_definitions(): - check('class', 'public A', {1:"A", 2:"1A"}, output='A') - check('class', 'private A', {1:"A", 2:"1A"}) - check('class', 'A final', {1:'A', 2:'1A'}) + check('class', 'public A', {1: "A", 2: "1A"}, output='A') + check('class', 'private A', {1: "A", 2: "1A"}) + check('class', 'A final', {1: 'A', 2: '1A'}) # test bases - check('class', 'A', {1:"A", 2:"1A"}) - check('class', 'A::B::C', {1:"A::B::C", 2:"N1A1B1CE"}) - check('class', 'A : B', {1:"A", 2:"1A"}) - check('class', 'A : private B', {1:"A", 2:"1A"}, output='A : B') - check('class', 'A : public B', {1:"A", 2:"1A"}) - check('class', 'A : B, C', {1:"A", 2:"1A"}) - check('class', 'A : B, protected C, D', {1:"A", 2:"1A"}) - check('class', 'A : virtual private B', {1:'A', 2:'1A'}, output='A : virtual B') - check('class', 'A : B, virtual C', {1:'A', 2:'1A'}) - check('class', 'A : public virtual B', {1:'A', 2:'1A'}) - check('class', 'A : B, C...', {1:'A', 2:'1A'}) - check('class', 'A : B..., C', {1:'A', 2:'1A'}) + check('class', 'A', {1: "A", 2: "1A"}) + check('class', 'A::B::C', {1: "A::B::C", 2: "N1A1B1CE"}) + check('class', 'A : B', {1: "A", 2: "1A"}) + check('class', 'A : private B', {1: "A", 2: "1A"}, output='A : B') + check('class', 'A : public B', {1: "A", 2: "1A"}) + check('class', 'A : B, C', {1: "A", 2: "1A"}) + check('class', 'A : B, protected C, D', {1: "A", 2: "1A"}) + check('class', 'A : virtual private B', {1: 'A', 2: '1A'}, output='A : virtual B') + check('class', 'A : B, virtual C', {1: 'A', 2: '1A'}) + check('class', 'A : public virtual B', {1: 'A', 2: '1A'}) + check('class', 'A : B, C...', {1: 'A', 2: '1A'}) + check('class', 'A : B..., C', {1: 'A', 2: '1A'}) # from #4094 - check('class', 'template<class, class = std::void_t<>> has_var', {2:'I00E7has_var'}) - check('class', 'template<class T> has_var<T, std::void_t<decltype(&T::var)>>', {2:'I0E7has_varI1TNSt6void_tIDTadN1T3varEEEEE'}) + check('class', 'template<class, class = std::void_t<>> has_var', {2: 'I00E7has_var'}) + check('class', 'template<class T> has_var<T, std::void_t<decltype(&T::var)>>', + {2: 'I0E7has_varI1TNSt6void_tIDTadN1T3varEEEEE'}) def test_enum_definitions(): - check('enum', 'A', {2:"1A"}) - check('enum', 'A : std::underlying_type<B>::type', {2:"1A"}) - check('enum', 'A : unsigned int', {2:"1A"}) - check('enum', 'public A', {2:"1A"}, output='A') - check('enum', 'private A', {2:"1A"}) + check('enum', 'A', {2: "1A"}) + check('enum', 'A : std::underlying_type<B>::type', {2: "1A"}) + check('enum', 'A : unsigned int', {2: "1A"}) + check('enum', 'public A', {2: "1A"}, output='A') + check('enum', 'private A', {2: "1A"}) - check('enumerator', 'A', {2:"1A"}) - check('enumerator', 'A = std::numeric_limits<unsigned long>::max()', {2:"1A"}) + check('enumerator', 'A', {2: "1A"}) + check('enumerator', 'A = std::numeric_limits<unsigned long>::max()', {2: "1A"}) def test_templates(): - check('class', "A<T>", {2:"IE1AI1TE"}, output="template<> A<T>") + check('class', "A<T>", {2: "IE1AI1TE"}, output="template<> A<T>") # first just check which objects support templating - check('class', "template<> A", {2:"IE1A"}) - check('function', "template<> void A()", {2:"IE1Av"}) - check('member', "template<> A a", {2:"IE1a"}) - check('type', "template<> a = A", {2:"IE1a"}) + check('class', "template<> A", {2: "IE1A"}) + check('function', "template<> void A()", {2: "IE1Av"}) + check('member', "template<> A a", {2: "IE1a"}) + check('type', "template<> a = A", {2: "IE1a"}) with pytest.raises(DefinitionError): parse('enum', "template<> A") with pytest.raises(DefinitionError): parse('enumerator', "template<> A") # then all the real tests - check('class', "template<typename T1, typename T2> A", {2:"I00E1A"}) - check('type', "template<> a", {2:"IE1a"}) + check('class', "template<typename T1, typename T2> A", {2: "I00E1A"}) + check('type', "template<> a", {2: "IE1a"}) - check('class', "template<typename T> A", {2:"I0E1A"}) - check('class', "template<class T> A", {2:"I0E1A"}) - check('class', "template<typename ...T> A", {2:"IDpE1A"}) - check('class', "template<typename...> A", {2:"IDpE1A"}) - check('class', "template<typename = Test> A", {2:"I0E1A"}) - check('class', "template<typename T = Test> A", {2:"I0E1A"}) + check('class', "template<typename T> A", {2: "I0E1A"}) + check('class', "template<class T> A", {2: "I0E1A"}) + check('class', "template<typename ...T> A", {2: "IDpE1A"}) + check('class', "template<typename...> A", {2: "IDpE1A"}) + check('class', "template<typename = Test> A", {2: "I0E1A"}) + check('class', "template<typename T = Test> A", {2: "I0E1A"}) - check('class', "template<template<typename> typename T> A", {2:"II0E0E1A"}) + check('class', "template<template<typename> typename T> A", {2: "II0E0E1A"}) check('class', "template<template<typename> typename> A", {2: "II0E0E1A"}) - check('class', "template<template<typename> typename ...T> A", {2:"II0EDpE1A"}) + check('class', "template<template<typename> typename ...T> A", {2: "II0EDpE1A"}) check('class', "template<template<typename> typename...> A", {2: "II0EDpE1A"}) - check('class', "template<int> A", {2:"I_iE1A"}) - check('class', "template<int T> A", {2:"I_iE1A"}) - check('class', "template<int... T> A", {2:"I_DpiE1A"}) - check('class', "template<int T = 42> A", {2:"I_iE1A"}) - check('class', "template<int = 42> A", {2:"I_iE1A"}) + check('class', "template<int> A", {2: "I_iE1A"}) + check('class', "template<int T> A", {2: "I_iE1A"}) + check('class', "template<int... T> A", {2: "I_DpiE1A"}) + check('class', "template<int T = 42> A", {2: "I_iE1A"}) + check('class', "template<int = 42> A", {2: "I_iE1A"}) - check('class', "template<> A<NS::B<>>", {2:"IE1AIN2NS1BIEEE"}) + check('class', "template<> A<NS::B<>>", {2: "IE1AIN2NS1BIEEE"}) # from #2058 check('function', @@ -526,8 +537,8 @@ def test_templates(): "inline std::basic_ostream<Char, Traits> &operator<<(" "std::basic_ostream<Char, Traits> &os, " "const c_string_view_base<const Char, Traits> &str)", - {2:"I00ElsRNSt13basic_ostreamI4Char6TraitsEE" - "RK18c_string_view_baseIK4Char6TraitsE"}) + {2: "I00ElsRNSt13basic_ostreamI4Char6TraitsEE" + "RK18c_string_view_baseIK4Char6TraitsE"}) # template introductions with pytest.raises(DefinitionError): @@ -535,73 +546,75 @@ def test_templates(): with pytest.raises(DefinitionError): parse('enumerator', 'abc::ns::foo{id_0, id_1, id_2} A') check('class', 'abc::ns::foo{id_0, id_1, id_2} xyz::bar', - {2:'I000EXN3abc2ns3fooEI4id_04id_14id_2EEN3xyz3barE'}) + {2: 'I000EXN3abc2ns3fooEI4id_04id_14id_2EEN3xyz3barE'}) check('class', 'abc::ns::foo{id_0, id_1, ...id_2} xyz::bar', - {2:'I00DpEXN3abc2ns3fooEI4id_04id_1sp4id_2EEN3xyz3barE'}) + {2: 'I00DpEXN3abc2ns3fooEI4id_04id_1sp4id_2EEN3xyz3barE'}) check('class', 'abc::ns::foo{id_0, id_1, id_2} xyz::bar<id_0, id_1, id_2>', - {2:'I000EXN3abc2ns3fooEI4id_04id_14id_2EEN3xyz3barI4id_04id_14id_2EE'}) + {2: 'I000EXN3abc2ns3fooEI4id_04id_14id_2EEN3xyz3barI4id_04id_14id_2EE'}) check('class', 'abc::ns::foo{id_0, id_1, ...id_2} xyz::bar<id_0, id_1, id_2...>', - {2:'I00DpEXN3abc2ns3fooEI4id_04id_1sp4id_2EEN3xyz3barI4id_04id_1Dp4id_2EE'}) + {2: 'I00DpEXN3abc2ns3fooEI4id_04id_1sp4id_2EEN3xyz3barI4id_04id_1Dp4id_2EE'}) - check('class', 'template<> Concept{U} A<int>::B', {2:'IEI0EX7ConceptI1UEEN1AIiE1BE'}) + check('class', 'template<> Concept{U} A<int>::B', {2: 'IEI0EX7ConceptI1UEEN1AIiE1BE'}) check('type', 'abc::ns::foo{id_0, id_1, id_2} xyz::bar = ghi::qux', - {2:'I000EXN3abc2ns3fooEI4id_04id_14id_2EEN3xyz3barE'}) + {2: 'I000EXN3abc2ns3fooEI4id_04id_14id_2EEN3xyz3barE'}) check('type', 'abc::ns::foo{id_0, id_1, ...id_2} xyz::bar = ghi::qux', - {2:'I00DpEXN3abc2ns3fooEI4id_04id_1sp4id_2EEN3xyz3barE'}) + {2: 'I00DpEXN3abc2ns3fooEI4id_04id_1sp4id_2EEN3xyz3barE'}) check('function', 'abc::ns::foo{id_0, id_1, id_2} void xyz::bar()', - {2:'I000EXN3abc2ns3fooEI4id_04id_14id_2EEN3xyz3barEv'}) + {2: 'I000EXN3abc2ns3fooEI4id_04id_14id_2EEN3xyz3barEv'}) check('function', 'abc::ns::foo{id_0, id_1, ...id_2} void xyz::bar()', - {2:'I00DpEXN3abc2ns3fooEI4id_04id_1sp4id_2EEN3xyz3barEv'}) + {2: 'I00DpEXN3abc2ns3fooEI4id_04id_1sp4id_2EEN3xyz3barEv'}) check('member', 'abc::ns::foo{id_0, id_1, id_2} ghi::qux xyz::bar', - {2:'I000EXN3abc2ns3fooEI4id_04id_14id_2EEN3xyz3barE'}) + {2: 'I000EXN3abc2ns3fooEI4id_04id_14id_2EEN3xyz3barE'}) check('member', 'abc::ns::foo{id_0, id_1, ...id_2} ghi::qux xyz::bar', - {2:'I00DpEXN3abc2ns3fooEI4id_04id_1sp4id_2EEN3xyz3barE'}) - check('concept', 'Iterator{T, U} Another', {2:'I00EX8IteratorI1T1UEE7Another'}) + {2: 'I00DpEXN3abc2ns3fooEI4id_04id_1sp4id_2EEN3xyz3barE'}) + check('concept', 'Iterator{T, U} Another', {2: 'I00EX8IteratorI1T1UEE7Another'}) check('concept', 'template<typename ...Pack> Numerics = (... && Numeric<Pack>)', - {2:'IDpE8Numerics'}) + {2: 'IDpE8Numerics'}) # explicit specializations of members - check('member', 'template<> int A<int>::a', {2:'IEN1AIiE1aE'}) + check('member', 'template<> int A<int>::a', {2: 'IEN1AIiE1aE'}) check('member', 'template int A<int>::a', {2: 'IEN1AIiE1aE'}, output='template<> int A<int>::a') # same as above - check('member', 'template<> template<> int A<int>::B<int>::b', {2:'IEIEN1AIiE1BIiE1bE'}) + check('member', 'template<> template<> int A<int>::B<int>::b', {2: 'IEIEN1AIiE1BIiE1bE'}) check('member', 'template int A<int>::B<int>::b', {2: 'IEIEN1AIiE1BIiE1bE'}, output='template<> template<> int A<int>::B<int>::b') # same as above + # defaulted constrained type parameters + check('type', 'template<C T = int&> A', {2: 'I_1CE1A'}) + def test_template_args(): # from breathe#218 check('function', "template<typename F> " "void allow(F *f, typename func<F, B, G != 1>::type tt)", - {2:"I0E5allowP1FN4funcI1F1BXG != 1EE4typeE", - 3:"I0E5allowP1FN4funcI1F1BXne1GL1EEE4typeE"}) + {2: "I0E5allowP1FN4funcI1F1BXG != 1EE4typeE", + 3: "I0E5allowP1FN4funcI1F1BXne1GL1EEE4typeE"}) # from #3542 check('type', "template<typename T> " "enable_if_not_array_t = std::enable_if_t<!is_array<T>::value, int>", - {2:"I0E21enable_if_not_array_t"}) - + {2: "I0E21enable_if_not_array_t"}) def test_attributes(): # style: C++ - check('member', '[[]] int f', {1:'f__i', 2:'1f'}) - check('member', '[ [ ] ] int f', {1:'f__i', 2:'1f'}, + check('member', '[[]] int f', {1: 'f__i', 2: '1f'}) + check('member', '[ [ ] ] int f', {1: 'f__i', 2: '1f'}, # this will fail when the proper grammar is implemented output='[[ ]] int f') - check('member', '[[a]] int f', {1:'f__i', 2:'1f'}) + check('member', '[[a]] int f', {1: 'f__i', 2: '1f'}) # style: GNU - check('member', '__attribute__(()) int f', {1:'f__i', 2:'1f'}) - check('member', '__attribute__((a)) int f', {1:'f__i', 2:'1f'}) - check('member', '__attribute__((a, b)) int f', {1:'f__i', 2:'1f'}) + check('member', '__attribute__(()) int f', {1: 'f__i', 2: '1f'}) + check('member', '__attribute__((a)) int f', {1: 'f__i', 2: '1f'}) + check('member', '__attribute__((a, b)) int f', {1: 'f__i', 2: '1f'}) # style: user-defined id - check('member', 'id_attr int f', {1:'f__i', 2:'1f'}) + check('member', 'id_attr int f', {1: 'f__i', 2: '1f'}) # style: user-defined paren - check('member', 'paren_attr() int f', {1:'f__i', 2:'1f'}) - check('member', 'paren_attr(a) int f', {1:'f__i', 2:'1f'}) - check('member', 'paren_attr("") int f', {1:'f__i', 2:'1f'}) - check('member', 'paren_attr(()[{}][]{}) int f', {1:'f__i', 2:'1f'}) + check('member', 'paren_attr() int f', {1: 'f__i', 2: '1f'}) + check('member', 'paren_attr(a) int f', {1: 'f__i', 2: '1f'}) + check('member', 'paren_attr("") int f', {1: 'f__i', 2: '1f'}) + check('member', 'paren_attr(()[{}][]{}) int f', {1: 'f__i', 2: '1f'}) with pytest.raises(DefinitionError): parse('member', 'paren_attr(() int f') with pytest.raises(DefinitionError): @@ -617,7 +630,7 @@ def test_attributes(): # position: decl specs check('function', 'static inline __attribute__(()) void f()', - {1:'f', 2:'1fv'}, + {1: 'f', 2: '1fv'}, output='__attribute__(()) static inline void f()') diff --git a/tests/test_domain_js.py b/tests/test_domain_js.py index 22faf4458..a609dcefe 100644 --- a/tests/test_domain_js.py +++ b/tests/test_domain_js.py @@ -5,7 +5,7 @@ Tests the JavaScript Domain - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_domain_py.py b/tests/test_domain_py.py index bf391053f..0c1d28dd9 100644 --- a/tests/test_domain_py.py +++ b/tests/test_domain_py.py @@ -5,7 +5,7 @@ Tests the Python Domain - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_domain_rst.py b/tests/test_domain_rst.py index 1e55e92a1..8cfe7e284 100644 --- a/tests/test_domain_rst.py +++ b/tests/test_domain_rst.py @@ -5,7 +5,7 @@ Tests the reStructuredText domain. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_domain_std.py b/tests/test_domain_std.py index edd5a0ebf..06573fa38 100644 --- a/tests/test_domain_std.py +++ b/tests/test_domain_std.py @@ -5,7 +5,7 @@ Tests the std domain - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_environment.py b/tests/test_environment.py index 611d34577..6f9ffec08 100644 --- a/tests/test_environment.py +++ b/tests/test_environment.py @@ -5,7 +5,7 @@ Test the BuildEnvironment class. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ import pytest @@ -22,7 +22,7 @@ def setup_module(rootdir, sphinx_test_tempdir): global app, env srcdir = sphinx_test_tempdir / 'root-envtest' if not srcdir.exists(): - (rootdir/'test-root').copytree(srcdir) + (rootdir / 'test-root').copytree(srcdir) app = SphinxTestApp(srcdir=srcdir) env = app.env yield diff --git a/tests/test_environment_indexentries.py b/tests/test_environment_indexentries.py index b9de151cc..03e4d9662 100644 --- a/tests/test_environment_indexentries.py +++ b/tests/test_environment_indexentries.py @@ -5,7 +5,7 @@ Test the sphinx.environment.managers.indexentries. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_environment_toctree.py b/tests/test_environment_toctree.py index f7a24d1fc..26334858b 100644 --- a/tests/test_environment_toctree.py +++ b/tests/test_environment_toctree.py @@ -5,7 +5,7 @@ Test the sphinx.environment.managers.toctree. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_ext_apidoc.py b/tests/test_ext_apidoc.py index d98dbabb6..2bfc8016e 100644 --- a/tests/test_ext_apidoc.py +++ b/tests/test_ext_apidoc.py @@ -5,7 +5,7 @@ Test the sphinx.apidoc module. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -188,3 +188,80 @@ def test_extension_parsed(make_app, apidoc): with open(outdir / 'conf.py') as f: rst = f.read() assert "sphinx.ext.mathjax" in rst + + +@pytest.mark.apidoc( + coderoot='test-apidoc-toc/mypackage', + options=["--implicit-namespaces"], +) +def test_toc_all_references_should_exist_pep420_enabled(make_app, apidoc): + """All references in toc should exist. This test doesn't say if + directories with empty __init__.py and and nothing else should be + skipped, just ensures consistency between what's referenced in the toc + and what is created. This is the variant with pep420 enabled. + """ + outdir = apidoc.outdir + assert (outdir / 'conf.py').isfile() + + toc = extract_toc(outdir / 'mypackage.rst') + + refs = [l.strip() for l in toc.splitlines() if l.strip()] + found_refs = [] + missing_files = [] + for ref in refs: + if ref and ref[0] in (':', '#'): + continue + found_refs.append(ref) + filename = "{}.rst".format(ref) + if not (outdir / filename).isfile(): + missing_files.append(filename) + + assert len(missing_files) == 0, \ + 'File(s) referenced in TOC not found: {}\n' \ + 'TOC:\n{}'.format(", ".join(missing_files), toc) + + +@pytest.mark.apidoc( + coderoot='test-apidoc-toc/mypackage', +) +def test_toc_all_references_should_exist_pep420_disabled(make_app, apidoc): + """All references in toc should exist. This test doesn't say if + directories with empty __init__.py and and nothing else should be + skipped, just ensures consistency between what's referenced in the toc + and what is created. This is the variant with pep420 disabled. + """ + outdir = apidoc.outdir + assert (outdir / 'conf.py').isfile() + + toc = extract_toc(outdir / 'mypackage.rst') + + refs = [l.strip() for l in toc.splitlines() if l.strip()] + found_refs = [] + missing_files = [] + for ref in refs: + if ref and ref[0] in (':', '#'): + continue + filename = "{}.rst".format(ref) + found_refs.append(ref) + if not (outdir / filename).isfile(): + missing_files.append(filename) + + assert len(missing_files) == 0, \ + 'File(s) referenced in TOC not found: {}\n' \ + 'TOC:\n{}'.format(", ".join(missing_files), toc) + + +def extract_toc(path): + """Helper: Extract toc section from package rst file""" + with open(path) as f: + rst = f.read() + + # Read out the part containing the toctree + toctree_start = "\n.. toctree::\n" + toctree_end = "\nSubmodules" + + start_idx = rst.index(toctree_start) + end_idx = rst.index(toctree_end, start_idx) + toctree = rst[start_idx + len(toctree_start):end_idx] + + return toctree diff --git a/tests/test_ext_autodoc.py b/tests/test_ext_autodoc.py index 1c1ebf7a0..e7057df0f 100644 --- a/tests/test_ext_autodoc.py +++ b/tests/test_ext_autodoc.py @@ -5,7 +5,7 @@ Test the autodoc extension. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_ext_autosectionlabel.py b/tests/test_ext_autosectionlabel.py index 4726a2378..1266edbc3 100644 --- a/tests/test_ext_autosectionlabel.py +++ b/tests/test_ext_autosectionlabel.py @@ -5,7 +5,7 @@ Test sphinx.ext.autosectionlabel extension. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_ext_autosummary.py b/tests/test_ext_autosummary.py index b59f0cbc8..ce5aa6e85 100644 --- a/tests/test_ext_autosummary.py +++ b/tests/test_ext_autosummary.py @@ -5,7 +5,7 @@ Test the autosummary extension. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -57,10 +57,14 @@ def test_mangle_signature(): @pytest.mark.sphinx('dummy', **default_kw) -def test_get_items_summary(app, status, warning): +def test_get_items_summary(make_app, app_params): + import sphinx.ext.autosummary + import sphinx.ext.autosummary.generate + args, kwargs = app_params + app = make_app(*args, **kwargs) + sphinx.ext.autosummary.generate.setup_documenters(app) # monkey-patch Autosummary.get_items so we can easily get access to it's # results.. - import sphinx.ext.autosummary orig_get_items = sphinx.ext.autosummary.Autosummary.get_items autosummary_items = {} @@ -73,6 +77,10 @@ def test_get_items_summary(app, status, warning): def handler(app, what, name, obj, options, lines): assert isinstance(lines, list) + + # ensure no docstring is processed twice: + assert 'THIS HAS BEEN HANDLED' not in lines + lines.append('THIS HAS BEEN HANDLED') app.connect('autodoc-process-docstring', handler) sphinx.ext.autosummary.Autosummary.get_items = new_get_items @@ -81,7 +89,7 @@ def test_get_items_summary(app, status, warning): finally: sphinx.ext.autosummary.Autosummary.get_items = orig_get_items - html_warnings = warning.getvalue() + html_warnings = app._warning.getvalue() assert html_warnings == '' expected_values = { @@ -163,7 +171,8 @@ def test_import_by_name(): assert parent is sphinx.ext.autosummary assert modname == 'sphinx.ext.autosummary' - prefixed_name, obj, parent, modname = import_by_name('sphinx.ext.autosummary.Autosummary.get_items') + prefixed_name, obj, parent, modname = \ + import_by_name('sphinx.ext.autosummary.Autosummary.get_items') assert prefixed_name == 'sphinx.ext.autosummary.Autosummary.get_items' assert obj == sphinx.ext.autosummary.Autosummary.get_items assert parent is sphinx.ext.autosummary.Autosummary diff --git a/tests/test_ext_coverage.py b/tests/test_ext_coverage.py index ff3fb4c02..a8f222a00 100644 --- a/tests/test_ext_coverage.py +++ b/tests/test_ext_coverage.py @@ -5,7 +5,7 @@ Test the coverage builder. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -21,9 +21,9 @@ def test_build(app, status, warning): py_undoc = (app.outdir / 'python.txt').text() assert py_undoc.startswith('Undocumented Python objects\n' '===========================\n') - assert 'test_autodoc\n------------\n' in py_undoc + assert 'autodoc_target\n--------------\n' in py_undoc assert ' * Class -- missing methods:\n' in py_undoc - assert ' * process_docstring\n' in py_undoc + assert ' * raises\n' in py_undoc assert ' * function\n' not in py_undoc # these two are documented assert ' * Class\n' not in py_undoc # in autodoc.txt @@ -40,9 +40,9 @@ def test_build(app, status, warning): # the key is the full path to the header file, which isn't testable assert list(undoc_c.values())[0] == set([('function', 'Py_SphinxTest')]) - assert 'test_autodoc' in undoc_py - assert 'funcs' in undoc_py['test_autodoc'] - assert 'process_docstring' in undoc_py['test_autodoc']['funcs'] - assert 'classes' in undoc_py['test_autodoc'] - assert 'Class' in undoc_py['test_autodoc']['classes'] - assert 'undocmeth' in undoc_py['test_autodoc']['classes']['Class'] + assert 'autodoc_target' in undoc_py + assert 'funcs' in undoc_py['autodoc_target'] + assert 'raises' in undoc_py['autodoc_target']['funcs'] + assert 'classes' in undoc_py['autodoc_target'] + assert 'Class' in undoc_py['autodoc_target']['classes'] + assert 'undocmeth' in undoc_py['autodoc_target']['classes']['Class'] diff --git a/tests/test_ext_doctest.py b/tests/test_ext_doctest.py index fa3ad6bc4..020357879 100644 --- a/tests/test_ext_doctest.py +++ b/tests/test_ext_doctest.py @@ -5,7 +5,7 @@ Test the doctest extension. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ import pytest diff --git a/tests/test_ext_githubpages.py b/tests/test_ext_githubpages.py index 56ce7b775..18ee51480 100644 --- a/tests/test_ext_githubpages.py +++ b/tests/test_ext_githubpages.py @@ -5,7 +5,7 @@ Test sphinx.ext.githubpages extension. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_ext_graphviz.py b/tests/test_ext_graphviz.py index 1d2a3ab2f..762add6f0 100644 --- a/tests/test_ext_graphviz.py +++ b/tests/test_ext_graphviz.py @@ -5,7 +5,7 @@ Test sphinx.ext.graphviz extension. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -40,6 +40,7 @@ def test_graphviz_png_html(app, status, warning): r'}\" />\n</div>') assert re.search(html, content, re.S) + @pytest.mark.sphinx('html', testroot='ext-graphviz', confoverrides={'graphviz_output_format': 'svg'}) @pytest.mark.usefixtures('if_graphviz_found') @@ -80,6 +81,7 @@ def test_graphviz_svg_html(app, status, warning): r'</div>') assert re.search(html, content, re.S) + @pytest.mark.sphinx('latex', testroot='ext-graphviz') @pytest.mark.usefixtures('if_graphviz_found') def test_graphviz_latex(app, status, warning): diff --git a/tests/test_ext_ifconfig.py b/tests/test_ext_ifconfig.py index 5c59caaaf..b4c941512 100644 --- a/tests/test_ext_ifconfig.py +++ b/tests/test_ext_ifconfig.py @@ -5,7 +5,7 @@ Test sphinx.ext.ifconfig extension. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_ext_imgconverter.py b/tests/test_ext_imgconverter.py index cc84001df..8f610377c 100644 --- a/tests/test_ext_imgconverter.py +++ b/tests/test_ext_imgconverter.py @@ -5,7 +5,7 @@ Test sphinx.ext.imgconverter extension. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_ext_inheritance_diagram.py b/tests/test_ext_inheritance_diagram.py index 40edfa937..deb04ce15 100644 --- a/tests/test_ext_inheritance_diagram.py +++ b/tests/test_ext_inheritance_diagram.py @@ -5,7 +5,7 @@ Test sphinx.ext.inheritance_diagram extension. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_ext_intersphinx.py b/tests/test_ext_intersphinx.py index 594aa81b8..19f8613c6 100644 --- a/tests/test_ext_intersphinx.py +++ b/tests/test_ext_intersphinx.py @@ -5,7 +5,7 @@ Test the intersphinx extension. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -194,7 +194,7 @@ def test_missing_reference_stddomain(tempdir, app, status, warning): inv_file = tempdir / 'inventory' inv_file.write_bytes(inventory_v2) app.config.intersphinx_mapping = { - 'https://docs.python.org/': inv_file, + 'cmd': ('https://docs.python.org/', inv_file), } app.config.intersphinx_cache_limit = 0 @@ -213,6 +213,12 @@ def test_missing_reference_stddomain(tempdir, app, status, warning): rn = missing_reference(app, app.env, node, contnode) assert rn.astext() == 'ls -l' + # refers inventory by name + kwargs = {} + node, contnode = fake_node('std', 'option', 'cmd:ls -l', '-l', **kwargs) + rn = missing_reference(app, app.env, node, contnode) + assert rn.astext() == '-l' + @pytest.mark.sphinx('html', testroot='ext-intersphinx-cppdomain') def test_missing_reference_cppdomain(tempdir, app, status, warning): @@ -240,7 +246,6 @@ def test_missing_reference_cppdomain(tempdir, app, status, warning): ' title="(in foo v2.0)">bartype</a>' in html) - def test_missing_reference_jsdomain(tempdir, app, status, warning): inv_file = tempdir / 'inventory' inv_file.write_bytes(inventory_v2) diff --git a/tests/test_ext_math.py b/tests/test_ext_math.py index 92501a3db..5bf4ebb15 100644 --- a/tests/test_ext_math.py +++ b/tests/test_ext_math.py @@ -5,15 +5,29 @@ Test math extensions. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ +import os import re +import subprocess import pytest +def has_binary(binary): + try: + subprocess.check_output([binary]) + except OSError as e: + if e.errno == os.errno.ENOENT: + # handle file not found error. + return False + else: + return True + return True + + @pytest.mark.sphinx( 'html', testroot='ext-math', confoverrides = {'extensions': ['sphinx.ext.jsmath'], 'jsmath_path': 'dummy.js'}) @@ -34,6 +48,8 @@ def test_jsmath(app, status, warning): assert '<div class="math">\na + 1 < b</div>' in content +@pytest.mark.skipif(not has_binary('dvipng'), + reason='Requires dvipng" binary') @pytest.mark.sphinx('html', testroot='ext-math-simple', confoverrides = {'extensions': ['sphinx.ext.imgmath']}) def test_imgmath_png(app, status, warning): @@ -49,6 +65,8 @@ def test_imgmath_png(app, status, warning): assert re.search(html, content, re.S) +@pytest.mark.skipif(not has_binary('dvisvgm'), + reason='Requires dvisvgm" binary') @pytest.mark.sphinx('html', testroot='ext-math-simple', confoverrides={'extensions': ['sphinx.ext.imgmath'], 'imgmath_image_format': 'svg'}) @@ -139,3 +157,52 @@ def test_math_eqref_format_latex(app, status, warning): content = (app.outdir / 'test.tex').text() macro = r'Referencing equation Eq.\\ref{equation:math:foo}.' assert re.search(macro, content, re.S) + + +@pytest.mark.sphinx('html', testroot='ext-math', + confoverrides={'extensions': ['sphinx.ext.mathjax'], + 'numfig': True, + 'math_numfig': True}) +def test_mathjax_numfig_html(app, status, warning): + app.builder.build_all() + + content = (app.outdir / 'math.html').text() + html = ('<div class="math" id="equation-math:0">\n' + '<span class="eqno">(1.2)') + assert html in content + html = ('<p>Referencing equation <a class="reference internal" ' + 'href="#equation-foo">(1.1)</a>.</p>') + assert html in content + + +@pytest.mark.sphinx('html', testroot='ext-math', + confoverrides={'extensions': ['sphinx.ext.jsmath'], + 'jsmath_path': 'dummy.js', + 'numfig': True, + 'math_numfig': True}) +def test_jsmath_numfig_html(app, status, warning): + app.builder.build_all() + + content = (app.outdir / 'math.html').text() + html = '<span class="eqno">(1.2)<a class="headerlink" href="#equation-math:0"' + assert html in content + html = ('<p>Referencing equation <a class="reference internal" ' + 'href="#equation-foo">(1.1)</a>.</p>') + assert html in content + + +@pytest.mark.sphinx('html', testroot='ext-math', + confoverrides={'extensions': ['sphinx.ext.imgmath'], + 'numfig': True, + 'numfig_secnum_depth': 0, + 'math_numfig': True}) +def test_imgmath_numfig_html(app, status, warning): + app.builder.build_all() + + content = (app.outdir / 'page.html').text() + html = '<span class="eqno">(3)<a class="headerlink" href="#equation-bar"' + assert html in content + html = ('<p>Referencing equations <a class="reference internal" ' + 'href="math.html#equation-foo">(1)</a> and ' + '<a class="reference internal" href="#equation-bar">(3)</a>.</p>') + assert html in content diff --git a/tests/test_ext_napoleon.py b/tests/test_ext_napoleon.py index b2ca7fe7a..d8d6adc65 100644 --- a/tests/test_ext_napoleon.py +++ b/tests/test_ext_napoleon.py @@ -6,7 +6,7 @@ Tests for :mod:`sphinx.ext.napoleon.__init__` module. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_ext_napoleon_docstring.py b/tests/test_ext_napoleon_docstring.py index e71d517fe..1865b004c 100644 --- a/tests/test_ext_napoleon_docstring.py +++ b/tests/test_ext_napoleon_docstring.py @@ -6,7 +6,7 @@ Tests for :mod:`sphinx.ext.napoleon.docstring` module. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_ext_napoleon_iterators.py b/tests/test_ext_napoleon_iterators.py index 5258d9b79..bf144275d 100644 --- a/tests/test_ext_napoleon_iterators.py +++ b/tests/test_ext_napoleon_iterators.py @@ -6,7 +6,7 @@ Tests for :mod:`sphinx.ext.napoleon.iterators` module. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_ext_todo.py b/tests/test_ext_todo.py index 4f01a07ab..0260b821d 100644 --- a/tests/test_ext_todo.py +++ b/tests/test_ext_todo.py @@ -5,7 +5,7 @@ Test sphinx.ext.todo extension. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -85,8 +85,9 @@ def test_todo_not_included(app, status, warning): assert len(todos) == 2 assert set(todo[1].astext() for todo in todos) == set(['todo in foo', 'todo in bar']) + @pytest.mark.sphinx('latex', testroot='ext-todo', freshenv=True, - confoverrides={'todo_include_todos': True, 'todo_emit_warnings': True}) + confoverrides={'todo_include_todos': True}) def test_todo_valid_link(app, status, warning): """ Test that the inserted "original entry" links for todo items have a target @@ -99,16 +100,17 @@ def test_todo_valid_link(app, status, warning): content = (app.outdir / 'TodoTests.tex').text() - # Look for the link to foo. We could equally well look for the link to bar. + # Look for the link to foo. Note that there are two of them because the + # source document uses todolist twice. We could equally well look for links + # to bar. link = r'\{\\hyperref\[\\detokenize\{(.*?foo.*?)}]\{\\sphinxcrossref{' \ r'\\sphinxstyleemphasis{original entry}}}}' m = re.findall(link, content) - assert len(m) == 1 + assert len(m) == 2 target = m[0] # Look for the targets of this link. - labels = [m for m in re.findall(r'\\label\{([^}]*)}', content) - if m == target] + labels = [m for m in re.findall(r'\\label\{([^}]*)}', content) if m == target] # If everything is correct we should have exactly one target. assert len(labels) == 1 diff --git a/tests/test_ext_viewcode.py b/tests/test_ext_viewcode.py index 4dceaa488..3f6612c76 100644 --- a/tests/test_ext_viewcode.py +++ b/tests/test_ext_viewcode.py @@ -5,7 +5,7 @@ Test sphinx.ext.viewcode extension. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_highlighting.py b/tests/test_highlighting.py index 938181fe1..5660869bd 100644 --- a/tests/test_highlighting.py +++ b/tests/test_highlighting.py @@ -5,7 +5,7 @@ Test the Pygments highlighting bridge. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_intl.py b/tests/test_intl.py index 6b72438bd..cb13b00f3 100644 --- a/tests/test_intl.py +++ b/tests/test_intl.py @@ -6,7 +6,7 @@ Test message patching for internationalization purposes. Runs the text builder in the test root. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ from __future__ import print_function @@ -222,6 +222,7 @@ def test_text_inconsistency_warnings(app, warning): u'.*/refs_inconsistency.txt:\\d+: WARNING: citation not found: ref3') assert_re_search(expected_citation_warning_expr, warnings) + @sphinx_intl @pytest.mark.sphinx('text') @pytest.mark.test_params(shared_result='test_intl_basic') diff --git a/tests/test_io.py b/tests/test_io.py index ecd4a1009..1c8fee86b 100644 --- a/tests/test_io.py +++ b/tests/test_io.py @@ -5,7 +5,7 @@ Tests io modules. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_markup.py b/tests/test_markup.py index 9c41845fc..c48096e34 100644 --- a/tests/test_markup.py +++ b/tests/test_markup.py @@ -5,7 +5,7 @@ Test various Sphinx-specific markup extensions. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -135,7 +135,7 @@ def get_verifier(verify, verify_re): '``code sample``', ('<p><code class="(samp )?docutils literal"><span class="pre">' 'code</span>   <span class="pre">sample</span></code></p>'), - r'\\sphinxcode{code sample}', + r'\\sphinxcode{\\sphinxupquote{code sample}}', ), ( # correct interpretation of code with whitespace @@ -143,7 +143,7 @@ def get_verifier(verify, verify_re): ':samp:`code sample`', ('<p><code class="(samp )?docutils literal"><span class="pre">' 'code</span>   <span class="pre">sample</span></code></p>'), - r'\\sphinxcode{code sample}', + r'\\sphinxcode{\\sphinxupquote{code sample}}', ), ( # interpolation of braces in samp and file roles (HTML only) @@ -152,7 +152,7 @@ def get_verifier(verify, verify_re): ('<p><code class="samp docutils literal"><span class="pre">a</span>' '<em><span class="pre">b</span></em>' '<span class="pre">c</span></code></p>'), - '\\sphinxcode{a\\sphinxstyleemphasis{b}c}', + '\\sphinxcode{\\sphinxupquote{a\\sphinxstyleemphasis{b}c}}', ), ( # interpolation of arrows in menuselection @@ -175,7 +175,7 @@ def get_verifier(verify, verify_re): ':option:`--with-option`', ('<p><code( class="xref std std-option docutils literal")?>' '<span class="pre">--with-option</span></code></p>$'), - r'\\sphinxcode{-{-}with-option}$', + r'\\sphinxcode{\\sphinxupquote{-{-}with-option}}$', ), ( # verify smarty-pants quotes @@ -190,14 +190,14 @@ def get_verifier(verify, verify_re): '``"John"``', ('<p><code class="docutils literal"><span class="pre">' '"John"</span></code></p>'), - '\\sphinxcode{"John"}', + '\\sphinxcode{\\sphinxupquote{"John"}}', ), ( # verify classes for inline roles 'verify', ':manpage:`mp(1)`', '<p><em class="manpage">mp(1)</em></p>', - '\\sphinxstyleliteralemphasis{mp(1)}', + '\\sphinxstyleliteralemphasis{\\sphinxupquote{mp(1)}}', ), ( # correct escaping in normal mode diff --git a/tests/test_metadata.py b/tests/test_metadata.py index 58f573b0a..a00d76f87 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -5,7 +5,7 @@ Test our handling of metadata in files with bibliographic metadata. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_pycode.py b/tests/test_pycode.py index 2b5ae1514..400c47dc5 100644 --- a/tests/test_pycode.py +++ b/tests/test_pycode.py @@ -41,7 +41,8 @@ def test_ModuleAnalyzer_for_file(): def test_ModuleAnalyzer_for_module(): analyzer = ModuleAnalyzer.for_module('sphinx') assert analyzer.modname == 'sphinx' - assert analyzer.srcname == SPHINX_MODULE_PATH + assert analyzer.srcname in (SPHINX_MODULE_PATH, + os.path.abspath(SPHINX_MODULE_PATH)) assert analyzer.encoding == 'utf-8' diff --git a/tests/test_quickstart.py b/tests/test_quickstart.py index f69a0a58e..b1b0fc535 100644 --- a/tests/test_quickstart.py +++ b/tests/test_quickstart.py @@ -5,7 +5,7 @@ Test the sphinx.quickstart module. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -96,7 +96,6 @@ def test_do_prompt_inputstrip(): def test_do_prompt_with_nonascii(): - d = {} answers = { 'Q1': u'\u30c9\u30a4\u30c4', } diff --git a/tests/test_search.py b/tests/test_search.py index f1825dfa4..fc5fb7e04 100644 --- a/tests/test_search.py +++ b/tests/test_search.py @@ -5,7 +5,7 @@ Test the search index builder. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_setup_command.py b/tests/test_setup_command.py index 562b0a715..e1f976b8a 100644 --- a/tests/test_setup_command.py +++ b/tests/test_setup_command.py @@ -5,7 +5,7 @@ Test setup_command for distutils. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_templating.py b/tests/test_templating.py index b0070f06a..550b3bc7d 100644 --- a/tests/test_templating.py +++ b/tests/test_templating.py @@ -5,15 +5,19 @@ Test templating. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ import pytest +from sphinx.ext.autosummary.generate import setup_documenters @pytest.mark.sphinx('html', testroot='templating') -def test_layout_overloading(app, status, warning): +def test_layout_overloading(make_app, app_params): + args, kwargs = app_params + app = make_app(*args, **kwargs) + setup_documenters(app) app.builder.build_update() result = (app.outdir / 'contents.html').text(encoding='utf-8') @@ -22,7 +26,10 @@ def test_layout_overloading(app, status, warning): @pytest.mark.sphinx('html', testroot='templating') -def test_autosummary_class_template_overloading(app, status, warning): +def test_autosummary_class_template_overloading(make_app, app_params): + args, kwargs = app_params + app = make_app(*args, **kwargs) + setup_documenters(app) app.builder.build_update() result = (app.outdir / 'generated' / 'sphinx.application.TemplateBridge.html').text( diff --git a/tests/test_theming.py b/tests/test_theming.py index 0977e1274..dfe583918 100644 --- a/tests/test_theming.py +++ b/tests/test_theming.py @@ -5,7 +5,7 @@ Test the Theme class. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_toctree.py b/tests/test_toctree.py index 18910197f..42ec0ce89 100644 --- a/tests/test_toctree.py +++ b/tests/test_toctree.py @@ -5,7 +5,7 @@ Test the HTML builder and check output against XPath. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ import pytest diff --git a/tests/test_util.py b/tests/test_util.py index aae54eaf0..189e221b2 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -5,7 +5,7 @@ Tests util functions. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -95,7 +95,6 @@ def test_parselinenos(): parselinenos('3-1', 10) - def test_xmlname_check(): checker = xmlname_checker() assert checker.match('id-pub') diff --git a/tests/test_util_fileutil.py b/tests/test_util_fileutil.py index 849ccce22..69f51f52c 100644 --- a/tests/test_util_fileutil.py +++ b/tests/test_util_fileutil.py @@ -5,7 +5,7 @@ Tests sphinx.util.fileutil functions. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ from sphinx.util.fileutil import copy_asset, copy_asset_file diff --git a/tests/test_util_i18n.py b/tests/test_util_i18n.py index 53e0e4cf1..bec4e91e9 100644 --- a/tests/test_util_i18n.py +++ b/tests/test_util_i18n.py @@ -5,7 +5,7 @@ Test i18n util. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ from __future__ import print_function diff --git a/tests/test_util_images.py b/tests/test_util_images.py index 6f67dcc82..624690831 100644 --- a/tests/test_util_images.py +++ b/tests/test_util_images.py @@ -5,7 +5,7 @@ Test images util. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ from __future__ import print_function @@ -44,22 +44,22 @@ def test_guess_mimetype(testroot): assert guess_mimetype('IMG.PNG') == 'image/png' # guess by content - assert guess_mimetype(content=(testroot/GIF_FILENAME).bytes()) == 'image/gif' - assert guess_mimetype(content=(testroot/PNG_FILENAME).bytes()) == 'image/png' - assert guess_mimetype(content=(testroot/PDF_FILENAME).bytes()) is None - assert guess_mimetype(content=(testroot/TXT_FILENAME).bytes()) is None - assert guess_mimetype(content=(testroot/TXT_FILENAME).bytes(), + assert guess_mimetype(content=(testroot / GIF_FILENAME).bytes()) == 'image/gif' + assert guess_mimetype(content=(testroot / PNG_FILENAME).bytes()) == 'image/png' + assert guess_mimetype(content=(testroot / PDF_FILENAME).bytes()) is None + assert guess_mimetype(content=(testroot / TXT_FILENAME).bytes()) is None + assert guess_mimetype(content=(testroot / TXT_FILENAME).bytes(), default='text/plain') == 'text/plain' # the priority of params: filename > content > default assert guess_mimetype('img.png', - content=(testroot/GIF_FILENAME).bytes(), + content=(testroot / GIF_FILENAME).bytes(), default='text/plain') == 'image/png' assert guess_mimetype('no_extension', - content=(testroot/GIF_FILENAME).bytes(), + content=(testroot / GIF_FILENAME).bytes(), default='text/plain') == 'image/gif' assert guess_mimetype('no_extension', - content=(testroot/TXT_FILENAME).bytes(), + content=(testroot / TXT_FILENAME).bytes(), default='text/plain') == 'text/plain' diff --git a/tests/test_util_inspect.py b/tests/test_util_inspect.py index 63e04ee76..f0188cafa 100644 --- a/tests/test_util_inspect.py +++ b/tests/test_util_inspect.py @@ -5,7 +5,7 @@ Tests util.inspect functions. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ import sys @@ -113,7 +113,6 @@ def test_getargspec_bound_methods(): assert expected_bound == inspect.getargspec(wrapped_bound_method) - def test_Signature(): # literals with pytest.raises(TypeError): diff --git a/tests/test_util_logging.py b/tests/test_util_logging.py index 7ae086872..48eed82b0 100644 --- a/tests/test_util_logging.py +++ b/tests/test_util_logging.py @@ -5,7 +5,7 @@ Test logging util. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ from __future__ import print_function @@ -183,7 +183,7 @@ def test_warning_location(app, status, warning): assert 'index.txt:10: WARNING: message2' in warning.getvalue() logger.warning('message3', location=None) - assert colorize('darkred', 'WARNING: message3') in warning.getvalue() + assert colorize('red', 'WARNING: message3') in warning.getvalue() node = nodes.Node() node.source, node.line = ('index.txt', 10) @@ -200,7 +200,7 @@ def test_warning_location(app, status, warning): node.source, node.line = (None, None) logger.warning('message7', location=node) - assert colorize('darkred', 'WARNING: message7') in warning.getvalue() + assert colorize('red', 'WARNING: message7') in warning.getvalue() def test_pending_warnings(app, status, warning): @@ -236,7 +236,7 @@ def test_colored_logs(app, status, warning): assert colorize('darkgray', 'message1') in status.getvalue() assert 'message2\n' in status.getvalue() # not colored assert 'message3\n' in status.getvalue() # not colored - assert colorize('darkred', 'WARNING: message4') in warning.getvalue() + assert colorize('red', 'WARNING: message4') in warning.getvalue() assert 'WARNING: message5\n' in warning.getvalue() # not colored assert colorize('darkred', 'WARNING: message6') in warning.getvalue() diff --git a/tests/test_util_matching.py b/tests/test_util_matching.py index 3b84f4735..fc38470d3 100644 --- a/tests/test_util_matching.py +++ b/tests/test_util_matching.py @@ -5,7 +5,7 @@ Tests sphinx.util.matching functions. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ from sphinx.util.matching import compile_matchers, Matcher diff --git a/tests/test_util_nodes.py b/tests/test_util_nodes.py index c392c2bc7..c58ecc205 100644 --- a/tests/test_util_nodes.py +++ b/tests/test_util_nodes.py @@ -5,7 +5,7 @@ Tests uti.nodes functions. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ from textwrap import dedent diff --git a/tests/test_util_rst.py b/tests/test_util_rst.py index 5fce6e3eb..406ea710e 100644 --- a/tests/test_util_rst.py +++ b/tests/test_util_rst.py @@ -5,7 +5,7 @@ Tests sphinx.util.rst functions. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ from sphinx.util.rst import escape diff --git a/tests/test_versioning.py b/tests/test_versioning.py index b73c00fa6..e17d250e5 100644 --- a/tests/test_versioning.py +++ b/tests/test_versioning.py @@ -5,7 +5,7 @@ Test the versioning implementation. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -28,7 +28,7 @@ def setup_module(rootdir, sphinx_test_tempdir): global app, original, original_uids srcdir = sphinx_test_tempdir / 'test-versioning' if not srcdir.exists(): - (rootdir/'test-versioning').copytree(srcdir) + (rootdir / 'test-versioning').copytree(srcdir) app = SphinxTestApp(srcdir=srcdir) app.builder.env.app = app app.connect('doctree-resolved', on_doctree_resolved) diff --git a/tests/test_websupport.py b/tests/test_websupport.py index 51cb2b287..10942798c 100644 --- a/tests/test_websupport.py +++ b/tests/test_websupport.py @@ -5,7 +5,7 @@ Test the Web Support Package - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_writer_latex.py b/tests/test_writer_latex.py index b026f8d17..5c73469ec 100644 --- a/tests/test_writer_latex.py +++ b/tests/test_writer_latex.py @@ -5,7 +5,7 @@ Test the LaTeX writer - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ from __future__ import print_function |