Merge pull request #3718 from sphinx-doc/3458-sphinx-testing

refs #3458 sphinx.testing
This commit is contained in:
Takeshi KOMIYA 2017-05-16 15:06:02 +09:00 committed by GitHub
commit 384839f37c
97 changed files with 535 additions and 452 deletions

View File

@ -34,6 +34,8 @@ Bugs fixed
Testing
--------
* #3458: Add ``sphinx.testing` (experimental)
Release 1.6 beta3 (released May 07, 2017)
=========================================

View File

@ -337,3 +337,28 @@ warnings with:
* ``PYTHONWARNINGS= make html`` (Linux/Mac)
* ``export PYTHONWARNINGS=`` and do ``make html`` (Linux/Mac)
* ``set PYTHONWARNINGS=`` and do ``make html`` (Windows)
Unit Testing
------------
Sphinx has been tested with pytest runner. Sphinx developers write unit tests
using pytest notation. Utility functions and pytest fixtures for testing are
provided in ``sphinx.testing``. If you are a developer of Sphinx extensions,
you can write unit tests with using pytest. At this time, ``sphinx.testing``
will help your test implementation.
How to use pytest fixtures that are provided by ``sphinx.teting``?
You can require ``'sphinx.testing.fixtures'`` in your test modules or
``conftest.py`` files like this::
pytest_plugins = 'sphinx.testing.fixtures'
If you want to know more detailed usage, please refer to ``tests/conftest.py``
and other ``test_*.py`` files under ``tests`` directory.
.. note::
Prior to Sphinx - 1.5.2, Sphinx was running the test with nose.
.. versionadded:: 1.6
``sphinx.testing`` as a experimental.

View File

@ -0,0 +1,15 @@
# -*- coding: utf-8 -*-
"""
sphinx.testing
~~~~~~~~~~~~~~
Sphinx test utilities
You can require sphinx.testing pytest fixtures in a test module or a conftest
file like this:
pytest_plugins = 'sphinx.testing.fixtures'
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

231
sphinx/testing/fixtures.py Normal file
View File

@ -0,0 +1,231 @@
# -*- coding: utf-8 -*-
"""
sphinx.testing.fixtures
~~~~~~~~~~~~~~~~~~~~~~~
Sphinx test fixtures for pytest
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from __future__ import print_function
import os
import subprocess
import sys
from collections import namedtuple
from tempfile import gettempdir
import pytest
from six import StringIO, string_types
from . import util
if False:
from typing import Dict, Union # NOQA
@pytest.fixture(scope='session')
def rootdir():
return None
@pytest.fixture
def app_params(request, test_params, shared_result, sphinx_test_tempdir, rootdir):
"""
parameters that is specified by 'pytest.mark.sphinx' for
sphinx.application.Sphinx initialization
"""
# ##### process pytest.mark.sphinx
markers = request.node.get_marker("sphinx")
pargs = {}
kwargs = {} # type: Dict[str, str]
if markers is not None:
# to avoid stacking positional args
for info in reversed(list(markers)):
for i, a in enumerate(info.args):
pargs[i] = a
kwargs.update(info.kwargs)
args = [pargs[i] for i in sorted(pargs.keys())]
# ##### process pytest.mark.test_params
if test_params['shared_result']:
if 'srcdir' in kwargs:
raise pytest.Exception('You can not spcify shared_result and '
'srcdir in same time.')
kwargs['srcdir'] = test_params['shared_result']
restore = shared_result.restore(test_params['shared_result'])
kwargs.update(restore)
# ##### prepare Application params
testroot = kwargs.pop('testroot', 'root')
kwargs['srcdir'] = srcdir = sphinx_test_tempdir / kwargs.get('srcdir', testroot)
# special support for sphinx/tests
if rootdir and not srcdir.exists():
testroot_path = rootdir / ('test-' + testroot)
testroot_path.copytree(srcdir)
return namedtuple('app_params', 'args,kwargs')(args, kwargs) # type: ignore
@pytest.fixture
def test_params(request):
"""
test parameters that is specified by 'pytest.mark.test_params'
:param Union[str] shared_result:
If the value is provided, app._status and app._warning objects will be
shared in the parametrized test functions and/or test functions that
have same 'shared_result' value.
**NOTE**: You can not specify shared_result and srcdir in same time.
"""
env = request.node.get_marker('test_params')
kwargs = env.kwargs if env else {}
result = {
'shared_result': None,
}
result.update(kwargs)
if (result['shared_result'] and
not isinstance(result['shared_result'], string_types)):
raise pytest.Exception('You can only provide a string type of value '
'for "shared_result" ')
return result
@pytest.fixture(scope='function')
def app(test_params, app_params, make_app, shared_result):
"""
provides sphinx.application.Sphinx object
"""
args, kwargs = app_params
app_ = make_app(*args, **kwargs)
yield app_
print('# testroot:', kwargs.get('testroot', 'root'))
print('# builder:', app_.builder.name)
print('# srcdir:', app_.srcdir)
print('# outdir:', app_.outdir)
print('# status:', '\n' + app_._status.getvalue())
print('# warning:', '\n' + app_._warning.getvalue())
if test_params['shared_result']:
shared_result.store(test_params['shared_result'], app_)
@pytest.fixture(scope='function')
def status(app):
"""
compat for testing with previous @with_app decorator
"""
return app._status
@pytest.fixture(scope='function')
def warning(app):
"""
compat for testing with previous @with_app decorator
"""
return app._warning
@pytest.fixture()
def make_app(test_params):
"""
provides make_app function to initialize SphinxTestApp instance.
if you want to initialize 'app' in your test function. please use this
instead of using SphinxTestApp class directory.
"""
apps = []
syspath = sys.path[:]
def make(*args, **kwargs):
status, warning = StringIO(), StringIO()
kwargs.setdefault('status', status)
kwargs.setdefault('warning', warning)
app_ = util.SphinxTestApp(*args, **kwargs) # type: Union[util.SphinxTestApp, util.SphinxTestAppWrapperForSkipBuilding] # NOQA
apps.append(app_)
if test_params['shared_result']:
app_ = util.SphinxTestAppWrapperForSkipBuilding(app_)
return app_
yield make
sys.path[:] = syspath
for app_ in apps:
app_.cleanup()
class SharedResult(object):
cache = {} # type: Dict[str, Dict[str, str]]
def store(self, key, app_):
if key in self.cache:
return
data = {
'status': app_._status.getvalue(),
'warning': app_._warning.getvalue(),
}
self.cache[key] = data
def restore(self, key):
if key not in self.cache:
return {}
data = self.cache[key]
return {
'status': StringIO(data['status']),
'warning': StringIO(data['warning']),
}
@pytest.fixture
def shared_result():
return SharedResult()
@pytest.fixture(scope='module', autouse=True)
def _shared_result_cache():
SharedResult.cache.clear()
@pytest.fixture
def if_graphviz_found(app):
"""
The test will be skipped when using 'if_graphviz_found' fixture and graphviz
dot command is not found.
"""
graphviz_dot = getattr(app.config, 'graphviz_dot', '')
try:
if graphviz_dot:
dot = subprocess.Popen([graphviz_dot, '-V'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE) # show version
dot.communicate()
return
except OSError: # No such file or directory
pass
pytest.skip('graphviz "dot" is not available')
@pytest.fixture(scope='session')
def sphinx_test_tempdir():
"""
temporary directory that wrapped with `path` class.
"""
return util.path(os.environ.get('SPHINX_TEST_TEMPDIR', gettempdir())).abspath()
@pytest.fixture
def tempdir(tmpdir):
"""
temporary directory that wrapped with `path` class.
this fixture is for compat with old test implementation.
"""
return util.path(tmpdir)

9
tests/path.py → sphinx/testing/path.py Executable file → Normal file
View File

@ -1,8 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
path
~~~~
sphinx.testing.path
~~~~~~~~~~~~~~~~~~~
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
@ -26,8 +25,8 @@ class path(text_type):
def __new__(cls, s, encoding=FILESYSTEMENCODING, errors='strict'):
if isinstance(s, str):
s = s.decode(encoding, errors)
return text_type.__new__(cls, s)
return text_type.__new__(cls, s)
return text_type.__new__(cls, s) # type: ignore
return text_type.__new__(cls, s) # type: ignore
@property
def parent(self):

View File

@ -1,12 +1,13 @@
# -*- coding: utf-8 -*-
"""
sphinx.testing.util
~~~~~~~~~~~~~~~~~~~
Sphinx test suite utilities
~~~~~~~~~~~~~~~~~~~~~~~~~~~
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import os
import re
import sys
@ -28,22 +29,19 @@ from sphinx.ext.autodoc import AutoDirective
from sphinx.pycode import ModuleAnalyzer
from sphinx.deprecation import RemovedInSphinx17Warning
from path import path
from sphinx.testing.path import path
if False:
from typing import List # NOQA
__all__ = [
'rootdir', 'tempdir',
'skip_unless_importable', 'Struct',
'SphinxTestApp',
'path',
'Struct',
'SphinxTestApp', 'SphinxTestAppWrapperForSkipBuilding',
'remove_unicode_literals',
]
rootdir = path(os.path.dirname(__file__) or '.').abspath()
tempdir = path(os.environ['SPHINX_TEST_TEMPDIR']).abspath()
def assert_re_search(regex, text, flags=0):
if not re.search(regex, text, flags):
assert False, '%r did not match %r' % (regex, text)
@ -88,16 +86,6 @@ def assert_node(node, cls=None, xpath="", **kwargs):
'The node%s[%s] is not %r: %r' % (xpath, key, value, node[key])
def skip_unless_importable(module, msg=None):
"""Decorator to skip test if module is not importable."""
try:
__import__(module)
except ImportError:
return pytest.mark.skipif(True, reason=(msg or 'conditional skip'))
else:
return pytest.mark.skipif(False, reason=(msg or 'conditional skip'))
def etree_parse(path):
with warnings.catch_warnings(record=False):
warnings.filterwarnings("ignore", category=DeprecationWarning)
@ -115,22 +103,9 @@ class SphinxTestApp(application.Sphinx):
better default values for the initialization parameters.
"""
def __init__(self, buildername='html', testroot=None, srcdir=None,
def __init__(self, buildername='html', srcdir=None,
freshenv=False, confoverrides=None, status=None, warning=None,
tags=None, docutilsconf=None):
if testroot is None:
defaultsrcdir = 'root'
testroot = rootdir / 'root'
else:
defaultsrcdir = 'test-' + testroot
testroot = rootdir / 'roots' / ('test-' + testroot)
if srcdir is None:
srcdir = tempdir / defaultsrcdir
else:
srcdir = tempdir / srcdir
if not srcdir.exists():
testroot.copytree(srcdir)
if docutilsconf is not None:
(srcdir / 'docutils.conf').write_text(docutilsconf)
@ -184,6 +159,26 @@ class SphinxTestApp(application.Sphinx):
return '<%s buildername=%r>' % (self.__class__.__name__, self.builder.name)
class SphinxTestAppWrapperForSkipBuilding(object):
"""
This class is a wrapper for SphinxTestApp to speed up the test by skipping
`app.build` process if it is already built and there is even one output
file.
"""
def __init__(self, app_):
self.app = app_
def __getattr__(self, name):
return getattr(self.app, name)
def build(self, *args, **kw):
if not self.app.outdir.listdir():
# if listdir is empty, do build.
self.app.build(*args, **kw)
# otherwise, we can use built cache
_unicode_literals_re = re.compile(r'u(".*?")|u(\'.*?\')')
@ -313,7 +308,7 @@ class ListOutput(object):
"""
def __init__(self, name):
self.name = name
self.content = []
self.content = [] # type: List[str]
def reset(self):
del self.content[:]

View File

@ -1,230 +1,20 @@
# -*- coding: utf-8 -*-
from __future__ import print_function
"""
pytest config for sphinx/tests
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import sys
import subprocess
from collections import namedtuple
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import os
import pytest
from six import StringIO, string_types
from sphinx.testing.path import path
import util
pytest_plugins = 'sphinx.testing.fixtures'
@pytest.fixture
def app_params(request, test_params, shared_result):
"""
parameters that is specified by 'pytest.mark.sphinx' for
sphinx.application.Sphinx initialization
"""
# ##### process pytest.mark.sphinx
markers = request.node.get_marker("sphinx")
pargs = {}
kwargs = {}
if markers is not None:
# to avoid stacking positional args
for info in reversed(list(markers)):
for i, a in enumerate(info.args):
pargs[i] = a
kwargs.update(info.kwargs)
args = [pargs[i] for i in sorted(pargs.keys())]
# ##### process pytest.mark.test_params
if test_params['shared_result']:
if 'srcdir' in kwargs:
raise pytest.Exception('You can not spcify shared_result and '
'srcdir in same time.')
kwargs['srcdir'] = test_params['shared_result']
restore = shared_result.restore(test_params['shared_result'])
kwargs.update(restore)
# ##### prepare Application params
if 'srcdir' in kwargs:
srcdir = util.tempdir / kwargs['srcdir']
else:
srcdir = util.tempdir / kwargs.get('testroot', 'root')
kwargs['srcdir'] = srcdir
if kwargs.get('testroot') is None:
testroot_path = util.rootdir / 'root'
else:
testroot_path = util.rootdir / 'roots' / ('test-' + kwargs['testroot'])
if not srcdir.exists():
testroot_path.copytree(srcdir)
return namedtuple('app_params', 'args,kwargs')(args, kwargs)
@pytest.fixture
def test_params(request):
"""
test parameters that is specified by 'pytest.mark.test_params'
:param Union[str] shared_result:
If the value is provided, app._status and app._warning objects will be
shared in the parametrized test functions and/or test functions that
have same 'shared_result' value.
**NOTE**: You can not specify shared_result and srcdir in same time.
"""
env = request.node.get_marker('test_params')
kwargs = env.kwargs if env else {}
result = {
'shared_result': None,
}
result.update(kwargs)
if (result['shared_result'] and
not isinstance(result['shared_result'], string_types)):
raise pytest.Exception('You can only provide a string type of value '
'for "shared_result" ')
return result
class SphinxTestAppWrapperForSkipBuilding(object):
"""
This class is a wrapper for SphinxTestApp to speed up the test by skipping
`app.build` process if it is already built and there is even one output
file.
"""
def __init__(self, app_):
self.app = app_
def __getattr__(self, name):
return getattr(self.app, name)
def build(self, *args, **kw):
if not self.app.outdir.listdir():
# if listdir is empty, do build.
self.app.build(*args, **kw)
# otherwise, we can use built cache
@pytest.fixture(scope='function')
def app(test_params, app_params, make_app, shared_result):
"""
provides sphinx.application.Sphinx object
"""
args, kwargs = app_params
app_ = make_app(*args, **kwargs)
yield app_
print('# testroot:', kwargs.get('testroot', 'root'))
print('# builder:', app_.builder.name)
print('# srcdir:', app_.srcdir)
print('# outdir:', app_.outdir)
print('# status:', '\n' + app_._status.getvalue())
print('# warning:', '\n' + app_._warning.getvalue())
if test_params['shared_result']:
shared_result.store(test_params['shared_result'], app_)
@pytest.fixture(scope='function')
def status(app):
"""
compat for testing with previous @with_app decorator
"""
return app._status
@pytest.fixture(scope='function')
def warning(app):
"""
compat for testing with previous @with_app decorator
"""
return app._warning
@pytest.fixture()
def make_app(test_params):
"""
provides make_app function to initialize SphinxTestApp instance.
if you want to initialize 'app' in your test function. please use this
instead of using SphinxTestApp class directory.
"""
apps = []
syspath = sys.path[:]
def make(*args, **kwargs):
status, warning = StringIO(), StringIO()
kwargs.setdefault('status', status)
kwargs.setdefault('warning', warning)
app_ = util.SphinxTestApp(*args, **kwargs)
apps.append(app_)
if test_params['shared_result']:
app_ = SphinxTestAppWrapperForSkipBuilding(app_)
return app_
yield make
sys.path[:] = syspath
for app_ in apps:
app_.cleanup()
class SharedResult(object):
cache = {}
def store(self, key, app_):
if key in self.cache:
return
data = {
'status': app_._status.getvalue(),
'warning': app_._warning.getvalue(),
}
self.cache[key] = data
def restore(self, key):
if key not in self.cache:
return {}
data = self.cache[key]
return {
'status': StringIO(data['status']),
'warning': StringIO(data['warning']),
}
@pytest.fixture
def shared_result():
return SharedResult()
@pytest.fixture(scope='module', autouse=True)
def _shared_result_cache():
SharedResult.cache.clear()
@pytest.fixture
def if_graphviz_found(app):
"""
The test will be skipped when using 'if_graphviz_found' fixture and graphviz
dot command is not found.
"""
graphviz_dot = getattr(app.config, 'graphviz_dot', '')
try:
if graphviz_dot:
dot = subprocess.Popen([graphviz_dot, '-V'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE) # show version
dot.communicate()
return
except OSError: # No such file or directory
pass
pytest.skip('graphviz "dot" is not available')
@pytest.fixture
def tempdir(tmpdir):
"""
temporary directory that wrapped with `path` class.
this fixture is for compat with old test implementation.
"""
return util.path(tmpdir)
@pytest.fixture(scope='session')
def rootdir():
return path(os.path.dirname(__file__) or '.').abspath() / 'roots'

View File

@ -13,7 +13,7 @@
# "raises" imported for usage by autodoc
import six
import sys
from util import SphinxTestApp, Struct
from sphinx.testing.util import SphinxTestApp, Struct
import pytest
from six import StringIO
@ -25,17 +25,19 @@ from sphinx.ext.autodoc import AutoDirective, add_documenter, \
app = None
def setup_module():
@pytest.fixture(scope='module', autouse=True)
def setup_module(rootdir, sphinx_test_tempdir):
global app
app = SphinxTestApp()
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)
def teardown_module():
yield
app.cleanup()

View File

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 65 KiB

View File

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 65 KiB

View File

Before

Width:  |  Height:  |  Size: 120 B

After

Width:  |  Height:  |  Size: 120 B

View File

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 65 KiB

View File

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 65 KiB

View File

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

Before

Width:  |  Height:  |  Size: 120 B

After

Width:  |  Height:  |  Size: 120 B

View File

@ -15,8 +15,7 @@ import os
import sys
import warnings
import traceback
from path import path
import shutil
testroot = os.path.dirname(__file__) or '.'
sys.path.insert(0, os.path.abspath(os.path.join(testroot, os.path.pardir)))
@ -46,19 +45,20 @@ 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 = path(os.environ['SPHINX_TEST_TEMPDIR'])
tempdir = os.environ['SPHINX_TEST_TEMPDIR']
print('Temporary files will be placed in %s.' % tempdir)
if tempdir.exists():
tempdir.rmtree()
tempdir.makedirs()
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 'root' and 'roots' dirs for pytest test collector
# 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 ('root', 'roots')
for sub in ('roots',)
]
args = sys.argv[1:]
for ignore_path in ignore_paths:

View File

@ -12,15 +12,14 @@
import sys
import pytest
from util import rootdir
def setup_module():
sys.path.insert(0, rootdir / 'roots' / 'test-api-set-translator')
def teardown_module():
sys.path.remove(rootdir / 'roots' / 'test-api-set-translator')
@pytest.fixture(scope='module', autouse=True)
def setup_module(rootdir):
p = rootdir / 'test-api-set-translator'
sys.path.insert(0, p)
yield
sys.path.remove(p)
@pytest.mark.sphinx('html')

View File

@ -17,13 +17,13 @@ import pytest
from sphinx.apidoc import main as apidoc_main
from util import rootdir, remove_unicode_literals
from sphinx.testing.util import remove_unicode_literals
@pytest.fixture()
def apidoc(tempdir, apidoc_params):
def apidoc(rootdir, tempdir, apidoc_params):
_, kwargs = apidoc_params
coderoot = kwargs.get('coderoot', (rootdir / 'root'))
coderoot = rootdir / kwargs.get('coderoot', 'test-root')
outdir = tempdir / 'out'
args = ['sphinx-apidoc', '-o', outdir, '-F', coderoot] + kwargs.get('options', [])
apidoc_main(args)
@ -46,7 +46,7 @@ def apidoc_params(request):
return args, kwargs
@pytest.mark.apidoc(coderoot=(rootdir / 'root'))
@pytest.mark.apidoc(coderoot='test-root')
def test_simple(make_app, apidoc):
outdir = apidoc.outdir
assert (outdir / 'conf.py').isfile()
@ -60,7 +60,7 @@ def test_simple(make_app, apidoc):
@pytest.mark.apidoc(
coderoot=(rootdir / 'roots' / 'test-apidoc-pep420'),
coderoot='test-apidoc-pep420',
options=["--implicit-namespaces"],
)
def test_pep_0420_enabled(make_app, apidoc):
@ -97,7 +97,7 @@ def test_pep_0420_enabled(make_app, apidoc):
assert "a.b.x namespace\n" in txt
@pytest.mark.apidoc(coderoot=(rootdir / 'roots' / 'test-apidoc-pep420'))
@pytest.mark.apidoc(coderoot='test-apidoc-pep420')
def test_pep_0420_disabled(make_app, apidoc):
outdir = apidoc.outdir
assert (outdir / 'conf.py').isfile()
@ -111,7 +111,7 @@ def test_pep_0420_disabled(make_app, apidoc):
@pytest.mark.apidoc(
coderoot=(rootdir / 'roots' / 'test-apidoc-pep420' / 'a' / 'b'))
coderoot='test-apidoc-pep420/a/b')
def test_pep_0420_disabled_top_level_verify(make_app, apidoc):
outdir = apidoc.outdir
assert (outdir / 'conf.py').isfile()
@ -131,7 +131,7 @@ def test_pep_0420_disabled_top_level_verify(make_app, apidoc):
@pytest.mark.apidoc(
coderoot=(rootdir / 'roots' / 'test-apidoc-trailing-underscore'))
coderoot='test-apidoc-trailing-underscore')
def test_trailing_underscore(make_app, apidoc):
outdir = apidoc.outdir
assert (outdir / 'conf.py').isfile()
@ -150,7 +150,7 @@ def test_trailing_underscore(make_app, apidoc):
@pytest.mark.apidoc(
coderoot=(rootdir / 'root'),
coderoot='test-root',
options=[
'--doc-project', u'プロジェクト名'.encode('utf-8'),
'--doc-author', u'著者名'.encode('utf-8'),
@ -178,7 +178,7 @@ def test_multibyte_parameters(make_app, apidoc):
@pytest.mark.apidoc(
coderoot=(rootdir / 'root'),
coderoot='test-root',
options=['--ext-mathjax'],
)
def test_extension_parsed(make_app, apidoc):

View File

@ -13,7 +13,7 @@ from docutils import nodes
from sphinx.application import ExtensionError
from sphinx.domains import Domain
from util import strip_escseq
from sphinx.testing.util import strip_escseq
import pytest

View File

@ -12,7 +12,7 @@
from six import PY3
from util import SphinxTestApp, Struct # NOQA
from sphinx.testing.util import SphinxTestApp, Struct # NOQA
import pytest
import enum
@ -25,17 +25,19 @@ from sphinx.ext.autodoc import AutoDirective, add_documenter, \
app = None
def setup_module():
@pytest.fixture(scope='module', autouse=True)
def setup_module(rootdir, sphinx_test_tempdir):
global app
app = SphinxTestApp()
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)
def teardown_module():
yield
app.cleanup()

View File

@ -16,7 +16,7 @@ import pytest
from textwrap import dedent
from sphinx.errors import SphinxError
from util import rootdir, tempdir, path
from sphinx.testing.path import path
def request_session_head(url, **kwargs):
@ -27,14 +27,14 @@ def request_session_head(url, **kwargs):
@pytest.fixture
def nonascii_srcdir(request):
def nonascii_srcdir(request, rootdir, sphinx_test_tempdir):
# If supported, build in a non-ASCII source dir
test_name = u'\u65e5\u672c\u8a9e'
basedir = tempdir / request.node.originalname
basedir = sphinx_test_tempdir / request.node.originalname
try:
srcdir = basedir / test_name
if not srcdir.exists():
(rootdir / 'root').copytree(srcdir)
(rootdir / 'test-root').copytree(srcdir)
except UnicodeEncodeError:
srcdir = basedir / 'all'
else:

View File

@ -14,7 +14,7 @@
import plistlib
import pytest
from path import path
from sphinx.testing.path import path
# Use plistlib.load in 3.4 and above
try:

View File

@ -17,7 +17,7 @@ from six import PY3
from sphinx import __display_version__
from sphinx.util.inventory import InventoryFile
from util import remove_unicode_literals, strip_escseq
from sphinx.testing.util import remove_unicode_literals, strip_escseq
import xml.etree.cElementTree as ElementTree
from html5lib import getTreeBuilder, HTMLParser
import pytest

View File

@ -21,7 +21,7 @@ from html5lib import getTreeBuilder, HTMLParser
from sphinx.util.docutils import is_html5_writer_available
from util import skip_unless
from sphinx.testing.util import skip_unless
from test_build_html import flat_dict, tail_check, check_xpath
TREE_BUILDER = getTreeBuilder('etree', implementation=ElementTree)

View File

@ -24,7 +24,7 @@ from sphinx.util.osutil import cd, ensuredir
from sphinx.util import docutils
from sphinx.writers.latex import LaTeXTranslator
from util import SkipTest, remove_unicode_literals, strip_escseq, skip_if
from sphinx.testing.util import SkipTest, remove_unicode_literals, strip_escseq, skip_if
from test_build_html import ENV_WARNINGS

View File

@ -19,7 +19,7 @@ import pytest
from sphinx.writers.texinfo import TexinfoTranslator
from util import SkipTest, remove_unicode_literals, strip_escseq
from sphinx.testing.util import SkipTest, remove_unicode_literals, strip_escseq
from test_build_html import ENV_WARNINGS

View File

@ -12,7 +12,7 @@
from docutils.utils import column_width
from sphinx.writers.text import MAXWIDTH
from util import with_app
from sphinx.testing.util import with_app
def with_text_app(*args, **kw):

View File

@ -12,37 +12,36 @@ import shutil
import pytest
from util import find_files, rootdir, tempdir
root = tempdir / 'test-intl'
build_dir = root / '_build'
locale_dir = build_dir / 'locale'
from sphinx.testing.util import find_files
@pytest.fixture
def setup_test():
# delete remnants left over after failed build
root.rmtree(True)
(rootdir / 'roots' / 'test-intl').copytree(root)
def setup_test(app_params):
srcdir = app_params.kwargs['srcdir']
locale_dir = srcdir / 'locale'
# copy all catalogs into locale layout directory
for po in find_files(root, '.po'):
for po in find_files(srcdir, '.po'):
copy_po = (locale_dir / 'en' / 'LC_MESSAGES' / po)
if not copy_po.parent.exists():
copy_po.parent.makedirs()
shutil.copy(root / po, copy_po)
shutil.copy(srcdir / po, copy_po)
yield
build_dir.rmtree(True)
# delete remnants left over after failed build
locale_dir.rmtree(True)
(srcdir / '_build').rmtree(True)
@pytest.mark.usefixtures('setup_test')
@pytest.mark.test_params(shared_result='test-catalogs')
@pytest.mark.sphinx(
'html', testroot='intl',
confoverrides={'language': 'en', 'locale_dirs': [locale_dir]})
confoverrides={'language': 'en', 'locale_dirs': ['./locale']})
def test_compile_all_catalogs(app, status, warning):
app.builder.compile_all_catalogs()
locale_dir = app.srcdir / 'locale'
catalog_dir = locale_dir / app.config.language / 'LC_MESSAGES'
expect = set([
x.replace('.po', '.mo')
@ -54,10 +53,12 @@ def test_compile_all_catalogs(app, status, warning):
@pytest.mark.usefixtures('setup_test')
@pytest.mark.test_params(shared_result='test-catalogs')
@pytest.mark.sphinx(
'html', testroot='intl',
confoverrides={'language': 'en', 'locale_dirs': [locale_dir]})
'html', testroot='intl',
confoverrides={'language': 'en', 'locale_dirs': ['./locale']})
def test_compile_specific_catalogs(app, status, warning):
locale_dir = app.srcdir / 'locale'
catalog_dir = locale_dir / app.config.language / 'LC_MESSAGES'
def get_actual():
@ -70,12 +71,14 @@ def test_compile_specific_catalogs(app, status, warning):
@pytest.mark.usefixtures('setup_test')
@pytest.mark.test_params(shared_result='test-catalogs')
@pytest.mark.sphinx(
'html', testroot='intl',
confoverrides={'language': 'en', 'locale_dirs': [locale_dir]})
'html', testroot='intl',
confoverrides={'language': 'en', 'locale_dirs': ['./locale']})
def test_compile_update_catalogs(app, status, warning):
app.builder.compile_update_catalogs()
locale_dir = app.srcdir / 'locale'
catalog_dir = locale_dir / app.config.language / 'LC_MESSAGES'
expect = set([
x.replace('.po', '.mo')

View File

@ -16,6 +16,7 @@ import mock
import sphinx
from sphinx.config import Config
from sphinx.errors import ExtensionError, ConfigError, VersionRequirementError
from sphinx.testing.path import path
@pytest.mark.sphinx(confoverrides={
@ -129,8 +130,19 @@ def test_errors_if_setup_is_not_callable(tempdir, make_app):
assert 'callable' in str(excinfo.value)
@pytest.fixture
def make_app_with_empty_project(make_app, tempdir):
(tempdir / 'conf.py').write_text('')
def _make_app(*args, **kw):
kw.setdefault('srcdir', path(tempdir))
return make_app(*args, **kw)
return _make_app
@mock.patch.object(sphinx, '__display_version__', '1.3.4')
def test_needs_sphinx(make_app):
def test_needs_sphinx(make_app_with_empty_project):
make_app = make_app_with_empty_project
# micro version
app = make_app(confoverrides={'needs_sphinx': '1.3.3'}) # OK: less
app.cleanup()

View File

@ -13,43 +13,52 @@ import pytest
from sphinx.config import Config
from sphinx.directives.code import LiteralIncludeReader
from util import etree_parse, rootdir
from sphinx.testing.util import etree_parse
TESTROOT_PATH = rootdir / 'roots' / 'test-directive-code'
LITERAL_INC_PATH = TESTROOT_PATH / 'literal.inc'
DUMMY_CONFIG = Config(None, None, {}, '')
def test_LiteralIncludeReader():
@pytest.fixture(scope='module')
def testroot(rootdir):
testroot_path = rootdir / 'test-directive-code'
return testroot_path
@pytest.fixture(scope='module')
def literal_inc_path(testroot):
return testroot / 'literal.inc'
def test_LiteralIncludeReader(literal_inc_path):
options = {'lineno-match': True}
reader = LiteralIncludeReader(LITERAL_INC_PATH, options, DUMMY_CONFIG)
reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG)
content, lines = reader.read()
assert content == LITERAL_INC_PATH.text()
assert content == literal_inc_path.text()
assert lines == 14
assert reader.lineno_start == 1
def test_LiteralIncludeReader_lineno_start():
def test_LiteralIncludeReader_lineno_start(literal_inc_path):
options = {'lineno-start': 5}
reader = LiteralIncludeReader(LITERAL_INC_PATH, options, DUMMY_CONFIG)
reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG)
content, lines = reader.read()
assert content == LITERAL_INC_PATH.text()
assert content == literal_inc_path.text()
assert lines == 14
assert reader.lineno_start == 5
def test_LiteralIncludeReader_pyobject1():
def test_LiteralIncludeReader_pyobject1(literal_inc_path):
options = {'lineno-match': True, 'pyobject': 'Foo'}
reader = LiteralIncludeReader(LITERAL_INC_PATH, options, DUMMY_CONFIG)
reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG)
content, lines = reader.read()
assert content == ("class Foo:\n"
" pass\n")
assert reader.lineno_start == 6
def test_LiteralIncludeReader_pyobject2():
def test_LiteralIncludeReader_pyobject2(literal_inc_path):
options = {'pyobject': 'Bar'}
reader = LiteralIncludeReader(LITERAL_INC_PATH, options, DUMMY_CONFIG)
reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG)
content, lines = reader.read()
assert content == ("class Bar:\n"
" def baz():\n"
@ -57,25 +66,25 @@ def test_LiteralIncludeReader_pyobject2():
assert reader.lineno_start == 1 # no lineno-match
def test_LiteralIncludeReader_pyobject3():
def test_LiteralIncludeReader_pyobject3(literal_inc_path):
options = {'pyobject': 'Bar.baz'}
reader = LiteralIncludeReader(LITERAL_INC_PATH, options, DUMMY_CONFIG)
reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG)
content, lines = reader.read()
assert content == (" def baz():\n"
" pass\n")
def test_LiteralIncludeReader_pyobject_and_lines():
def test_LiteralIncludeReader_pyobject_and_lines(literal_inc_path):
options = {'pyobject': 'Bar', 'lines': '2-'}
reader = LiteralIncludeReader(LITERAL_INC_PATH, options, DUMMY_CONFIG)
reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG)
content, lines = reader.read()
assert content == (" def baz():\n"
" pass\n")
def test_LiteralIncludeReader_lines1():
def test_LiteralIncludeReader_lines1(literal_inc_path):
options = {'lines': '1-4'}
reader = LiteralIncludeReader(LITERAL_INC_PATH, options, DUMMY_CONFIG)
reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG)
content, lines = reader.read()
assert content == (u"# Literally included file using Python highlighting\n"
u"# -*- coding: utf-8 -*-\n"
@ -83,18 +92,18 @@ def test_LiteralIncludeReader_lines1():
u"foo = \"Including Unicode characters: üöä\"\n")
def test_LiteralIncludeReader_lines2():
def test_LiteralIncludeReader_lines2(literal_inc_path):
options = {'lines': '1,4,6'}
reader = LiteralIncludeReader(LITERAL_INC_PATH, options, DUMMY_CONFIG)
reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG)
content, lines = reader.read()
assert content == (u"# Literally included file using Python highlighting\n"
u"foo = \"Including Unicode characters: üöä\"\n"
u"class Foo:\n")
def test_LiteralIncludeReader_lines_and_lineno_match1():
def test_LiteralIncludeReader_lines_and_lineno_match1(literal_inc_path):
options = {'lines': '4-6', 'lineno-match': True}
reader = LiteralIncludeReader(LITERAL_INC_PATH, options, DUMMY_CONFIG)
reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG)
content, lines = reader.read()
assert content == (u"foo = \"Including Unicode characters: üöä\"\n"
u"\n"
@ -103,24 +112,24 @@ def test_LiteralIncludeReader_lines_and_lineno_match1():
@pytest.mark.sphinx() # init locale for errors
def test_LiteralIncludeReader_lines_and_lineno_match2(app, status, warning):
def test_LiteralIncludeReader_lines_and_lineno_match2(literal_inc_path, app, status, warning):
options = {'lines': '1,4,6', 'lineno-match': True}
reader = LiteralIncludeReader(LITERAL_INC_PATH, options, DUMMY_CONFIG)
reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG)
with pytest.raises(ValueError):
content, lines = reader.read()
@pytest.mark.sphinx() # init locale for errors
def test_LiteralIncludeReader_lines_and_lineno_match3(app, status, warning):
def test_LiteralIncludeReader_lines_and_lineno_match3(literal_inc_path, app, status, warning):
options = {'lines': '100-', 'lineno-match': True}
reader = LiteralIncludeReader(LITERAL_INC_PATH, options, DUMMY_CONFIG)
reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG)
with pytest.raises(ValueError):
content, lines = reader.read()
def test_LiteralIncludeReader_start_at():
def test_LiteralIncludeReader_start_at(literal_inc_path):
options = {'lineno-match': True, 'start-at': 'Foo', 'end-at': 'Bar'}
reader = LiteralIncludeReader(LITERAL_INC_PATH, options, DUMMY_CONFIG)
reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG)
content, lines = reader.read()
assert content == ("class Foo:\n"
" pass\n"
@ -129,19 +138,19 @@ def test_LiteralIncludeReader_start_at():
assert reader.lineno_start == 6
def test_LiteralIncludeReader_start_after():
def test_LiteralIncludeReader_start_after(literal_inc_path):
options = {'lineno-match': True, 'start-after': 'Foo', 'end-before': 'Bar'}
reader = LiteralIncludeReader(LITERAL_INC_PATH, options, DUMMY_CONFIG)
reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG)
content, lines = reader.read()
assert content == (" pass\n"
"\n")
assert reader.lineno_start == 7
def test_LiteralIncludeReader_start_after_and_lines():
def test_LiteralIncludeReader_start_after_and_lines(literal_inc_path):
options = {'lineno-match': True, 'lines': '6-',
'start-after': 'coding', 'end-before': 'comment'}
reader = LiteralIncludeReader(LITERAL_INC_PATH, options, DUMMY_CONFIG)
reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG)
content, lines = reader.read()
assert content == ("\n"
"class Bar:\n"
@ -151,9 +160,9 @@ def test_LiteralIncludeReader_start_after_and_lines():
assert reader.lineno_start == 8
def test_LiteralIncludeReader_start_at_and_lines():
def test_LiteralIncludeReader_start_at_and_lines(literal_inc_path):
options = {'lines': '2, 3, 5', 'start-at': 'foo', 'end-before': '#'}
reader = LiteralIncludeReader(LITERAL_INC_PATH, options, DUMMY_CONFIG)
reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG)
content, lines = reader.read()
assert content == ("\n"
"class Foo:\n"
@ -161,41 +170,41 @@ def test_LiteralIncludeReader_start_at_and_lines():
assert reader.lineno_start == 1
def test_LiteralIncludeReader_missing_start_and_end():
def test_LiteralIncludeReader_missing_start_and_end(literal_inc_path):
options = {'start-at': 'NOTHING'}
reader = LiteralIncludeReader(LITERAL_INC_PATH, options, DUMMY_CONFIG)
reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG)
with pytest.raises(ValueError):
content, lines = reader.read()
options = {'end-at': 'NOTHING'}
reader = LiteralIncludeReader(LITERAL_INC_PATH, options, DUMMY_CONFIG)
reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG)
with pytest.raises(ValueError):
content, lines = reader.read()
options = {'start-after': 'NOTHING'}
reader = LiteralIncludeReader(LITERAL_INC_PATH, options, DUMMY_CONFIG)
reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG)
with pytest.raises(ValueError):
content, lines = reader.read()
options = {'end-before': 'NOTHING'}
reader = LiteralIncludeReader(LITERAL_INC_PATH, options, DUMMY_CONFIG)
reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG)
with pytest.raises(ValueError):
content, lines = reader.read()
def test_LiteralIncludeReader_prepend():
def test_LiteralIncludeReader_prepend(literal_inc_path):
options = {'lines': '1', 'prepend': 'Hello', 'append': 'Sphinx'}
reader = LiteralIncludeReader(LITERAL_INC_PATH, options, DUMMY_CONFIG)
reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG)
content, lines = reader.read()
assert content == ("Hello\n"
"# Literally included file using Python highlighting\n"
"Sphinx\n")
def test_LiteralIncludeReader_dedent():
def test_LiteralIncludeReader_dedent(literal_inc_path):
# dedent: 2
options = {'lines': '10-12', 'dedent': 2}
reader = LiteralIncludeReader(LITERAL_INC_PATH, options, DUMMY_CONFIG)
reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG)
content, lines = reader.read()
assert content == (" def baz():\n"
" pass\n"
@ -203,7 +212,7 @@ def test_LiteralIncludeReader_dedent():
# dedent: 4
options = {'lines': '10-12', 'dedent': 4}
reader = LiteralIncludeReader(LITERAL_INC_PATH, options, DUMMY_CONFIG)
reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG)
content, lines = reader.read()
assert content == ("def baz():\n"
" pass\n"
@ -211,17 +220,17 @@ def test_LiteralIncludeReader_dedent():
# dedent: 6
options = {'lines': '10-12', 'dedent': 6}
reader = LiteralIncludeReader(LITERAL_INC_PATH, options, DUMMY_CONFIG)
reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG)
content, lines = reader.read()
assert content == ("f baz():\n"
" pass\n"
"\n")
def test_LiteralIncludeReader_tabwidth():
def test_LiteralIncludeReader_tabwidth(testroot):
# tab-width: 4
options = {'tab-width': 4, 'pyobject': 'Qux'}
reader = LiteralIncludeReader(TESTROOT_PATH / 'target.py', options, DUMMY_CONFIG)
reader = LiteralIncludeReader(testroot / 'target.py', options, DUMMY_CONFIG)
content, lines = reader.read()
assert content == ("class Qux:\n"
" def quux(self):\n"
@ -229,27 +238,27 @@ def test_LiteralIncludeReader_tabwidth():
# tab-width: 8
options = {'tab-width': 8, 'pyobject': 'Qux'}
reader = LiteralIncludeReader(TESTROOT_PATH / 'target.py', options, DUMMY_CONFIG)
reader = LiteralIncludeReader(testroot / 'target.py', options, DUMMY_CONFIG)
content, lines = reader.read()
assert content == ("class Qux:\n"
" def quux(self):\n"
" pass\n")
def test_LiteralIncludeReader_tabwidth_dedent():
def test_LiteralIncludeReader_tabwidth_dedent(testroot):
options = {'tab-width': 4, 'dedent': 4, 'pyobject': 'Qux.quux'}
reader = LiteralIncludeReader(TESTROOT_PATH / 'target.py', options, DUMMY_CONFIG)
reader = LiteralIncludeReader(testroot / 'target.py', options, DUMMY_CONFIG)
content, lines = reader.read()
assert content == ("def quux(self):\n"
" pass\n")
def test_LiteralIncludeReader_diff():
options = {'diff': TESTROOT_PATH / 'literal-diff.inc'}
reader = LiteralIncludeReader(LITERAL_INC_PATH, options, DUMMY_CONFIG)
def test_LiteralIncludeReader_diff(testroot, literal_inc_path):
options = {'diff': testroot / 'literal-diff.inc'}
reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG)
content, lines = reader.read()
assert content == ("--- " + TESTROOT_PATH + "/literal-diff.inc\n"
"+++ " + TESTROOT_PATH + "/literal.inc\n"
assert content == ("--- " + testroot + "/literal-diff.inc\n"
"+++ " + testroot + "/literal.inc\n"
"@@ -7,8 +7,8 @@\n"
" pass\n"
" \n"

View File

@ -12,7 +12,8 @@
import re
import pytest
from util import path, SkipTest
from sphinx.testing.path import path
from sphinx.testing.util import SkipTest
def regex_count(expr, result):
@ -77,7 +78,7 @@ def test_docutils_source_link_with_nonascii_file(app, status, warning):
try:
(srcdir / (mb_name + '.txt')).write_text('')
except UnicodeEncodeError:
from path import FILESYSTEMENCODING
from sphinx.testing.path import FILESYSTEMENCODING
raise SkipTest(
'nonascii filename not supported on this filesystem encoding: '
'%s', FILESYSTEMENCODING)

View File

@ -16,7 +16,7 @@ from docutils import nodes
from sphinx import addnodes
from sphinx.domains.javascript import JavaScriptDomain
from util import assert_node
from sphinx.testing.util import assert_node
@pytest.mark.sphinx('dummy', testroot='domain-js')

View File

@ -17,7 +17,7 @@ from docutils import nodes
from sphinx import addnodes
from sphinx.domains.python import py_sig_re, _pseudo_parse_arglist, PythonDomain
from util import assert_node
from sphinx.testing.util import assert_node
def parse(sig):

View File

@ -8,22 +8,24 @@
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import pytest
from util import SphinxTestApp, path
from sphinx.testing.util import SphinxTestApp, path
from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.builders.latex import LaTeXBuilder
app = env = None
def setup_module():
@pytest.fixture(scope='module', autouse=True)
def setup_module(rootdir, sphinx_test_tempdir):
global app, env
app = SphinxTestApp(srcdir='root-envtest')
srcdir = sphinx_test_tempdir / 'root-envtest'
if not srcdir.exists():
(rootdir/'test-root').copytree(srcdir)
app = SphinxTestApp(srcdir=srcdir)
env = app.env
def teardown_module():
yield
app.cleanup()

View File

@ -16,7 +16,7 @@ from sphinx.addnodes import compact_paragraph, only
from sphinx.builders.html import StandaloneHTMLBuilder
import pytest
from util import assert_node
from sphinx.testing.util import assert_node
@pytest.mark.sphinx('xml', testroot='toctree')

View File

@ -13,7 +13,7 @@ from six import iteritems, StringIO
from sphinx.ext.autosummary import mangle_signature
from util import etree_parse
from sphinx.testing.util import etree_parse
import pytest

View File

@ -11,7 +11,6 @@
import re
import sys
from util import rootdir
from sphinx.ext.inheritance_diagram import InheritanceException, import_classes
import pytest
@ -44,12 +43,12 @@ def test_inheritance_diagram_latex(app, status, warning):
assert re.search(pattern, content, re.M)
def test_import_classes():
def test_import_classes(rootdir):
from sphinx.application import Sphinx, TemplateBridge
from sphinx.util.i18n import CatalogInfo
try:
sys.path.append(rootdir / 'roots/test-ext-inheritance_diagram')
sys.path.append(rootdir / 'test-ext-inheritance_diagram')
from example.sphinx import DummyClass
# got exception for unknown class or module

View File

@ -12,7 +12,7 @@
import re
import pytest
from util import SkipTest
from sphinx.testing.util import SkipTest
@pytest.mark.sphinx(

View File

@ -20,7 +20,7 @@ from babel.messages import pofile, mofile
from six import string_types
import pytest
from util import (
from sphinx.testing.util import (
path, etree_parse, strip_escseq,
assert_re_search, assert_not_re_search, assert_startswith, assert_node
)
@ -494,15 +494,15 @@ def test_gettext_buildr_ignores_only_directive(app):
@sphinx_intl
# use individual shared_result directory to avoid "incompatible doctree" error
@pytest.mark.test_params(shared_result='test_gettext_dont_rebuild_mo')
def test_gettext_dont_rebuild_mo(make_app, app_params, build_mo):
# --- don't rebuild by .mo mtime
def get_number_of_update_targets(app_):
updated = app_.env.update(app_.config, app_.srcdir, app_.doctreedir)
return len(updated)
# setup new directory
args, kwargs = app_params
kwargs['srcdir'] = 'test_gettext_dont_rebuild_mo'
# phase1: build document with non-gettext builder and generate mo file in srcdir
app0 = make_app('dummy', *args, **kwargs)

View File

@ -23,7 +23,7 @@ from sphinx.writers.html import HTMLWriter, HTMLTranslator
from sphinx.writers.latex import LaTeXWriter, LaTeXTranslator
import pytest
from util import assert_node
from sphinx.testing.util import assert_node
@pytest.fixture

View File

@ -16,7 +16,7 @@ from six import PY2, text_type, StringIO
from six.moves import input
import pytest
from util import SkipTest
from sphinx.testing.util import SkipTest
from sphinx import application
from sphinx import quickstart as qs

View File

@ -18,19 +18,11 @@ import sphinx
import pytest
from sphinx.util.osutil import cd
from util import rootdir, tempdir
from textwrap import dedent
root = tempdir / 'test-setup'
def setup_module():
if not root.exists():
(rootdir / 'roots' / 'test-setup').copytree(root)
@pytest.fixture
def setup_command(request, tempdir):
def setup_command(request, tempdir, rootdir):
"""
Run `setup.py build_sphinx` with args and kwargs,
pass it to the test and clean up properly.
@ -38,8 +30,8 @@ def setup_command(request, tempdir):
marker = request.node.get_marker('setup_command')
args = marker.args if marker else []
pkgrootdir = tempdir / 'root'
root.copytree(pkgrootdir)
pkgrootdir = tempdir / 'test-setup'
(rootdir / 'test-setup').copytree(pkgrootdir)
with cd(pkgrootdir):
pythonpath = os.path.dirname(os.path.dirname(sphinx.__file__))
@ -89,7 +81,7 @@ def nonascii_srcdir(request, setup_command):
try:
(srcdir / mb_name).makedirs()
except UnicodeEncodeError:
from path import FILESYSTEMENCODING
from sphinx.testing.path import FILESYSTEMENCODING
pytest.skip(
'non-ASCII filename not supported on this filesystem encoding: '
'%s' % FILESYSTEMENCODING)

View File

@ -17,7 +17,7 @@ from sphinx.util import (
display_chunk, encode_uri, parselinenos, split_docinfo, status_iterator
)
from util import strip_escseq
from sphinx.testing.util import strip_escseq
def test_encode_uri():

View File

@ -16,23 +16,25 @@ from sphinx.util.images import (
get_image_size, guess_mimetype, get_image_extension, parse_data_uri
)
from util import rootdir
GIF_FILENAME = 'img.gif'
PNG_FILENAME = 'img.png'
PDF_FILENAME = 'img.pdf'
TXT_FILENAME = 'contents.txt'
GIF_FILENAME = rootdir / 'root' / 'img.gif'
PNG_FILENAME = rootdir / 'root' / 'img.png'
PDF_FILENAME = rootdir / 'root' / 'img.pdf'
TXT_FILENAME = rootdir / 'root' / 'contents.txt'
@pytest.fixture(scope='module')
def testroot(rootdir):
return rootdir / 'test-root'
def test_get_image_size():
assert get_image_size(GIF_FILENAME) == (200, 181)
assert get_image_size(PNG_FILENAME) == (200, 181)
assert get_image_size(PDF_FILENAME) is None
assert get_image_size(TXT_FILENAME) is None
def test_get_image_size(testroot):
assert get_image_size(testroot / GIF_FILENAME) == (200, 181)
assert get_image_size(testroot / PNG_FILENAME) == (200, 181)
assert get_image_size(testroot / PDF_FILENAME) is None
assert get_image_size(testroot / TXT_FILENAME) is None
def test_guess_mimetype():
def test_guess_mimetype(testroot):
# guess by filename
assert guess_mimetype('img.png') == 'image/png'
assert guess_mimetype('img.jpg') == 'image/jpeg'
@ -42,21 +44,22 @@ def test_guess_mimetype():
assert guess_mimetype('IMG.PNG') == 'image/png'
# guess by content
assert guess_mimetype(content=GIF_FILENAME.bytes()) == 'image/gif'
assert guess_mimetype(content=PNG_FILENAME.bytes()) == 'image/png'
assert guess_mimetype(content=PDF_FILENAME.bytes()) is None
assert guess_mimetype(content=TXT_FILENAME.bytes()) is None
assert guess_mimetype(content=TXT_FILENAME.bytes(), default='text/plain') == 'text/plain'
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=GIF_FILENAME.bytes(),
content=(testroot/GIF_FILENAME).bytes(),
default='text/plain') == 'image/png'
assert guess_mimetype('no_extension',
content=GIF_FILENAME.bytes(),
content=(testroot/GIF_FILENAME).bytes(),
default='text/plain') == 'image/gif'
assert guess_mimetype('no_extension',
content=TXT_FILENAME.bytes(),
content=(testroot/TXT_FILENAME).bytes(),
default='text/plain') == 'text/plain'

View File

@ -20,7 +20,7 @@ from sphinx.util.logging import is_suppressed_warning
from sphinx.util.parallel import ParallelTasks
import pytest
from util import strip_escseq
from sphinx.testing.util import strip_escseq
def test_info_and_warning(app, status, warning):

View File

@ -11,28 +11,31 @@
import pickle
import pytest
from docutils.parsers.rst.directives.html import MetaBody
from sphinx import addnodes
from sphinx.versioning import add_uids, merge_doctrees, get_ratio
from util import SphinxTestApp
from sphinx.testing.util import SphinxTestApp
app = original = original_uids = None
def setup_module():
@pytest.fixture(scope='module', autouse=True)
def setup_module(rootdir, sphinx_test_tempdir):
global app, original, original_uids
app = SphinxTestApp(testroot='versioning')
srcdir = sphinx_test_tempdir / 'test-versioning'
if not srcdir.exists():
(rootdir/'test-versioning').copytree(srcdir)
app = SphinxTestApp(srcdir=srcdir)
app.builder.env.app = app
app.connect('doctree-resolved', on_doctree_resolved)
app.build()
original = doctrees['original']
original_uids = [n.uid for n in add_uids(original, is_paragraph)]
def teardown_module():
yield
app.cleanup()

View File

@ -16,17 +16,16 @@ except ImportError:
sqlalchemy_missing = True
import pytest
from util import rootdir, tempdir
@pytest.mark.skipif(sqlalchemy_missing, reason='needs sqlalchemy')
def test_build(request):
def test_build(request, rootdir, sphinx_test_tempdir):
settings = {
'srcdir': rootdir / 'roots' / 'test-basic',
'srcdir': rootdir / 'test-basic',
# to use same directory for 'builddir' in each 'support' fixture, using
# 'tempdir' (static) value instead of 'tempdir' fixture value.
# 'sphinx_test_tempdir' (static) value instead of 'tempdir' fixture value.
# each test expect result of db value at previous test case.
'builddir': tempdir / 'websupport'
'builddir': sphinx_test_tempdir / 'websupport'
}
marker = request.node.get_marker('support')
if marker: