mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge branch 'stable'
This commit is contained in:
commit
4c22cd10ca
@ -12,7 +12,7 @@ python:
|
||||
- "pypy"
|
||||
env:
|
||||
global:
|
||||
- TEST='-v --with-timer --timer-top-n 25'
|
||||
- TEST='-v --durations 25'
|
||||
- PYTHONFAULTHANDLER=x
|
||||
- PYTHONWARNINGS=all
|
||||
matrix:
|
||||
|
4
CHANGES
4
CHANGES
@ -58,6 +58,7 @@ Features added
|
||||
|
||||
* #3241: emit latex warning if buggy titlesec (ref #3210)
|
||||
* #3194: Refer the $MAKE environment variable to determine ``make`` command
|
||||
* Emit warning for nested numbered toctrees (refs: #3142)
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
@ -70,6 +71,9 @@ Bugs fixed
|
||||
attributes of Enum class correctly.
|
||||
* #3261: ``latex_use_parts`` makes sphinx crash
|
||||
* The warning type ``misc.highlighting_failure`` does not work
|
||||
* #3294: ``add_latex_package()`` make crashes non-LaTeX builders
|
||||
* The caption of table are rendered as invalid HTML (refs: #3287)
|
||||
|
||||
|
||||
Release 1.5.1 (released Dec 13, 2016)
|
||||
=====================================
|
||||
|
7
Makefile
7
Makefile
@ -75,14 +75,13 @@ reindent:
|
||||
@$(PYTHON) utils/reindent.py -r -n .
|
||||
|
||||
test:
|
||||
@cd tests; $(PYTHON) run.py -I py35 -d -m '^[tT]est' $(TEST)
|
||||
@cd tests; $(PYTHON) run.py --ignore py35 -v $(TEST)
|
||||
|
||||
test-async:
|
||||
@cd tests; $(PYTHON) run.py -d -m '^[tT]est' $(TEST)
|
||||
@cd tests; $(PYTHON) run.py -v $(TEST)
|
||||
|
||||
covertest:
|
||||
@cd tests; $(PYTHON) run.py -d -m '^[tT]est' --with-coverage \
|
||||
--cover-package=sphinx $(TEST)
|
||||
@cd tests; $(PYTHON) run.py -v --cov=sphinx --junitxml=.junit.xml $(TEST)
|
||||
|
||||
build:
|
||||
@$(PYTHON) setup.py build
|
||||
|
@ -233,6 +233,7 @@ General configuration
|
||||
* ref.citation
|
||||
* ref.doc
|
||||
* misc.highlighting_failure
|
||||
* toc.secnum
|
||||
* epub.unknown_project_files
|
||||
|
||||
You can choose from these types.
|
||||
|
@ -812,6 +812,7 @@ class Sphinx(object):
|
||||
def add_latex_package(self, packagename, options=None):
|
||||
# type: (unicode, unicode) -> None
|
||||
logger.debug('[app] adding latex package: %r', packagename)
|
||||
if hasattr(self.builder, 'usepackages'): # only for LaTeX builder
|
||||
self.builder.usepackages.append((packagename, options))
|
||||
|
||||
def add_lexer(self, alias, lexer):
|
||||
|
@ -483,10 +483,14 @@ class Toctree(EnvironmentManager):
|
||||
if depth == 0:
|
||||
return
|
||||
for (title, ref) in toctreenode['entries']:
|
||||
if url_re.match(ref) or ref == 'self' or ref in assigned:
|
||||
if url_re.match(ref) or ref == 'self':
|
||||
# don't mess with those
|
||||
continue
|
||||
if ref in self.tocs:
|
||||
elif ref in assigned:
|
||||
logger.warning('%s is already assigned section numbers '
|
||||
'(nested numbered toctree?)', ref,
|
||||
location=toctreenode, type='toc', subtype='secnum')
|
||||
elif ref in self.tocs:
|
||||
secnums = self.toc_secnumbers[ref] = {}
|
||||
assigned.add(ref)
|
||||
_walk_toc(self.tocs[ref], secnums, depth,
|
||||
|
@ -228,9 +228,10 @@ def save_traceback(app):
|
||||
modfile = getattr(extmod, '__file__', 'unknown')
|
||||
if isinstance(modfile, bytes):
|
||||
modfile = modfile.decode(fs_encoding, 'replace')
|
||||
os.write(fd, ('# %s (%s) from %s\n' % (
|
||||
extname, app._extension_metadata[extname]['version'],
|
||||
modfile)).encode('utf-8'))
|
||||
version = app._extension_metadata[extname]['version']
|
||||
if version != 'builtin':
|
||||
os.write(fd, ('# %s (%s) from %s\n' %
|
||||
(extname, version, modfile)).encode('utf-8'))
|
||||
os.write(fd, exc_format.encode('utf-8'))
|
||||
os.close(fd)
|
||||
return path
|
||||
|
@ -344,6 +344,27 @@ class HTMLTranslator(BaseTranslator):
|
||||
if isinstance(node.parent, nodes.table):
|
||||
self.body.append('<span class="caption-text">')
|
||||
|
||||
def depart_title(self, node):
|
||||
close_tag = self.context[-1]
|
||||
if (self.permalink_text and self.builder.add_permalinks and
|
||||
node.parent.hasattr('ids') and node.parent['ids']):
|
||||
# add permalink anchor
|
||||
if close_tag.startswith('</h'):
|
||||
self.add_permalink_ref(node.parent, _('Permalink to this headline'))
|
||||
elif close_tag.startswith('</a></h'):
|
||||
self.body.append(u'</a><a class="headerlink" href="#%s" ' %
|
||||
node.parent['ids'][0] +
|
||||
u'title="%s">%s' % (
|
||||
_('Permalink to this headline'),
|
||||
self.permalink_text))
|
||||
elif isinstance(node.parent, nodes.table):
|
||||
self.body.append('</span>')
|
||||
self.add_permalink_ref(node.parent, _('Permalink to this table'))
|
||||
elif isinstance(node.parent, nodes.table):
|
||||
self.body.append('</span>')
|
||||
|
||||
BaseTranslator.depart_title(self, node)
|
||||
|
||||
# overwritten
|
||||
def visit_literal_block(self, node):
|
||||
if node.rawsource != node.astext():
|
||||
@ -701,25 +722,6 @@ class HTMLTranslator(BaseTranslator):
|
||||
def depart_manpage(self, node):
|
||||
return self.depart_literal_emphasis(node)
|
||||
|
||||
def depart_title(self, node):
|
||||
close_tag = self.context[-1]
|
||||
if (self.permalink_text and self.builder.add_permalinks and
|
||||
node.parent.hasattr('ids') and node.parent['ids']):
|
||||
# add permalink anchor
|
||||
if close_tag.startswith('</h'):
|
||||
self.add_permalink_ref(node.parent, _('Permalink to this headline'))
|
||||
elif close_tag.startswith('</a></h'):
|
||||
self.body.append(u'</a><a class="headerlink" href="#%s" ' %
|
||||
node.parent['ids'][0] +
|
||||
u'title="%s">%s' % (
|
||||
_('Permalink to this headline'),
|
||||
self.permalink_text))
|
||||
elif isinstance(node.parent, nodes.table):
|
||||
self.body.append('</span>')
|
||||
self.add_permalink_ref(node.parent, _('Permalink to this table'))
|
||||
|
||||
BaseTranslator.depart_title(self, node)
|
||||
|
||||
# overwritten to add even/odd classes
|
||||
|
||||
def visit_table(self, node):
|
||||
|
@ -1,6 +1,6 @@
|
||||
flake8
|
||||
nose
|
||||
nose-timer
|
||||
pytest>=3.0
|
||||
pytest-cov
|
||||
mock
|
||||
six>=1.4
|
||||
Jinja2>=2.3
|
||||
|
108
tests/conftest.py
Normal file
108
tests/conftest.py
Normal file
@ -0,0 +1,108 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
import pytest
|
||||
from six import StringIO
|
||||
|
||||
from util import SphinxTestApp, path
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def app_params(request):
|
||||
"""
|
||||
parameters that is specified by 'pytest.mark.sphinx' for
|
||||
sphinx.application.Sphinx initialization
|
||||
"""
|
||||
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())]
|
||||
return args, kwargs
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def app(app_params, make_app):
|
||||
"""
|
||||
provides sphinx.application.Sphinx object
|
||||
"""
|
||||
args, kwargs = app_params
|
||||
app_ = make_app(*args, **kwargs)
|
||||
return 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():
|
||||
"""
|
||||
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_ = SphinxTestApp(*args, **kwargs)
|
||||
apps.append(app_)
|
||||
return app_
|
||||
yield make
|
||||
|
||||
sys.path[:] = syspath
|
||||
for app_ in apps:
|
||||
app_.cleanup()
|
||||
|
||||
|
||||
@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 path(tmpdir)
|
1158
tests/coverage.py
1158
tests/coverage.py
File diff suppressed because it is too large
Load Diff
@ -12,7 +12,7 @@ import sys
|
||||
import shutil
|
||||
from io import open
|
||||
|
||||
from six import PY2, text_type, binary_type
|
||||
from six import PY2, text_type
|
||||
|
||||
|
||||
FILESYSTEMENCODING = sys.getfilesystemencoding() or sys.getdefaultencoding()
|
||||
@ -144,9 +144,7 @@ class path(text_type):
|
||||
"""
|
||||
mode = 'rU' if PY2 else 'r'
|
||||
with open(self, mode=mode, encoding=encoding, **kwargs) as f:
|
||||
text = f.read()
|
||||
contents = repr_as(text, '<%s contents>' % self.basename())
|
||||
return contents
|
||||
return f.read()
|
||||
|
||||
def bytes(self):
|
||||
"""
|
||||
@ -201,21 +199,3 @@ class path(text_type):
|
||||
|
||||
def __repr__(self):
|
||||
return '%s(%s)' % (self.__class__.__name__, text_type.__repr__(self))
|
||||
|
||||
|
||||
# Lives here only to avoid circular references; use it from util.py!
|
||||
class _repr_text(text_type):
|
||||
def __repr__(self):
|
||||
return self._repr
|
||||
|
||||
|
||||
class _repr_bin(binary_type):
|
||||
def __repr__(self):
|
||||
return self._repr
|
||||
|
||||
|
||||
def repr_as(string, repr_):
|
||||
wrapper = _repr_text if isinstance(string, text_type) else _repr_bin
|
||||
proxy = wrapper(string)
|
||||
proxy._repr = repr_
|
||||
return proxy
|
||||
|
@ -14,7 +14,7 @@
|
||||
import six
|
||||
import sys
|
||||
from util import TestApp, Struct, raises, SkipTest
|
||||
from nose.tools import with_setup, eq_
|
||||
import pytest
|
||||
|
||||
from six import StringIO
|
||||
from docutils.statemachine import ViewList
|
||||
@ -42,6 +42,7 @@ def teardown_module():
|
||||
directive = options = None
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def setup_test():
|
||||
global options, directive
|
||||
global processed_docstrings, processed_signatures, _warnings
|
||||
@ -106,7 +107,7 @@ def skip_member(app, what, name, obj, skip, options):
|
||||
return True
|
||||
|
||||
|
||||
@with_setup(setup_test)
|
||||
@pytest.mark.usefixtures('setup_test')
|
||||
def test_generate():
|
||||
def assert_warns(warn_str, objtype, name, **kw):
|
||||
inst = AutoDirective._registry[objtype](directive, name)
|
@ -4,7 +4,7 @@ import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.abspath('.'))
|
||||
extensions = ['test_enumerable_node']
|
||||
extensions = ['enumerable_node']
|
||||
|
||||
master_doc = 'index'
|
||||
numfig = True
|
||||
|
@ -11,7 +11,7 @@ class DummyTestParser(Parser):
|
||||
pass
|
||||
|
||||
|
||||
extensions = ['test_source_parser']
|
||||
extensions = ['source_parser']
|
||||
source_suffix = ['.rst', '.test']
|
||||
source_parsers = {
|
||||
'.test': DummyTestParser
|
||||
|
@ -11,7 +11,7 @@ class DummyMarkdownParser(Parser):
|
||||
pass
|
||||
|
||||
|
||||
extensions = ['test_source_parser']
|
||||
extensions = ['source_parser']
|
||||
source_suffix = ['.rst', '.md']
|
||||
source_parsers = {
|
||||
'.md': DummyMarkdownParser
|
||||
|
16
tests/run.py
16
tests/run.py
@ -17,14 +17,14 @@ import warnings
|
||||
import traceback
|
||||
|
||||
from path import path
|
||||
import nose
|
||||
import pytest
|
||||
|
||||
testroot = os.path.dirname(__file__) or '.'
|
||||
sys.path.insert(0, os.path.abspath(os.path.join(testroot, os.path.pardir)))
|
||||
|
||||
# check dependencies before testing
|
||||
print('Checking dependencies...')
|
||||
for modname in ('nose', 'mock', 'six', 'docutils', 'jinja2', 'pygments',
|
||||
for modname in ('pytest', 'mock', 'six', 'docutils', 'jinja2', 'pygments',
|
||||
'snowballstemmer', 'babel', 'html5lib'):
|
||||
try:
|
||||
__import__(modname)
|
||||
@ -50,7 +50,15 @@ print('Running Sphinx test suite (with Python %s)...' % sys.version.split()[0])
|
||||
sys.stdout.flush()
|
||||
|
||||
# filter warnings of test dependencies
|
||||
warnings.filterwarnings('ignore', category=DeprecationWarning, module='nose.util')
|
||||
warnings.filterwarnings('ignore', category=DeprecationWarning, module='site') # virtualenv
|
||||
|
||||
nose.main(argv=sys.argv)
|
||||
# exclude 'root' and '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')
|
||||
]
|
||||
args = sys.argv[1:]
|
||||
for path in ignore_paths:
|
||||
args.extend(['--ignore', path])
|
||||
|
||||
sys.exit(pytest.main(args))
|
||||
|
@ -11,7 +11,8 @@
|
||||
|
||||
import sys
|
||||
|
||||
from util import with_app, rootdir
|
||||
import pytest
|
||||
from util import rootdir
|
||||
|
||||
|
||||
def setup_module():
|
||||
@ -22,7 +23,7 @@ def teardown_module():
|
||||
sys.path.remove(rootdir / 'roots' / 'test-api-set-translator')
|
||||
|
||||
|
||||
@with_app('html')
|
||||
@pytest.mark.sphinx('html')
|
||||
def test_html_translator(app, status, warning):
|
||||
# no set_translator()
|
||||
translator_class = app.builder.translator_class
|
||||
@ -30,8 +31,8 @@ def test_html_translator(app, status, warning):
|
||||
assert translator_class.__name__ == 'SmartyPantsHTMLTranslator'
|
||||
|
||||
|
||||
@with_app('html',
|
||||
confoverrides={'html_use_smartypants': False})
|
||||
@pytest.mark.sphinx('html', confoverrides={
|
||||
'html_use_smartypants': False})
|
||||
def test_html_with_smartypants(app, status, warning):
|
||||
# no set_translator(), html_use_smartypants=False
|
||||
translator_class = app.builder.translator_class
|
||||
@ -39,7 +40,7 @@ def test_html_with_smartypants(app, status, warning):
|
||||
assert translator_class.__name__ == 'HTMLTranslator'
|
||||
|
||||
|
||||
@with_app('html', testroot='api-set-translator')
|
||||
@pytest.mark.sphinx('html', testroot='api-set-translator')
|
||||
def test_html_with_set_translator_for_html_(app, status, warning):
|
||||
# use set_translator()
|
||||
translator_class = app.builder.translator_class
|
||||
@ -48,7 +49,7 @@ def test_html_with_set_translator_for_html_(app, status, warning):
|
||||
|
||||
|
||||
# this test break test_websupport.test_comments test. why?
|
||||
# @with_app(
|
||||
# @pytest.mark.sphinx(
|
||||
# buildername='dirhtml',
|
||||
# srcdir=(test_roots / 'test-api-set-translator'),
|
||||
# )
|
||||
@ -58,63 +59,63 @@ def test_html_with_set_translator_for_html_(app, status, warning):
|
||||
# assert translator_class.__name__ == 'ConfDirHTMLTranslator'
|
||||
|
||||
|
||||
@with_app('singlehtml', testroot='api-set-translator')
|
||||
@pytest.mark.sphinx('singlehtml', testroot='api-set-translator')
|
||||
def test_singlehtml_set_translator_for_singlehtml(app, status, warning):
|
||||
translator_class = app.builder.translator_class
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfSingleHTMLTranslator'
|
||||
|
||||
|
||||
@with_app('pickle', testroot='api-set-translator')
|
||||
@pytest.mark.sphinx('pickle', testroot='api-set-translator')
|
||||
def test_pickle_set_translator_for_pickle(app, status, warning):
|
||||
translator_class = app.builder.translator_class
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfPickleTranslator'
|
||||
|
||||
|
||||
@with_app('json', testroot='api-set-translator')
|
||||
@pytest.mark.sphinx('json', testroot='api-set-translator')
|
||||
def test_json_set_translator_for_json(app, status, warning):
|
||||
translator_class = app.builder.translator_class
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfJsonTranslator'
|
||||
|
||||
|
||||
@with_app('latex', testroot='api-set-translator')
|
||||
@pytest.mark.sphinx('latex', testroot='api-set-translator')
|
||||
def test_html_with_set_translator_for_latex(app, status, warning):
|
||||
translator_class = app.builder.translator_class
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfLaTeXTranslator'
|
||||
|
||||
|
||||
@with_app('man', testroot='api-set-translator')
|
||||
@pytest.mark.sphinx('man', testroot='api-set-translator')
|
||||
def test_html_with_set_translator_for_man(app, status, warning):
|
||||
translator_class = app.builder.translator_class
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfManualPageTranslator'
|
||||
|
||||
|
||||
@with_app('texinfo', testroot='api-set-translator')
|
||||
@pytest.mark.sphinx('texinfo', testroot='api-set-translator')
|
||||
def test_html_with_set_translator_for_texinfo(app, status, warning):
|
||||
translator_class = app.builder.translator_class
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfTexinfoTranslator'
|
||||
|
||||
|
||||
@with_app('text', testroot='api-set-translator')
|
||||
@pytest.mark.sphinx('text', testroot='api-set-translator')
|
||||
def test_html_with_set_translator_for_text(app, status, warning):
|
||||
translator_class = app.builder.translator_class
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfTextTranslator'
|
||||
|
||||
|
||||
@with_app('xml', testroot='api-set-translator')
|
||||
@pytest.mark.sphinx('xml', testroot='api-set-translator')
|
||||
def test_html_with_set_translator_for_xml(app, status, warning):
|
||||
translator_class = app.builder.translator_class
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfXMLTranslator'
|
||||
|
||||
|
||||
@with_app('pseudoxml', testroot='api-set-translator')
|
||||
@pytest.mark.sphinx('pseudoxml', testroot='api-set-translator')
|
||||
def test_html_with_set_translator_for_pseudoxml(app, status, warning):
|
||||
translator_class = app.builder.translator_class
|
||||
assert translator_class
|
||||
|
@ -11,45 +11,60 @@
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
from six import PY2
|
||||
from collections import namedtuple
|
||||
|
||||
from sphinx import apidoc
|
||||
import pytest
|
||||
|
||||
from util import with_tempdir, with_app, rootdir
|
||||
from sphinx.apidoc import main as apidoc_main
|
||||
|
||||
from util import rootdir, remove_unicode_literals
|
||||
|
||||
|
||||
@with_tempdir
|
||||
def test_simple(tempdir):
|
||||
codedir = rootdir / 'root'
|
||||
@pytest.fixture()
|
||||
def apidoc(tempdir, apidoc_params):
|
||||
_, kwargs = apidoc_params
|
||||
coderoot = kwargs.get('coderoot', (rootdir / 'root'))
|
||||
outdir = tempdir / 'out'
|
||||
args = ['sphinx-apidoc', '-o', outdir, '-F', codedir]
|
||||
apidoc.main(args)
|
||||
args = ['sphinx-apidoc', '-o', outdir, '-F', coderoot] + kwargs.get('options', [])
|
||||
apidoc_main(args)
|
||||
return namedtuple('apidoc', 'coderoot,outdir')(coderoot, outdir)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def apidoc_params(request):
|
||||
markers = request.node.get_marker("apidoc")
|
||||
pargs = {}
|
||||
kwargs = {}
|
||||
|
||||
if markers is not None:
|
||||
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())]
|
||||
return args, kwargs
|
||||
|
||||
|
||||
@pytest.mark.apidoc(coderoot=(rootdir / 'root'))
|
||||
def test_simple(make_app, apidoc):
|
||||
outdir = apidoc.outdir
|
||||
assert (outdir / 'conf.py').isfile()
|
||||
assert (outdir / 'autodoc_fodder.rst').isfile()
|
||||
assert (outdir / 'index.rst').isfile()
|
||||
|
||||
@with_app('text', srcdir=outdir)
|
||||
def assert_build(app, status, warning):
|
||||
app = make_app('text', srcdir=outdir)
|
||||
app.build()
|
||||
print(status.getvalue())
|
||||
print(warning.getvalue())
|
||||
|
||||
sys.path.append(codedir)
|
||||
try:
|
||||
assert_build()
|
||||
finally:
|
||||
sys.path.remove(codedir)
|
||||
print(app._status.getvalue())
|
||||
print(app._warning.getvalue())
|
||||
|
||||
|
||||
@with_tempdir
|
||||
def test_pep_0420_enabled(tempdir):
|
||||
codedir = rootdir / 'root' / 'pep_0420'
|
||||
outdir = tempdir / 'out'
|
||||
args = ['sphinx-apidoc', '-o', outdir, '-F', codedir, "--implicit-namespaces"]
|
||||
apidoc.main(args)
|
||||
|
||||
@pytest.mark.apidoc(
|
||||
coderoot=(rootdir / 'root' / 'pep_0420'),
|
||||
options=["--implicit-namespaces"],
|
||||
)
|
||||
def test_pep_0420_enabled(make_app, apidoc):
|
||||
outdir = apidoc.outdir
|
||||
assert (outdir / 'conf.py').isfile()
|
||||
assert (outdir / 'a.b.c.rst').isfile()
|
||||
assert (outdir / 'a.b.x.rst').isfile()
|
||||
@ -66,49 +81,28 @@ def test_pep_0420_enabled(tempdir):
|
||||
assert "automodule:: a.b.x.y\n" in rst
|
||||
assert "automodule:: a.b.x\n" not in rst
|
||||
|
||||
@with_app('text', srcdir=outdir)
|
||||
def assert_build(app, status, warning):
|
||||
app = make_app('text', srcdir=outdir)
|
||||
app.build()
|
||||
print(status.getvalue())
|
||||
print(warning.getvalue())
|
||||
|
||||
sys.path.append(codedir)
|
||||
try:
|
||||
assert_build()
|
||||
finally:
|
||||
sys.path.remove(codedir)
|
||||
print(app._status.getvalue())
|
||||
print(app._warning.getvalue())
|
||||
|
||||
|
||||
@with_tempdir
|
||||
def test_pep_0420_disabled(tempdir):
|
||||
codedir = rootdir / 'root' / 'pep_0420'
|
||||
outdir = tempdir / 'out'
|
||||
args = ['sphinx-apidoc', '-o', outdir, '-F', codedir]
|
||||
apidoc.main(args)
|
||||
|
||||
@pytest.mark.apidoc(coderoot=(rootdir / 'root' / 'pep_0420'))
|
||||
def test_pep_0420_disabled(make_app, apidoc):
|
||||
outdir = apidoc.outdir
|
||||
assert (outdir / 'conf.py').isfile()
|
||||
assert not (outdir / 'a.b.c.rst').exists()
|
||||
assert not (outdir / 'a.b.x.rst').exists()
|
||||
|
||||
@with_app('text', srcdir=outdir)
|
||||
def assert_build(app, status, warning):
|
||||
app = make_app('text', srcdir=outdir)
|
||||
app.build()
|
||||
print(status.getvalue())
|
||||
print(warning.getvalue())
|
||||
print(app._status.getvalue())
|
||||
print(app._warning.getvalue())
|
||||
|
||||
sys.path.append(codedir)
|
||||
try:
|
||||
assert_build()
|
||||
finally:
|
||||
sys.path.remove(codedir)
|
||||
|
||||
@with_tempdir
|
||||
def test_pep_0420_disabled_top_level_verify(tempdir):
|
||||
codedir = rootdir / 'root' / 'pep_0420' / 'a' / 'b'
|
||||
outdir = tempdir / 'out'
|
||||
args = ['sphinx-apidoc', '-o', outdir, '-F', codedir]
|
||||
apidoc.main(args)
|
||||
|
||||
@pytest.mark.apidoc(coderoot=(rootdir / 'root' / 'pep_0420' / 'a' / 'b'))
|
||||
def test_pep_0420_disabled_top_level_verify(make_app, apidoc):
|
||||
outdir = apidoc.outdir
|
||||
assert (outdir / 'conf.py').isfile()
|
||||
assert (outdir / 'c.rst').isfile()
|
||||
assert not (outdir / 'x.rst').exists()
|
||||
@ -119,53 +113,35 @@ def test_pep_0420_disabled_top_level_verify(tempdir):
|
||||
assert "automodule:: c.d\n" in rst
|
||||
assert "automodule:: c\n" in rst
|
||||
|
||||
@with_app('text', srcdir=outdir)
|
||||
def assert_build(app, status, warning):
|
||||
app = make_app('text', srcdir=outdir)
|
||||
app.build()
|
||||
print(status.getvalue())
|
||||
print(warning.getvalue())
|
||||
print(app._status.getvalue())
|
||||
print(app._warning.getvalue())
|
||||
|
||||
sys.path.append(codedir)
|
||||
try:
|
||||
assert_build()
|
||||
finally:
|
||||
sys.path.remove(codedir)
|
||||
|
||||
@with_tempdir
|
||||
def test_multibyte_parameters(tempdir):
|
||||
codedir = rootdir / 'root'
|
||||
outdir = tempdir / 'out'
|
||||
args = ['sphinx-apidoc', '-o', outdir, '-F', codedir,
|
||||
@pytest.mark.apidoc(
|
||||
coderoot=(rootdir / 'root'),
|
||||
options=[
|
||||
'--doc-project', u'プロジェクト名'.encode('utf-8'),
|
||||
'--doc-author', u'著者名'.encode('utf-8'),
|
||||
'--doc-version', u'バージョン'.encode('utf-8'),
|
||||
'--doc-release', u'リリース'.encode('utf-8')]
|
||||
apidoc.main(args)
|
||||
|
||||
'--doc-release', u'リリース'.encode('utf-8'),
|
||||
],
|
||||
)
|
||||
def test_multibyte_parameters(make_app, apidoc):
|
||||
outdir = apidoc.outdir
|
||||
assert (outdir / 'conf.py').isfile()
|
||||
assert (outdir / 'autodoc_fodder.rst').isfile()
|
||||
assert (outdir / 'index.rst').isfile()
|
||||
|
||||
conf_py = (outdir / 'conf.py').text()
|
||||
if PY2:
|
||||
assert u"project = u'プロジェクト名'" in conf_py
|
||||
assert u"author = u'著者名'" in conf_py
|
||||
assert u"version = u'バージョン'" in conf_py
|
||||
assert u"release = u'リリース'" in conf_py
|
||||
else:
|
||||
assert u"project = 'プロジェクト名'" in conf_py
|
||||
assert u"author = '著者名'" in conf_py
|
||||
assert u"version = 'バージョン'" in conf_py
|
||||
assert u"release = 'リリース'" in conf_py
|
||||
conf_py_ = remove_unicode_literals(conf_py)
|
||||
assert u"project = 'プロジェクト名'" in conf_py_
|
||||
assert u"author = '著者名'" in conf_py_
|
||||
assert u"version = 'バージョン'" in conf_py_
|
||||
assert u"release = 'リリース'" in conf_py_
|
||||
|
||||
@with_app('text', srcdir=outdir)
|
||||
def assert_build(app, status, warning):
|
||||
app = make_app('text', srcdir=outdir)
|
||||
app.build()
|
||||
print(status.getvalue())
|
||||
print(warning.getvalue())
|
||||
|
||||
sys.path.append(codedir)
|
||||
try:
|
||||
assert_build()
|
||||
finally:
|
||||
sys.path.remove(codedir)
|
||||
print(app._status.getvalue())
|
||||
print(app._warning.getvalue())
|
||||
|
@ -8,25 +8,28 @@
|
||||
:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
import codecs
|
||||
|
||||
from docutils import nodes
|
||||
|
||||
from sphinx.application import ExtensionError
|
||||
from sphinx.domains import Domain
|
||||
|
||||
from util import with_app, raises_msg, strip_escseq
|
||||
from util import strip_escseq
|
||||
import pytest
|
||||
|
||||
|
||||
@with_app()
|
||||
def test_events(app, status, warning):
|
||||
def empty():
|
||||
pass
|
||||
raises_msg(ExtensionError, "Unknown event name: invalid",
|
||||
app.connect, "invalid", empty)
|
||||
with pytest.raises(ExtensionError) as excinfo:
|
||||
app.connect("invalid", empty)
|
||||
assert "Unknown event name: invalid" in str(excinfo.value)
|
||||
|
||||
app.add_event("my_event")
|
||||
raises_msg(ExtensionError, "Event 'my_event' already present",
|
||||
app.add_event, "my_event")
|
||||
with pytest.raises(ExtensionError) as excinfo:
|
||||
app.add_event("my_event")
|
||||
assert "Event 'my_event' already present" in str(excinfo.value)
|
||||
|
||||
def mock_callback(a_app, *args):
|
||||
assert a_app is app
|
||||
@ -41,26 +44,22 @@ def test_events(app, status, warning):
|
||||
"Callback called when disconnected"
|
||||
|
||||
|
||||
@with_app()
|
||||
def test_emit_with_nonascii_name_node(app, status, warning):
|
||||
node = nodes.section(names=[u'\u65e5\u672c\u8a9e'])
|
||||
app.emit('my_event', node)
|
||||
|
||||
|
||||
@with_app()
|
||||
def test_extensions(app, status, warning):
|
||||
app.setup_extension('shutil')
|
||||
assert strip_escseq(warning.getvalue()).startswith("WARNING: extension 'shutil'")
|
||||
|
||||
|
||||
@with_app()
|
||||
def test_extension_in_blacklist(app, status, warning):
|
||||
app.setup_extension('sphinxjp.themecore')
|
||||
msg = strip_escseq(warning.getvalue())
|
||||
assert msg.startswith("WARNING: the extension 'sphinxjp.themecore' was")
|
||||
|
||||
|
||||
@with_app()
|
||||
def test_domain_override(app, status, warning):
|
||||
class A(Domain):
|
||||
name = 'foo'
|
||||
@ -72,15 +71,18 @@ def test_domain_override(app, status, warning):
|
||||
name = 'foo'
|
||||
|
||||
# No domain know named foo.
|
||||
raises_msg(ExtensionError, 'domain foo not yet registered',
|
||||
app.override_domain, A)
|
||||
with pytest.raises(ExtensionError) as excinfo:
|
||||
app.override_domain(A)
|
||||
assert 'domain foo not yet registered' in str(excinfo.value)
|
||||
|
||||
assert app.add_domain(A) is None
|
||||
assert app.override_domain(B) is None
|
||||
raises_msg(ExtensionError, 'new domain not a subclass of registered '
|
||||
'foo domain', app.override_domain, C)
|
||||
with pytest.raises(ExtensionError) as excinfo:
|
||||
app.override_domain(C)
|
||||
assert 'new domain not a subclass of registered foo domain' in str(excinfo.value)
|
||||
|
||||
|
||||
@with_app(testroot='add_source_parser')
|
||||
@pytest.mark.sphinx(testroot='add_source_parser')
|
||||
def test_add_source_parser(app, status, warning):
|
||||
assert set(app.config.source_suffix) == set(['.rst', '.md', '.test'])
|
||||
assert set(app.config.source_parsers.keys()) == set(['.md', '.test'])
|
||||
@ -88,7 +90,7 @@ def test_add_source_parser(app, status, warning):
|
||||
assert app.config.source_parsers['.test'].__name__ == 'TestSourceParser'
|
||||
|
||||
|
||||
@with_app(testroot='add_source_parser-conflicts-with-users-setting')
|
||||
@pytest.mark.sphinx(testroot='add_source_parser-conflicts-with-users-setting')
|
||||
def test_add_source_parser_conflicts_with_users_setting(app, status, warning):
|
||||
assert set(app.config.source_suffix) == set(['.rst', '.test'])
|
||||
assert set(app.config.source_parsers.keys()) == set(['.test'])
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
# "raises" imported for usage by autodoc
|
||||
from util import TestApp, Struct, raises, SkipTest # NOQA
|
||||
from nose.tools import with_setup, eq_
|
||||
import pytest
|
||||
|
||||
import enum
|
||||
from six import StringIO, add_metaclass
|
||||
@ -41,6 +41,7 @@ def teardown_module():
|
||||
directive = options = None
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def setup_test():
|
||||
global options, directive
|
||||
global processed_docstrings, processed_signatures, _warnings
|
||||
@ -74,6 +75,10 @@ def setup_test():
|
||||
processed_signatures = []
|
||||
_warnings = []
|
||||
|
||||
yield
|
||||
|
||||
AutoDirective._special_attrgetters.clear()
|
||||
|
||||
|
||||
_warnings = []
|
||||
processed_docstrings = []
|
||||
@ -105,7 +110,7 @@ def skip_member(app, what, name, obj, skip, options):
|
||||
return True
|
||||
|
||||
|
||||
@with_setup(setup_test)
|
||||
@pytest.mark.usefixtures('setup_test')
|
||||
def test_parse_name():
|
||||
def verify(objtype, name, result):
|
||||
inst = AutoDirective._registry[objtype](directive, name)
|
||||
@ -147,7 +152,7 @@ def test_parse_name():
|
||||
del directive.env.temp_data['autodoc:class']
|
||||
|
||||
|
||||
@with_setup(setup_test)
|
||||
@pytest.mark.usefixtures('setup_test')
|
||||
def test_format_signature():
|
||||
def formatsig(objtype, name, obj, args, retann):
|
||||
inst = AutoDirective._registry[objtype](directive, name)
|
||||
@ -253,7 +258,7 @@ def test_format_signature():
|
||||
'(b, c=42, *d, **e)'
|
||||
|
||||
|
||||
@with_setup(setup_test)
|
||||
@pytest.mark.usefixtures('setup_test')
|
||||
def test_get_doc():
|
||||
def getdocl(objtype, obj, encoding=None):
|
||||
inst = AutoDirective._registry[objtype](directive, 'tmp')
|
||||
@ -423,7 +428,7 @@ def test_get_doc():
|
||||
assert getdocl('class', I) == ['Class docstring', '', 'New docstring']
|
||||
|
||||
|
||||
@with_setup(setup_test)
|
||||
@pytest.mark.usefixtures('setup_test')
|
||||
def test_docstring_processing():
|
||||
def process(objtype, name, obj):
|
||||
inst = AutoDirective._registry[objtype](directive, name)
|
||||
@ -478,7 +483,7 @@ def test_docstring_processing():
|
||||
app.disconnect(lid)
|
||||
|
||||
|
||||
@with_setup(setup_test)
|
||||
@pytest.mark.usefixtures('setup_test')
|
||||
def test_docstring_property_processing():
|
||||
def genarate_docstring(objtype, name, **kw):
|
||||
del processed_docstrings[:]
|
||||
@ -515,7 +520,7 @@ def test_docstring_property_processing():
|
||||
assert 'Second line of docstring' in docstrings
|
||||
|
||||
|
||||
@with_setup(setup_test)
|
||||
@pytest.mark.usefixtures('setup_test')
|
||||
def test_new_documenter():
|
||||
class MyDocumenter(ModuleLevelDocumenter):
|
||||
objtype = 'integer'
|
||||
@ -543,7 +548,7 @@ def test_new_documenter():
|
||||
assert_result_contains('.. py:data:: integer', 'module', 'test_autodoc')
|
||||
|
||||
|
||||
@with_setup(setup_test, AutoDirective._special_attrgetters.clear)
|
||||
@pytest.mark.usefixtures('setup_test')
|
||||
def test_attrgetter_using():
|
||||
def assert_getter_works(objtype, name, obj, attrs=[], **kw):
|
||||
getattr_spy = []
|
||||
@ -575,7 +580,7 @@ def test_attrgetter_using():
|
||||
assert_getter_works('class', 'test_autodoc.Class', Class, ['meth', 'inheritedmeth'])
|
||||
|
||||
|
||||
@with_setup(setup_test)
|
||||
@pytest.mark.usefixtures('setup_test')
|
||||
def test_generate():
|
||||
def assert_warns(warn_str, objtype, name, **kw):
|
||||
inst = AutoDirective._registry[objtype](directive, name)
|
||||
@ -1084,7 +1089,7 @@ def test_type_hints():
|
||||
raise SkipTest('Cannot import Python code with function annotations')
|
||||
|
||||
def verify_arg_spec(f, expected):
|
||||
eq_(formatargspec(f, *getargspec(f)), expected)
|
||||
assert formatargspec(f, *getargspec(f)) == expected
|
||||
|
||||
# Class annotations
|
||||
verify_arg_spec(f0, '(x: int, y: numbers.Integral) -> None')
|
||||
|
@ -9,16 +9,15 @@
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
from six import BytesIO
|
||||
|
||||
import pickle
|
||||
from docutils import nodes
|
||||
import mock
|
||||
import pytest
|
||||
from textwrap import dedent
|
||||
from sphinx.errors import SphinxError
|
||||
import sphinx.builders.linkcheck
|
||||
|
||||
from util import with_app, with_tempdir, rootdir, tempdir, SkipTest, TestApp, path
|
||||
from util import rootdir, tempdir, SkipTest, TestApp, path
|
||||
|
||||
try:
|
||||
from docutils.writers.manpage import Writer as ManWriter
|
||||
@ -77,13 +76,12 @@ def test_build_all():
|
||||
yield verify_build, buildername, srcdir
|
||||
|
||||
|
||||
@with_tempdir
|
||||
def test_master_doc_not_found(tmpdir):
|
||||
(tmpdir / 'conf.py').write_text('master_doc = "index"')
|
||||
assert tmpdir.listdir() == ['conf.py']
|
||||
def test_master_doc_not_found(tempdir):
|
||||
(tempdir / 'conf.py').write_text('master_doc = "index"')
|
||||
assert tempdir.listdir() == ['conf.py']
|
||||
|
||||
try:
|
||||
app = TestApp(buildername='dummy', srcdir=tmpdir)
|
||||
app = TestApp(buildername='dummy', srcdir=tempdir)
|
||||
app.builder.build_all()
|
||||
assert False # SphinxError not raised
|
||||
except Exception as exc:
|
||||
@ -92,7 +90,7 @@ def test_master_doc_not_found(tmpdir):
|
||||
app.cleanup()
|
||||
|
||||
|
||||
@with_app(buildername='text', testroot='circular')
|
||||
@pytest.mark.sphinx(buildername='text', testroot='circular')
|
||||
def test_circular_toctree(app, status, warning):
|
||||
app.builder.build_all()
|
||||
warnings = warning.getvalue()
|
||||
@ -104,7 +102,7 @@ def test_circular_toctree(app, status, warning):
|
||||
'contents <- sub <- contents') in warnings
|
||||
|
||||
|
||||
@with_app(buildername='text', testroot='numbered-circular')
|
||||
@pytest.mark.sphinx(buildername='text', testroot='numbered-circular')
|
||||
def test_numbered_circular_toctree(app, status, warning):
|
||||
app.builder.build_all()
|
||||
warnings = warning.getvalue()
|
||||
@ -116,7 +114,7 @@ def test_numbered_circular_toctree(app, status, warning):
|
||||
'contents <- sub <- contents') in warnings
|
||||
|
||||
|
||||
@with_app(buildername='dummy', testroot='image-glob')
|
||||
@pytest.mark.sphinx(buildername='dummy', testroot='image-glob')
|
||||
def test_image_glob(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
import plistlib
|
||||
|
||||
from util import with_app
|
||||
import pytest
|
||||
from path import path
|
||||
|
||||
# Use plistlib.load in 3.4 and above
|
||||
@ -43,7 +43,8 @@ def check_localization(outdir):
|
||||
assert (lprojdir / 'localized.txt').isfile()
|
||||
|
||||
|
||||
@with_app(buildername='applehelp', testroot='basic', srcdir='applehelp_output',
|
||||
@pytest.mark.sphinx(
|
||||
'applehelp', testroot='basic', srcdir='applehelp_output',
|
||||
confoverrides={'applehelp_bundle_id': 'org.sphinx-doc.Sphinx.help',
|
||||
'applehelp_disable_external_tools': True})
|
||||
def test_applehelp_output(app, status, warning):
|
||||
|
@ -15,9 +15,11 @@ import re
|
||||
import gettext
|
||||
from subprocess import Popen, PIPE
|
||||
|
||||
from nose.tools import assert_true, assert_equal
|
||||
import pytest
|
||||
|
||||
from util import with_app, gen_with_app, SkipTest, assert_in
|
||||
from util import (
|
||||
gen_with_app, SkipTest, assert_in, assert_true, assert_equal
|
||||
)
|
||||
|
||||
|
||||
@gen_with_app('gettext', srcdir='root-gettext')
|
||||
@ -76,7 +78,8 @@ def test_all(app, status, warning):
|
||||
yield assert_equal, _("Testing various markup"), u"Testing various markup"
|
||||
|
||||
|
||||
@with_app('gettext', testroot='intl',
|
||||
@pytest.mark.sphinx(
|
||||
'gettext', testroot='intl', srcdir='gettext',
|
||||
confoverrides={'gettext_compact': False})
|
||||
def test_gettext_index_entries(app, status, warning):
|
||||
# regression test for #976
|
||||
@ -123,7 +126,8 @@ def test_gettext_index_entries(app, status, warning):
|
||||
assert msgids == []
|
||||
|
||||
|
||||
@with_app('gettext', testroot='intl',
|
||||
@pytest.mark.sphinx(
|
||||
'gettext', testroot='intl', srcdir='gettext',
|
||||
confoverrides={'gettext_compact': False, 'gettext_additional_targets': []})
|
||||
def test_gettext_disable_index_entries(app, status, warning):
|
||||
# regression test for #976
|
||||
@ -155,7 +159,7 @@ def test_gettext_disable_index_entries(app, status, warning):
|
||||
assert msgids == []
|
||||
|
||||
|
||||
@with_app(buildername='gettext', testroot='intl')
|
||||
@pytest.mark.sphinx('gettext', testroot='intl', srcdir='gettext')
|
||||
def test_gettext_template(app, status, warning):
|
||||
app.builder.build_all()
|
||||
assert (app.outdir / 'sphinx.pot').isfile()
|
||||
|
@ -15,19 +15,17 @@ import re
|
||||
from six import PY3, iteritems
|
||||
|
||||
from sphinx import __display_version__
|
||||
from util import remove_unicode_literals, gen_with_app, with_app, strip_escseq
|
||||
from util import remove_unicode_literals, gen_with_app, strip_escseq
|
||||
from etree13 import ElementTree
|
||||
from html5lib import getTreeBuilder, HTMLParser
|
||||
import pytest
|
||||
|
||||
|
||||
TREE_BUILDER = getTreeBuilder('etree', implementation=ElementTree)
|
||||
HTML_PARSER = HTMLParser(TREE_BUILDER, namespaceHTMLElements=False)
|
||||
|
||||
ENV_WARNINGS = """\
|
||||
(%(root)s/autodoc_fodder.py:docstring of autodoc_fodder.MarkupError:\\d+: \
|
||||
WARNING: duplicate object description of autodoc_fodder.MarkupError, other \
|
||||
instance in %(root)s/autodoc.rst, use :noindex: for one of them
|
||||
)?%(root)s/autodoc_fodder.py:docstring of autodoc_fodder.MarkupError:\\d+: \
|
||||
%(root)s/autodoc_fodder.py:docstring of autodoc_fodder.MarkupError:\\d+: \
|
||||
WARNING: Explicit markup ends without a blank line; unexpected unindent.
|
||||
%(root)s/index.rst:\\d+: WARNING: Encoding 'utf-8-sig' used for reading included \
|
||||
file u'%(root)s/wrongenc.inc' seems to be wrong, try giving an :encoding: option
|
||||
@ -36,7 +34,7 @@ file u'%(root)s/wrongenc.inc' seems to be wrong, try giving an :encoding: option
|
||||
%(root)s/index.rst:\\d+: WARNING: download file not readable: %(root)s/nonexisting.png
|
||||
%(root)s/index.rst:\\d+: WARNING: invalid single index entry u''
|
||||
%(root)s/undecodable.rst:\\d+: WARNING: undecodable source characters, replacing \
|
||||
with "\\?": b?'here: >>>(\\\\|/)xbb<<<'
|
||||
with "\\?": b?'here: >>>(\\\\|/)xbb<<<((\\\\|/)r)?'
|
||||
"""
|
||||
|
||||
HTML_WARNINGS = ENV_WARNINGS + """\
|
||||
@ -387,7 +385,7 @@ def check_extra_entries(outdir):
|
||||
assert (outdir / 'robots.txt').isfile()
|
||||
|
||||
|
||||
@with_app(buildername='html', testroot='warnings', freshenv=True)
|
||||
@pytest.mark.sphinx('html', testroot='warnings', freshenv=True)
|
||||
def test_html_warnings(app, status, warning):
|
||||
app.builder.build_all()
|
||||
html_warnings = strip_escseq(warning.getvalue().replace(os.sep, '/'))
|
||||
@ -662,7 +660,7 @@ def test_numfig_without_numbered_toctree(app, status, warning):
|
||||
yield check_xpath, etree, fname, xpath, check, be_found
|
||||
|
||||
|
||||
@gen_with_app(buildername='html', testroot='numfig',
|
||||
@gen_with_app(buildername='html', testroot='numfig', srcdir='test_build_html_numfig_on',
|
||||
confoverrides={'numfig': True})
|
||||
def test_numfig_with_numbered_toctree(app, status, warning):
|
||||
app.builder.build_all()
|
||||
@ -763,6 +761,7 @@ def test_numfig_with_numbered_toctree(app, status, warning):
|
||||
|
||||
|
||||
@gen_with_app(buildername='html', testroot='numfig',
|
||||
srcdir='test_build_html_numfig_format_warn',
|
||||
confoverrides={'numfig': True,
|
||||
'numfig_format': {'figure': 'Figure:%s',
|
||||
'table': 'Tab_%s',
|
||||
@ -867,6 +866,7 @@ def test_numfig_with_prefix(app, status, warning):
|
||||
|
||||
|
||||
@gen_with_app(buildername='html', testroot='numfig',
|
||||
srcdir='test_build_html_numfig_depth_2',
|
||||
confoverrides={'numfig': True, 'numfig_secnum_depth': 2})
|
||||
def test_numfig_with_secnum_depth(app, status, warning):
|
||||
app.builder.build_all()
|
||||
@ -967,6 +967,7 @@ def test_numfig_with_secnum_depth(app, status, warning):
|
||||
|
||||
|
||||
@gen_with_app(buildername='singlehtml', testroot='numfig',
|
||||
srcdir='test_build_html_numfig_on',
|
||||
confoverrides={'numfig': True})
|
||||
def test_numfig_with_singlehtml(app, status, warning):
|
||||
app.builder.build_all()
|
||||
@ -1084,7 +1085,7 @@ def test_enumerable_node(app, status, warning):
|
||||
yield check_xpath, etree, fname, xpath, check, be_found
|
||||
|
||||
|
||||
@with_app(buildername='html', testroot='html_assets')
|
||||
@pytest.mark.sphinx('html', testroot='html_assets')
|
||||
def test_html_assets(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
||||
@ -1112,7 +1113,7 @@ def test_html_assets(app, status, warning):
|
||||
assert not (app.outdir / 'subdir' / '.htpasswd').exists()
|
||||
|
||||
|
||||
@with_app(buildername='html', confoverrides={'html_sourcelink_suffix': ''})
|
||||
@pytest.mark.sphinx('html', confoverrides={'html_sourcelink_suffix': ''})
|
||||
def test_html_sourcelink_suffix(app, status, warning):
|
||||
app.builder.build_all()
|
||||
content_otherext = (app.outdir / 'otherext.html').text()
|
||||
|
@ -12,17 +12,17 @@ from __future__ import print_function
|
||||
|
||||
import os
|
||||
import re
|
||||
from functools import wraps
|
||||
from itertools import product
|
||||
from subprocess import Popen, PIPE
|
||||
|
||||
from six import PY3
|
||||
import pytest
|
||||
|
||||
from sphinx.errors import SphinxError
|
||||
from sphinx.util.osutil import cd, ensuredir
|
||||
from sphinx.writers.latex import LaTeXTranslator
|
||||
|
||||
from util import SkipTest, remove_unicode_literals, with_app, strip_escseq, skip_if
|
||||
from util import SkipTest, remove_unicode_literals, strip_escseq, skip_if
|
||||
from test_build_html import ENV_WARNINGS
|
||||
|
||||
|
||||
@ -90,14 +90,13 @@ def skip_if_stylefiles_notfound(testfunc):
|
||||
return testfunc
|
||||
|
||||
|
||||
def test_latex():
|
||||
for engine, docclass in product(LATEX_ENGINES, DOCCLASSES):
|
||||
yield build_latex_doc, engine, docclass
|
||||
|
||||
|
||||
@skip_if_stylefiles_notfound
|
||||
@with_app(buildername='latex')
|
||||
def build_latex_doc(app, status, warning, engine, docclass):
|
||||
@pytest.mark.parametrize(
|
||||
"engine,docclass",
|
||||
product(LATEX_ENGINES, DOCCLASSES),
|
||||
)
|
||||
@pytest.mark.sphinx('latex')
|
||||
def test_build_latex_doc(app, status, warning, engine, docclass):
|
||||
app.config.latex_engine = engine
|
||||
app.config.latex_documents[0] = app.config.latex_documents[0][:4] + (docclass,)
|
||||
|
||||
@ -110,7 +109,7 @@ def build_latex_doc(app, status, warning, engine, docclass):
|
||||
compile_latex_document(app)
|
||||
|
||||
|
||||
@with_app(buildername='latex')
|
||||
@pytest.mark.sphinx('latex')
|
||||
def test_writer(app, status, warning):
|
||||
app.builder.build_all()
|
||||
result = (app.outdir / 'SphinxTests.tex').text(encoding='utf8')
|
||||
@ -138,7 +137,7 @@ def test_writer(app, status, warning):
|
||||
'\\end{wrapfigure}' in result)
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='warnings', freshenv=True)
|
||||
@pytest.mark.sphinx('latex', testroot='warnings', freshenv=True)
|
||||
def test_latex_warnings(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
||||
@ -151,7 +150,7 @@ def test_latex_warnings(app, status, warning):
|
||||
'--- Got:\n' + warnings
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='basic')
|
||||
@pytest.mark.sphinx('latex', testroot='basic')
|
||||
def test_latex_title(app, status, warning):
|
||||
app.builder.build_all()
|
||||
result = (app.outdir / 'test.tex').text(encoding='utf8')
|
||||
@ -161,7 +160,7 @@ def test_latex_title(app, status, warning):
|
||||
assert '\\title{The basic Sphinx documentation for testing}' in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='latex-title')
|
||||
@pytest.mark.sphinx('latex', testroot='latex-title')
|
||||
def test_latex_title_after_admonitions(app, status, warning):
|
||||
app.builder.build_all()
|
||||
result = (app.outdir / 'test.tex').text(encoding='utf8')
|
||||
@ -171,7 +170,7 @@ def test_latex_title_after_admonitions(app, status, warning):
|
||||
assert '\\title{test-latex-title}' in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='numfig',
|
||||
@pytest.mark.sphinx('latex', testroot='numfig',
|
||||
confoverrides={'numfig': True})
|
||||
def test_numref(app, status, warning):
|
||||
app.builder.build_all()
|
||||
@ -204,7 +203,8 @@ def test_numref(app, status, warning):
|
||||
'\\nameref{\\detokenize{foo:foo}}}') in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='numfig',
|
||||
@pytest.mark.sphinx(
|
||||
'latex', testroot='numfig',
|
||||
confoverrides={'numfig': True,
|
||||
'numfig_format': {'figure': 'Figure:%s',
|
||||
'table': 'Tab_%s',
|
||||
@ -247,7 +247,8 @@ def test_numref_with_prefix1(app, status, warning):
|
||||
'\\nameref{\\detokenize{foo:foo}}}') in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='numfig',
|
||||
@pytest.mark.sphinx(
|
||||
'latex', testroot='numfig',
|
||||
confoverrides={'numfig': True,
|
||||
'numfig_format': {'figure': 'Figure:%s.',
|
||||
'table': 'Tab_%s:',
|
||||
@ -286,7 +287,8 @@ def test_numref_with_prefix2(app, status, warning):
|
||||
'\\nameref{\\detokenize{foo:foo}}}') in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='numfig',
|
||||
@pytest.mark.sphinx(
|
||||
'latex', testroot='numfig',
|
||||
confoverrides={'numfig': True, 'language': 'ja'})
|
||||
def test_numref_with_language_ja(app, status, warning):
|
||||
app.builder.build_all()
|
||||
@ -319,7 +321,7 @@ def test_numref_with_language_ja(app, status, warning):
|
||||
'\\nameref{\\detokenize{foo:foo}}}') in result
|
||||
|
||||
|
||||
@with_app(buildername='latex')
|
||||
@pytest.mark.sphinx('latex')
|
||||
def test_latex_add_latex_package(app, status, warning):
|
||||
app.add_latex_package('foo')
|
||||
app.add_latex_package('bar', 'baz')
|
||||
@ -329,7 +331,7 @@ def test_latex_add_latex_package(app, status, warning):
|
||||
assert '\\usepackage[baz]{bar}' in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='latex-babel')
|
||||
@pytest.mark.sphinx('latex', testroot='latex-babel')
|
||||
def test_babel_with_no_language_settings(app, status, warning):
|
||||
app.builder.build_all()
|
||||
result = (app.outdir / 'Python.tex').text(encoding='utf8')
|
||||
@ -348,7 +350,8 @@ def test_babel_with_no_language_settings(app, status, warning):
|
||||
assert '\\shorthandoff' not in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='latex-babel',
|
||||
@pytest.mark.sphinx(
|
||||
'latex', testroot='latex-babel',
|
||||
confoverrides={'language': 'de'})
|
||||
def test_babel_with_language_de(app, status, warning):
|
||||
app.builder.build_all()
|
||||
@ -368,7 +371,8 @@ def test_babel_with_language_de(app, status, warning):
|
||||
assert '\\shorthandoff{"}' in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='latex-babel',
|
||||
@pytest.mark.sphinx(
|
||||
'latex', testroot='latex-babel',
|
||||
confoverrides={'language': 'ru'})
|
||||
def test_babel_with_language_ru(app, status, warning):
|
||||
app.builder.build_all()
|
||||
@ -389,7 +393,8 @@ def test_babel_with_language_ru(app, status, warning):
|
||||
assert '\\shorthandoff' not in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='latex-babel',
|
||||
@pytest.mark.sphinx(
|
||||
'latex', testroot='latex-babel',
|
||||
confoverrides={'language': 'tr'})
|
||||
def test_babel_with_language_tr(app, status, warning):
|
||||
app.builder.build_all()
|
||||
@ -409,7 +414,8 @@ def test_babel_with_language_tr(app, status, warning):
|
||||
assert '\\shorthandoff{=}' in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='latex-babel',
|
||||
@pytest.mark.sphinx(
|
||||
'latex', testroot='latex-babel',
|
||||
confoverrides={'language': 'ja'})
|
||||
def test_babel_with_language_ja(app, status, warning):
|
||||
app.builder.build_all()
|
||||
@ -428,7 +434,8 @@ def test_babel_with_language_ja(app, status, warning):
|
||||
assert '\\shorthandoff' not in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='latex-babel',
|
||||
@pytest.mark.sphinx(
|
||||
'latex', testroot='latex-babel',
|
||||
confoverrides={'language': 'unknown'})
|
||||
def test_babel_with_unknown_language(app, status, warning):
|
||||
app.builder.build_all()
|
||||
@ -450,7 +457,7 @@ def test_babel_with_unknown_language(app, status, warning):
|
||||
assert "WARNING: no Babel option known for language 'unknown'" in warning.getvalue()
|
||||
|
||||
|
||||
@with_app(buildername='latex')
|
||||
@pytest.mark.sphinx('latex')
|
||||
def test_footnote(app, status, warning):
|
||||
app.builder.build_all()
|
||||
result = (app.outdir / 'SphinxTests.tex').text(encoding='utf8')
|
||||
@ -480,7 +487,7 @@ def test_footnote(app, status, warning):
|
||||
'footnotes in table\n%\n\\end{footnotetext}') in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='footnotes')
|
||||
@pytest.mark.sphinx('latex', testroot='footnotes')
|
||||
def test_reference_in_caption_and_codeblock_in_footnote(app, status, warning):
|
||||
app.builder.build_all()
|
||||
result = (app.outdir / 'Python.tex').text(encoding='utf8')
|
||||
@ -517,7 +524,8 @@ def test_reference_in_caption_and_codeblock_in_footnote(app, status, warning):
|
||||
assert '\\begin{sphinxVerbatim}[commandchars=\\\\\\{\\}]' in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='footnotes',
|
||||
@pytest.mark.sphinx(
|
||||
'latex', testroot='footnotes',
|
||||
confoverrides={'latex_show_urls': 'inline'})
|
||||
def test_latex_show_urls_is_inline(app, status, warning):
|
||||
app.builder.build_all()
|
||||
@ -560,7 +568,8 @@ def test_latex_show_urls_is_inline(app, status, warning):
|
||||
'{sphinx-dev@googlegroups.com}') in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='footnotes',
|
||||
@pytest.mark.sphinx(
|
||||
'latex', testroot='footnotes',
|
||||
confoverrides={'latex_show_urls': 'footnote'})
|
||||
def test_latex_show_urls_is_footnote(app, status, warning):
|
||||
app.builder.build_all()
|
||||
@ -611,7 +620,8 @@ def test_latex_show_urls_is_footnote(app, status, warning):
|
||||
'{sphinx-dev@googlegroups.com}\n') in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='footnotes',
|
||||
@pytest.mark.sphinx(
|
||||
'latex', testroot='footnotes',
|
||||
confoverrides={'latex_show_urls': 'no'})
|
||||
def test_latex_show_urls_is_no(app, status, warning):
|
||||
app.builder.build_all()
|
||||
@ -652,7 +662,7 @@ def test_latex_show_urls_is_no(app, status, warning):
|
||||
'{sphinx-dev@googlegroups.com}\n') in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='image-in-section')
|
||||
@pytest.mark.sphinx('latex', testroot='image-in-section')
|
||||
def test_image_in_section(app, status, warning):
|
||||
app.builder.build_all()
|
||||
result = (app.outdir / 'Python.tex').text(encoding='utf8')
|
||||
@ -668,7 +678,7 @@ def test_image_in_section(app, status, warning):
|
||||
assert ('\\chapter{Another section}' in result)
|
||||
|
||||
|
||||
@with_app(buildername='latex', confoverrides={'latex_logo': 'notfound.jpg'})
|
||||
@pytest.mark.sphinx('latex', confoverrides={'latex_logo': 'notfound.jpg'})
|
||||
def test_latex_logo_if_not_found(app, status, warning):
|
||||
try:
|
||||
app.builder.build_all()
|
||||
@ -677,7 +687,7 @@ def test_latex_logo_if_not_found(app, status, warning):
|
||||
assert isinstance(exc, SphinxError)
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='toctree-maxdepth',
|
||||
@pytest.mark.sphinx('latex', testroot='toctree-maxdepth',
|
||||
confoverrides={'latex_documents': [
|
||||
('index', 'SphinxTests.tex', 'Sphinx Tests Documentation',
|
||||
'Georg Brandl', 'manual'),
|
||||
@ -692,7 +702,8 @@ def test_toctree_maxdepth_manual(app, status, warning):
|
||||
assert '\\setcounter{secnumdepth}' not in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='toctree-maxdepth',
|
||||
@pytest.mark.sphinx(
|
||||
'latex', testroot='toctree-maxdepth',
|
||||
confoverrides={'latex_documents': [
|
||||
('index', 'SphinxTests.tex', 'Sphinx Tests Documentation',
|
||||
'Georg Brandl', 'howto'),
|
||||
@ -707,7 +718,8 @@ def test_toctree_maxdepth_howto(app, status, warning):
|
||||
assert '\\setcounter{secnumdepth}' not in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='toctree-maxdepth',
|
||||
@pytest.mark.sphinx(
|
||||
'latex', testroot='toctree-maxdepth',
|
||||
confoverrides={'master_doc': 'foo'})
|
||||
def test_toctree_not_found(app, status, warning):
|
||||
app.builder.build_all()
|
||||
@ -719,7 +731,8 @@ def test_toctree_not_found(app, status, warning):
|
||||
assert '\\setcounter{secnumdepth}' not in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='toctree-maxdepth',
|
||||
@pytest.mark.sphinx(
|
||||
'latex', testroot='toctree-maxdepth',
|
||||
confoverrides={'master_doc': 'bar'})
|
||||
def test_toctree_without_maxdepth(app, status, warning):
|
||||
app.builder.build_all()
|
||||
@ -731,7 +744,8 @@ def test_toctree_without_maxdepth(app, status, warning):
|
||||
assert '\\setcounter{secnumdepth}' not in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='toctree-maxdepth',
|
||||
@pytest.mark.sphinx(
|
||||
'latex', testroot='toctree-maxdepth',
|
||||
confoverrides={'master_doc': 'qux'})
|
||||
def test_toctree_with_deeper_maxdepth(app, status, warning):
|
||||
app.builder.build_all()
|
||||
@ -743,7 +757,8 @@ def test_toctree_with_deeper_maxdepth(app, status, warning):
|
||||
assert '\\setcounter{secnumdepth}{3}' in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='toctree-maxdepth',
|
||||
@pytest.mark.sphinx(
|
||||
'latex', testroot='toctree-maxdepth',
|
||||
confoverrides={'latex_toplevel_sectioning': None})
|
||||
def test_latex_toplevel_sectioning_is_None(app, status, warning):
|
||||
app.builder.build_all()
|
||||
@ -754,7 +769,8 @@ def test_latex_toplevel_sectioning_is_None(app, status, warning):
|
||||
assert '\\chapter{Foo}' in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='toctree-maxdepth',
|
||||
@pytest.mark.sphinx(
|
||||
'latex', testroot='toctree-maxdepth',
|
||||
confoverrides={'latex_toplevel_sectioning': 'part'})
|
||||
def test_latex_toplevel_sectioning_is_part(app, status, warning):
|
||||
app.builder.build_all()
|
||||
@ -765,7 +781,8 @@ def test_latex_toplevel_sectioning_is_part(app, status, warning):
|
||||
assert '\\part{Foo}' in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='toctree-maxdepth',
|
||||
@pytest.mark.sphinx(
|
||||
'latex', testroot='toctree-maxdepth',
|
||||
confoverrides={'latex_toplevel_sectioning': 'chapter'})
|
||||
def test_latex_toplevel_sectioning_is_chapter(app, status, warning):
|
||||
app.builder.build_all()
|
||||
@ -776,7 +793,8 @@ def test_latex_toplevel_sectioning_is_chapter(app, status, warning):
|
||||
assert '\\chapter{Foo}' in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='toctree-maxdepth',
|
||||
@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()
|
||||
@ -787,7 +805,7 @@ def test_latex_toplevel_sectioning_is_section(app, status, warning):
|
||||
assert '\\section{Foo}' in result
|
||||
|
||||
@skip_if_stylefiles_notfound
|
||||
@with_app(buildername='latex', testroot='maxlistdepth')
|
||||
@pytest.mark.sphinx('latex', testroot='maxlistdepth')
|
||||
def test_maxlistdepth_at_ten(app, status, warning):
|
||||
app.builder.build_all()
|
||||
result = (app.outdir / 'SphinxTests.tex').text(encoding='utf8')
|
||||
|
@ -10,10 +10,10 @@
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
from util import with_app
|
||||
import pytest
|
||||
|
||||
|
||||
@with_app('linkcheck', testroot='linkcheck', freshenv=True)
|
||||
@pytest.mark.sphinx('linkcheck', testroot='linkcheck', freshenv=True)
|
||||
def test_defaults(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
||||
@ -26,7 +26,8 @@ def test_defaults(app, status, warning):
|
||||
assert len(content.splitlines()) == 1
|
||||
|
||||
|
||||
@with_app('linkcheck', testroot='linkcheck', freshenv=True,
|
||||
@pytest.mark.sphinx(
|
||||
'linkcheck', testroot='linkcheck', freshenv=True,
|
||||
confoverrides={'linkcheck_anchors_ignore': ["^!", "^top$"]})
|
||||
def test_anchors_ignored(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
@ -10,10 +10,10 @@
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
from util import with_app
|
||||
import pytest
|
||||
|
||||
|
||||
@with_app(buildername='man')
|
||||
@pytest.mark.sphinx('man')
|
||||
def test_all(app, status, warning):
|
||||
app.builder.build_all()
|
||||
assert (app.outdir / 'SphinxTests.1').exists()
|
||||
|
@ -15,10 +15,11 @@ import re
|
||||
from subprocess import Popen, PIPE
|
||||
|
||||
from six import PY3
|
||||
import pytest
|
||||
|
||||
from sphinx.writers.texinfo import TexinfoTranslator
|
||||
|
||||
from util import SkipTest, remove_unicode_literals, with_app, strip_escseq
|
||||
from util import SkipTest, remove_unicode_literals, strip_escseq
|
||||
from test_build_html import ENV_WARNINGS
|
||||
|
||||
|
||||
@ -33,7 +34,7 @@ if PY3:
|
||||
TEXINFO_WARNINGS = remove_unicode_literals(TEXINFO_WARNINGS)
|
||||
|
||||
|
||||
@with_app(buildername='texinfo', testroot='warnings', freshenv=True)
|
||||
@pytest.mark.sphinx('texinfo', testroot='warnings', freshenv=True)
|
||||
def test_texinfo_warnings(app, status, warning):
|
||||
app.builder.build_all()
|
||||
warnings = strip_escseq(warning.getvalue().replace(os.sep, '/'))
|
||||
@ -45,7 +46,7 @@ def test_texinfo_warnings(app, status, warning):
|
||||
'--- Got:\n' + warnings
|
||||
|
||||
|
||||
@with_app(buildername='texinfo')
|
||||
@pytest.mark.sphinx('texinfo')
|
||||
def test_texinfo(app, status, warning):
|
||||
TexinfoTranslator.ignore_missing_images = True
|
||||
app.builder.build_all()
|
||||
|
@ -10,15 +10,16 @@
|
||||
"""
|
||||
import shutil
|
||||
|
||||
from nose.tools import with_setup
|
||||
import pytest
|
||||
|
||||
from util import with_app, find_files, rootdir, tempdir
|
||||
from util import find_files, rootdir, tempdir
|
||||
|
||||
root = tempdir / 'test-intl'
|
||||
build_dir = root / '_build'
|
||||
locale_dir = build_dir / 'locale'
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def setup_test():
|
||||
# delete remnants left over after failed build
|
||||
root.rmtree(True)
|
||||
@ -30,13 +31,14 @@ def setup_test():
|
||||
copy_po.parent.makedirs()
|
||||
shutil.copy(root / po, copy_po)
|
||||
|
||||
yield
|
||||
|
||||
def teardown_test():
|
||||
build_dir.rmtree(True)
|
||||
|
||||
|
||||
@with_setup(setup_test, teardown_test)
|
||||
@with_app(buildername='html', testroot='intl',
|
||||
@pytest.mark.usefixtures('setup_test')
|
||||
@pytest.mark.sphinx(
|
||||
'html', testroot='intl',
|
||||
confoverrides={'language': 'en', 'locale_dirs': [locale_dir]})
|
||||
def test_compile_all_catalogs(app, status, warning):
|
||||
app.builder.compile_all_catalogs()
|
||||
@ -51,8 +53,9 @@ def test_compile_all_catalogs(app, status, warning):
|
||||
assert actual == expect
|
||||
|
||||
|
||||
@with_setup(setup_test, teardown_test)
|
||||
@with_app(buildername='html', testroot='intl',
|
||||
@pytest.mark.usefixtures('setup_test')
|
||||
@pytest.mark.sphinx(
|
||||
'html', testroot='intl',
|
||||
confoverrides={'language': 'en', 'locale_dirs': [locale_dir]})
|
||||
def test_compile_specific_catalogs(app, status, warning):
|
||||
catalog_dir = locale_dir / app.config.language / 'LC_MESSAGES'
|
||||
@ -66,8 +69,9 @@ def test_compile_specific_catalogs(app, status, warning):
|
||||
assert actual == set(['admonitions.mo'])
|
||||
|
||||
|
||||
@with_setup(setup_test, teardown_test)
|
||||
@with_app(buildername='html', testroot='intl',
|
||||
@pytest.mark.usefixtures('setup_test')
|
||||
@pytest.mark.sphinx(
|
||||
'html', testroot='intl',
|
||||
confoverrides={'language': 'en', 'locale_dirs': [locale_dir]})
|
||||
def test_compile_update_catalogs(app, status, warning):
|
||||
app.builder.compile_update_catalogs()
|
||||
|
@ -10,17 +10,20 @@
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
from six import PY3, iteritems
|
||||
import pytest
|
||||
import mock
|
||||
|
||||
from util import TestApp, with_app, gen_with_app, with_tempdir, \
|
||||
raises, raises_msg, assert_in, assert_not_in
|
||||
from util import TestApp, gen_with_app, \
|
||||
assert_in, assert_not_in
|
||||
|
||||
import sphinx
|
||||
from sphinx.config import Config
|
||||
from sphinx.errors import ExtensionError, ConfigError, VersionRequirementError
|
||||
|
||||
|
||||
@with_app(confoverrides={'master_doc': 'master', 'nonexisting_value': 'True',
|
||||
@pytest.mark.sphinx(confoverrides={
|
||||
'master_doc': 'master',
|
||||
'nonexisting_value': 'True',
|
||||
'latex_elements.docclass': 'scrartcl',
|
||||
'modindex_common_prefix': 'path1,path2'})
|
||||
def test_core_config(app, status, warning):
|
||||
@ -55,11 +58,14 @@ def test_core_config(app, status, warning):
|
||||
assert 'nonexisting_value' not in cfg
|
||||
|
||||
# invalid values
|
||||
raises(AttributeError, getattr, cfg, '_value')
|
||||
raises(AttributeError, getattr, cfg, 'nonexisting_value')
|
||||
with pytest.raises(AttributeError):
|
||||
getattr(cfg, '_value')
|
||||
with pytest.raises(AttributeError):
|
||||
getattr(cfg, 'nonexisting_value')
|
||||
|
||||
# non-value attributes are deleted from the namespace
|
||||
raises(AttributeError, getattr, cfg, 'sys')
|
||||
with pytest.raises(AttributeError):
|
||||
getattr(cfg, 'sys')
|
||||
|
||||
# setting attributes
|
||||
cfg.project = 'Foo'
|
||||
@ -70,7 +76,7 @@ def test_core_config(app, status, warning):
|
||||
assert cfg['project'] == cfg.project == 'Sphinx Tests'
|
||||
|
||||
|
||||
@with_app()
|
||||
@pytest.mark.sphinx()
|
||||
def test_extension_values(app, status, warning):
|
||||
cfg = app.config
|
||||
|
||||
@ -80,24 +86,27 @@ def test_extension_values(app, status, warning):
|
||||
assert cfg.value_from_conf_py == 84
|
||||
|
||||
# no duplicate values allowed
|
||||
raises_msg(ExtensionError, 'already present', app.add_config_value,
|
||||
'html_title', 'x', True)
|
||||
raises_msg(ExtensionError, 'already present', app.add_config_value,
|
||||
'value_from_ext', 'x', True)
|
||||
with pytest.raises(ExtensionError) as excinfo:
|
||||
app.add_config_value('html_title', 'x', True)
|
||||
assert 'already present' in str(excinfo.value)
|
||||
with pytest.raises(ExtensionError) as excinfo:
|
||||
app.add_config_value('value_from_ext', 'x', True)
|
||||
assert 'already present' in str(excinfo.value)
|
||||
|
||||
|
||||
@with_tempdir
|
||||
@mock.patch("sphinx.config.logger")
|
||||
def test_errors_warnings(dir, logger):
|
||||
def test_errors_warnings(logger, tempdir):
|
||||
# test the error for syntax errors in the config file
|
||||
(dir / 'conf.py').write_text(u'project = \n', encoding='ascii')
|
||||
raises_msg(ConfigError, 'conf.py', Config, dir, 'conf.py', {}, None)
|
||||
(tempdir / 'conf.py').write_text(u'project = \n', encoding='ascii')
|
||||
with pytest.raises(ConfigError) as excinfo:
|
||||
Config(tempdir, 'conf.py', {}, None)
|
||||
assert 'conf.py' in str(excinfo.value)
|
||||
|
||||
# test the automatic conversion of 2.x only code in configs
|
||||
(dir / 'conf.py').write_text(
|
||||
(tempdir / 'conf.py').write_text(
|
||||
u'# -*- coding: utf-8\n\nproject = u"Jägermeister"\n',
|
||||
encoding='utf-8')
|
||||
cfg = Config(dir, 'conf.py', {}, None)
|
||||
cfg = Config(tempdir, 'conf.py', {}, None)
|
||||
cfg.init_values()
|
||||
assert cfg.project == u'Jägermeister'
|
||||
assert logger.called is False
|
||||
@ -107,20 +116,21 @@ def test_errors_warnings(dir, logger):
|
||||
# skip the test there
|
||||
if PY3:
|
||||
return
|
||||
(dir / 'conf.py').write_text(
|
||||
(tempdir / 'conf.py').write_text(
|
||||
u'# -*- coding: latin-1\nproject = "fooä"\n', encoding='latin-1')
|
||||
cfg = Config(dir, 'conf.py', {}, None)
|
||||
cfg = Config(tempdir, 'conf.py', {}, None)
|
||||
|
||||
assert logger.warning.called is False
|
||||
cfg.check_unicode()
|
||||
assert logger.warning.called is True
|
||||
|
||||
|
||||
@with_tempdir
|
||||
def test_errors_if_setup_is_not_callable(dir):
|
||||
def test_errors_if_setup_is_not_callable(tempdir):
|
||||
# test the error to call setup() in the config file
|
||||
(dir / 'conf.py').write_text(u'setup = 1')
|
||||
raises_msg(ConfigError, 'callable', TestApp, srcdir=dir)
|
||||
(tempdir / 'conf.py').write_text(u'setup = 1')
|
||||
with pytest.raises(ConfigError) as excinfo:
|
||||
TestApp(srcdir=tempdir)
|
||||
assert 'callable' in str(excinfo.value)
|
||||
|
||||
|
||||
@mock.patch.object(sphinx, '__display_version__', '1.3.4')
|
||||
@ -130,40 +140,39 @@ def test_needs_sphinx():
|
||||
app.cleanup()
|
||||
app = TestApp(confoverrides={'needs_sphinx': '1.3.4'}) # OK: equals
|
||||
app.cleanup()
|
||||
raises(VersionRequirementError, TestApp,
|
||||
confoverrides={'needs_sphinx': '1.3.5'}) # NG: greater
|
||||
with pytest.raises(VersionRequirementError):
|
||||
TestApp(confoverrides={'needs_sphinx': '1.3.5'}) # NG: greater
|
||||
|
||||
# minor version
|
||||
app = TestApp(confoverrides={'needs_sphinx': '1.2'}) # OK: less
|
||||
app.cleanup()
|
||||
app = TestApp(confoverrides={'needs_sphinx': '1.3'}) # OK: equals
|
||||
app.cleanup()
|
||||
raises(VersionRequirementError, TestApp,
|
||||
confoverrides={'needs_sphinx': '1.4'}) # NG: greater
|
||||
with pytest.raises(VersionRequirementError):
|
||||
TestApp(confoverrides={'needs_sphinx': '1.4'}) # NG: greater
|
||||
|
||||
# major version
|
||||
app = TestApp(confoverrides={'needs_sphinx': '0'}) # OK: less
|
||||
app.cleanup()
|
||||
app = TestApp(confoverrides={'needs_sphinx': '1'}) # OK: equals
|
||||
app.cleanup()
|
||||
raises(VersionRequirementError, TestApp,
|
||||
confoverrides={'needs_sphinx': '2'}) # NG: greater
|
||||
with pytest.raises(VersionRequirementError):
|
||||
TestApp(confoverrides={'needs_sphinx': '2'}) # NG: greater
|
||||
|
||||
|
||||
@with_tempdir
|
||||
@mock.patch("sphinx.config.logger")
|
||||
def test_config_eol(tmpdir, logger):
|
||||
def test_config_eol(logger, tempdir):
|
||||
# test config file's eol patterns: LF, CRLF
|
||||
configfile = tmpdir / 'conf.py'
|
||||
configfile = tempdir / 'conf.py'
|
||||
for eol in (b'\n', b'\r\n'):
|
||||
configfile.write_bytes(b'project = "spam"' + eol)
|
||||
cfg = Config(tmpdir, 'conf.py', {}, None)
|
||||
cfg = Config(tempdir, 'conf.py', {}, None)
|
||||
cfg.init_values()
|
||||
assert cfg.project == u'spam'
|
||||
assert logger.called is False
|
||||
|
||||
|
||||
@with_app(confoverrides={'master_doc': 123,
|
||||
@pytest.mark.sphinx(confoverrides={'master_doc': 123,
|
||||
'language': 'foo',
|
||||
'primary_domain': None})
|
||||
def test_builtin_conf(app, status, warning):
|
||||
@ -209,13 +218,13 @@ def test_gen_check_types(app, status, warning):
|
||||
)
|
||||
|
||||
|
||||
@with_app(testroot='config')
|
||||
@pytest.mark.sphinx(testroot='config')
|
||||
def test_check_enum(app, status, warning):
|
||||
assert "The config value `value17` has to be a one of ('default', 'one', 'two'), " \
|
||||
not in warning.getvalue()
|
||||
|
||||
|
||||
@with_app(testroot='config', confoverrides={'value17': 'invalid'})
|
||||
@pytest.mark.sphinx(testroot='config', confoverrides={'value17': 'invalid'})
|
||||
def test_check_enum_failed(app, status, warning):
|
||||
assert "The config value `value17` has to be a one of ('default', 'one', 'two'), " \
|
||||
"but `invalid` is given." in warning.getvalue()
|
||||
|
@ -9,10 +9,12 @@
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
from util import with_app, etree_parse
|
||||
import pytest
|
||||
|
||||
from util import etree_parse
|
||||
|
||||
|
||||
@with_app('xml', testroot='directive-code')
|
||||
@pytest.mark.sphinx('xml', testroot='directive-code')
|
||||
def test_code_block(app, status, warning):
|
||||
app.builder.build('index')
|
||||
et = etree_parse(app.outdir / 'index.xml')
|
||||
@ -28,7 +30,7 @@ def test_code_block(app, status, warning):
|
||||
assert actual == expect
|
||||
|
||||
|
||||
@with_app('xml', testroot='directive-code')
|
||||
@pytest.mark.sphinx('xml', testroot='directive-code')
|
||||
def test_code_block_dedent(app, status, warning):
|
||||
app.builder.build(['dedent_code'])
|
||||
et = etree_parse(app.outdir / 'dedent_code.xml')
|
||||
@ -47,7 +49,7 @@ def test_code_block_dedent(app, status, warning):
|
||||
assert blocks[5].text == '\n\n' # dedent: 1000
|
||||
|
||||
|
||||
@with_app('html', testroot='directive-code')
|
||||
@pytest.mark.sphinx('html', testroot='directive-code')
|
||||
def test_code_block_caption_html(app, status, warning):
|
||||
app.builder.build(['caption'])
|
||||
html = (app.outdir / 'caption.html').text(encoding='utf-8')
|
||||
@ -59,7 +61,7 @@ def test_code_block_caption_html(app, status, warning):
|
||||
assert caption in html
|
||||
|
||||
|
||||
@with_app('latex', testroot='directive-code')
|
||||
@pytest.mark.sphinx('latex', testroot='directive-code')
|
||||
def test_code_block_caption_latex(app, status, warning):
|
||||
app.builder.build_all()
|
||||
latex = (app.outdir / 'Python.tex').text(encoding='utf-8')
|
||||
@ -72,7 +74,7 @@ def test_code_block_caption_latex(app, status, warning):
|
||||
assert link in latex
|
||||
|
||||
|
||||
@with_app('latex', testroot='directive-code')
|
||||
@pytest.mark.sphinx('latex', testroot='directive-code')
|
||||
def test_code_block_namedlink_latex(app, status, warning):
|
||||
app.builder.build_all()
|
||||
latex = (app.outdir / 'Python.tex').text(encoding='utf-8')
|
||||
@ -89,7 +91,7 @@ def test_code_block_namedlink_latex(app, status, warning):
|
||||
assert link2 in latex
|
||||
|
||||
|
||||
@with_app('xml', testroot='directive-code')
|
||||
@pytest.mark.sphinx('xml', testroot='directive-code')
|
||||
def test_literal_include(app, status, warning):
|
||||
app.builder.build(['index'])
|
||||
et = etree_parse(app.outdir / 'index.xml')
|
||||
@ -101,7 +103,7 @@ def test_literal_include(app, status, warning):
|
||||
assert actual == literal_src
|
||||
|
||||
|
||||
@with_app('xml', testroot='directive-code')
|
||||
@pytest.mark.sphinx('xml', testroot='directive-code')
|
||||
def test_literal_include_dedent(app, status, warning):
|
||||
literal_src = (app.srcdir / 'literal.inc').text(encoding='utf-8')
|
||||
literal_lines = [l[4:] for l in literal_src.split('\n')[9:11]]
|
||||
@ -119,7 +121,7 @@ def test_literal_include_dedent(app, status, warning):
|
||||
assert blocks[5].text == '\n\n' # dedent: 1000
|
||||
|
||||
|
||||
@with_app('xml', testroot='directive-code')
|
||||
@pytest.mark.sphinx('xml', testroot='directive-code')
|
||||
def test_literal_include_block_start_with_comment_or_brank(app, status, warning):
|
||||
app.builder.build(['python'])
|
||||
et = etree_parse(app.outdir / 'python.xml')
|
||||
@ -143,7 +145,7 @@ def test_literal_include_block_start_with_comment_or_brank(app, status, warning)
|
||||
assert actual == expect
|
||||
|
||||
|
||||
@with_app('html', testroot='directive-code')
|
||||
@pytest.mark.sphinx('html', testroot='directive-code')
|
||||
def test_literal_include_linenos(app, status, warning):
|
||||
app.builder.build(['linenos'])
|
||||
html = (app.outdir / 'linenos.html').text(encoding='utf-8')
|
||||
@ -166,7 +168,7 @@ def test_literal_include_linenos(app, status, warning):
|
||||
assert linenos in html
|
||||
|
||||
|
||||
@with_app('html', testroot='directive-code')
|
||||
@pytest.mark.sphinx('html', testroot='directive-code')
|
||||
def test_literal_include_lineno_start(app, status, warning):
|
||||
app.builder.build(['lineno_start'])
|
||||
html = (app.outdir / 'lineno_start.html').text(encoding='utf-8')
|
||||
@ -189,7 +191,7 @@ def test_literal_include_lineno_start(app, status, warning):
|
||||
assert linenos in html
|
||||
|
||||
|
||||
@with_app('html', testroot='directive-code')
|
||||
@pytest.mark.sphinx('html', testroot='directive-code')
|
||||
def test_literal_include_lineno_match(app, status, warning):
|
||||
app.builder.build(['lineno_match'])
|
||||
html = (app.outdir / 'lineno_match.html').text(encoding='utf-8')
|
||||
@ -229,7 +231,7 @@ def test_literal_include_lineno_match(app, status, warning):
|
||||
assert start_at_end_at in html
|
||||
|
||||
|
||||
@with_app('latex', testroot='directive-code')
|
||||
@pytest.mark.sphinx('latex', testroot='directive-code')
|
||||
def test_literalinclude_file_whole_of_emptyline(app, status, warning):
|
||||
app.builder.build_all()
|
||||
latex = (app.outdir / 'Python.tex').text(encoding='utf-8').replace('\r\n', '\n')
|
||||
@ -243,7 +245,7 @@ def test_literalinclude_file_whole_of_emptyline(app, status, warning):
|
||||
assert includes in latex
|
||||
|
||||
|
||||
@with_app('html', testroot='directive-code')
|
||||
@pytest.mark.sphinx('html', testroot='directive-code')
|
||||
def test_literalinclude_caption_html(app, status, warning):
|
||||
app.builder.build('index')
|
||||
html = (app.outdir / 'caption.html').text(encoding='utf-8')
|
||||
@ -255,7 +257,7 @@ def test_literalinclude_caption_html(app, status, warning):
|
||||
assert caption in html
|
||||
|
||||
|
||||
@with_app('latex', testroot='directive-code')
|
||||
@pytest.mark.sphinx('latex', testroot='directive-code')
|
||||
def test_literalinclude_caption_latex(app, status, warning):
|
||||
app.builder.build('index')
|
||||
latex = (app.outdir / 'Python.tex').text(encoding='utf-8')
|
||||
@ -268,7 +270,7 @@ def test_literalinclude_caption_latex(app, status, warning):
|
||||
assert link in latex
|
||||
|
||||
|
||||
@with_app('latex', testroot='directive-code')
|
||||
@pytest.mark.sphinx('latex', testroot='directive-code')
|
||||
def test_literalinclude_namedlink_latex(app, status, warning):
|
||||
app.builder.build('index')
|
||||
latex = (app.outdir / 'Python.tex').text(encoding='utf-8')
|
||||
@ -285,7 +287,7 @@ def test_literalinclude_namedlink_latex(app, status, warning):
|
||||
assert link2 in latex
|
||||
|
||||
|
||||
@with_app('xml', testroot='directive-code')
|
||||
@pytest.mark.sphinx('xml', testroot='directive-code')
|
||||
def test_literalinclude_classes(app, status, warning):
|
||||
app.builder.build(['classes'])
|
||||
et = etree_parse(app.outdir / 'classes.xml')
|
||||
|
@ -13,11 +13,10 @@ import re
|
||||
|
||||
from docutils import nodes
|
||||
from sphinx.util.nodes import process_only_nodes
|
||||
|
||||
from util import with_app
|
||||
import pytest
|
||||
|
||||
|
||||
@with_app('text', testroot='directive-only')
|
||||
@pytest.mark.sphinx('text', testroot='directive-only')
|
||||
def test_sectioning(app, status, warning):
|
||||
|
||||
def getsects(section):
|
||||
|
@ -11,14 +11,15 @@
|
||||
|
||||
import re
|
||||
|
||||
from util import with_app, path, SkipTest
|
||||
import pytest
|
||||
from util import path, SkipTest
|
||||
|
||||
|
||||
def regex_count(expr, result):
|
||||
return len(re.findall(expr, result))
|
||||
|
||||
|
||||
@with_app('html', testroot='docutilsconf', freshenv=True, docutilsconf='')
|
||||
@pytest.mark.sphinx('html', testroot='docutilsconf', freshenv=True, docutilsconf='')
|
||||
def test_html_with_default_docutilsconf(app, status, warning):
|
||||
app.builder.build(['contents'])
|
||||
result = (app.outdir / 'contents.html').text(encoding='utf-8')
|
||||
@ -29,7 +30,7 @@ def test_html_with_default_docutilsconf(app, status, warning):
|
||||
assert regex_count(r'<td class="option-group" colspan="2">', result) == 1
|
||||
|
||||
|
||||
@with_app('html', testroot='docutilsconf', freshenv=True, docutilsconf=(
|
||||
@pytest.mark.sphinx('html', testroot='docutilsconf', freshenv=True, docutilsconf=(
|
||||
'\n[html4css1 writer]'
|
||||
'\noption-limit:1'
|
||||
'\nfield-name-limit:1'
|
||||
@ -45,30 +46,30 @@ def test_html_with_docutilsconf(app, status, warning):
|
||||
assert regex_count(r'<td class="option-group" colspan="2">', result) == 2
|
||||
|
||||
|
||||
@with_app('html', testroot='docutilsconf')
|
||||
@pytest.mark.sphinx('html', testroot='docutilsconf')
|
||||
def test_html(app, status, warning):
|
||||
app.builder.build(['contents'])
|
||||
assert warning.getvalue() == ''
|
||||
|
||||
|
||||
@with_app('latex', testroot='docutilsconf')
|
||||
@pytest.mark.sphinx('latex', testroot='docutilsconf')
|
||||
def test_latex(app, status, warning):
|
||||
app.builder.build(['contents'])
|
||||
assert warning.getvalue() == ''
|
||||
|
||||
|
||||
@with_app('man', testroot='docutilsconf')
|
||||
@pytest.mark.sphinx('man', testroot='docutilsconf')
|
||||
def test_man(app, status, warning):
|
||||
app.builder.build(['contents'])
|
||||
assert warning.getvalue() == ''
|
||||
|
||||
|
||||
@with_app('texinfo', testroot='docutilsconf')
|
||||
@pytest.mark.sphinx('texinfo', testroot='docutilsconf')
|
||||
def test_texinfo(app, status, warning):
|
||||
app.builder.build(['contents'])
|
||||
|
||||
|
||||
@with_app('html', testroot='docutilsconf',
|
||||
@pytest.mark.sphinx('html', testroot='docutilsconf',
|
||||
docutilsconf='[general]\nsource_link=true\n')
|
||||
def test_docutils_source_link_with_nonascii_file(app, status, warning):
|
||||
srcdir = path(app.srcdir)
|
||||
|
@ -12,8 +12,7 @@
|
||||
import re
|
||||
|
||||
from six import text_type
|
||||
|
||||
from util import raises, with_app
|
||||
import pytest
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.domains.cpp import DefinitionParser, DefinitionError, NoOldIdError
|
||||
@ -150,9 +149,10 @@ def test_concept_definitions():
|
||||
None, 'I0EN1A1B7ConceptE')
|
||||
check('concept', 'template<typename A, typename B, typename ...C> Foo()',
|
||||
None, 'I00DpE3Foo')
|
||||
raises(DefinitionError, parse, 'concept', 'Foo')
|
||||
raises(DefinitionError, parse, 'concept',
|
||||
'template<typename T> template<typename U> Foo')
|
||||
with pytest.raises(DefinitionError):
|
||||
parse('concept', 'Foo')
|
||||
with pytest.raises(DefinitionError):
|
||||
parse('concept', 'template<typename T> template<typename U> Foo')
|
||||
|
||||
|
||||
def test_member_definitions():
|
||||
@ -259,9 +259,12 @@ def test_function_definitions():
|
||||
'int foo(Foo f = Foo(double(), std::make_pair(int(2), double(3.4))))',
|
||||
"foo__Foo", "3foo3Foo")
|
||||
check('function', 'int foo(A a = x(a))', "foo__A", "3foo1A")
|
||||
raises(DefinitionError, parse, 'function', 'int foo(B b=x(a)')
|
||||
raises(DefinitionError, parse, 'function', 'int foo)C c=x(a))')
|
||||
raises(DefinitionError, parse, 'function', 'int foo(D d=x(a')
|
||||
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)', "foo__ACRDp", "3fooDpRK1A")
|
||||
check('function', 'virtual void f()', "f", "1fv")
|
||||
# test for ::nestedName, from issue 1738
|
||||
@ -382,8 +385,10 @@ def test_templates():
|
||||
check('function', "template<> void A()", None, "IE1Av")
|
||||
check('member', "template<> A a", None, "IE1a")
|
||||
check('type', "template<> a = A", None, "IE1a")
|
||||
raises(DefinitionError, parse, 'enum', "template<> A")
|
||||
raises(DefinitionError, parse, 'enumerator', "template<> A")
|
||||
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", None, "I00E1A")
|
||||
check('type', "template<> a", None, "IE1a")
|
||||
@ -419,8 +424,10 @@ def test_templates():
|
||||
"RK18c_string_view_baseIK4Char6TraitsE")
|
||||
|
||||
# template introductions
|
||||
raises(DefinitionError, parse, 'enum', 'abc::ns::foo{id_0, id_1, id_2} A')
|
||||
raises(DefinitionError, parse, 'enumerator', 'abc::ns::foo{id_0, id_1, id_2} A')
|
||||
with pytest.raises(DefinitionError):
|
||||
parse('enum', 'abc::ns::foo{id_0, id_1, id_2} A')
|
||||
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',
|
||||
None, 'I000EXN3abc2ns3fooEI4id_04id_14id_2EEN3xyz3barE')
|
||||
check('class', 'abc::ns::foo{id_0, id_1, ...id_2} xyz::bar',
|
||||
@ -469,12 +476,18 @@ def test_attributes():
|
||||
check('member', 'paren_attr(a) int f', 'f__i', '1f')
|
||||
check('member', 'paren_attr("") int f', 'f__i', '1f')
|
||||
check('member', 'paren_attr(()[{}][]{}) int f', 'f__i', '1f')
|
||||
raises(DefinitionError, parse, 'member', 'paren_attr(() int f')
|
||||
raises(DefinitionError, parse, 'member', 'paren_attr([) int f')
|
||||
raises(DefinitionError, parse, 'member', 'paren_attr({) int f')
|
||||
raises(DefinitionError, parse, 'member', 'paren_attr([)]) int f')
|
||||
raises(DefinitionError, parse, 'member', 'paren_attr((])) int f')
|
||||
raises(DefinitionError, parse, 'member', 'paren_attr({]}) int f')
|
||||
with pytest.raises(DefinitionError):
|
||||
parse('member', 'paren_attr(() int f')
|
||||
with pytest.raises(DefinitionError):
|
||||
parse('member', 'paren_attr([) int f')
|
||||
with pytest.raises(DefinitionError):
|
||||
parse('member', 'paren_attr({) int f')
|
||||
with pytest.raises(DefinitionError):
|
||||
parse('member', 'paren_attr([)]) int f')
|
||||
with pytest.raises(DefinitionError):
|
||||
parse('member', 'paren_attr((])) int f')
|
||||
with pytest.raises(DefinitionError):
|
||||
parse('member', 'paren_attr({]}) int f')
|
||||
|
||||
# position: decl specs
|
||||
check('function', 'static inline __attribute__(()) void f()',
|
||||
@ -490,7 +503,7 @@ def test_attributes():
|
||||
# raise DefinitionError("")
|
||||
|
||||
|
||||
@with_app(testroot='domain-cpp', confoverrides={'add_function_parentheses': True})
|
||||
@pytest.mark.sphinx(testroot='domain-cpp', confoverrides={'add_function_parentheses': True})
|
||||
def test_build_domain_cpp_with_add_function_parentheses_is_True(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
||||
@ -527,7 +540,8 @@ def test_build_domain_cpp_with_add_function_parentheses_is_True(app, status, war
|
||||
check(s, t, f)
|
||||
|
||||
|
||||
@with_app(testroot='domain-cpp', confoverrides={'add_function_parentheses': False})
|
||||
@pytest.mark.sphinx(testroot='domain-cpp', confoverrides={
|
||||
'add_function_parentheses': False})
|
||||
def test_build_domain_cpp_with_add_function_parentheses_is_False(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
||||
|
@ -14,8 +14,9 @@ from docutils.nodes import bullet_list, list_item, caption, comment, reference
|
||||
from sphinx import addnodes
|
||||
from sphinx.addnodes import compact_paragraph, only
|
||||
from sphinx.builders.html import StandaloneHTMLBuilder
|
||||
import pytest
|
||||
|
||||
from util import with_app, gen_with_app, assert_node
|
||||
from util import gen_with_app, assert_node
|
||||
|
||||
|
||||
@gen_with_app('xml', testroot='toctree')
|
||||
@ -97,7 +98,7 @@ def _test_process_doc(app):
|
||||
assert 'qux' not in app.env.toctree_includes
|
||||
|
||||
|
||||
@with_app('dummy', testroot='toctree-glob')
|
||||
@pytest.mark.sphinx('dummy', testroot='toctree-glob')
|
||||
def test_glob(app, status, warning):
|
||||
includefiles = ['foo', 'bar/index', 'bar/bar_1', 'bar/bar_2',
|
||||
'bar/bar_3', 'baz', 'qux/index']
|
||||
|
@ -10,12 +10,11 @@
|
||||
"""
|
||||
|
||||
import pickle
|
||||
from docutils import nodes
|
||||
import pytest
|
||||
from sphinx import addnodes
|
||||
from util import with_app
|
||||
|
||||
|
||||
@with_app(buildername='dummy', testroot='ext-autodoc')
|
||||
@pytest.mark.sphinx('dummy', testroot='ext-autodoc')
|
||||
def test_autodoc(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
||||
|
@ -11,10 +11,10 @@
|
||||
|
||||
import re
|
||||
|
||||
from util import with_app
|
||||
import pytest
|
||||
|
||||
|
||||
@with_app('html', testroot='ext-autosectionlabel')
|
||||
@pytest.mark.sphinx('html', testroot='ext-autosectionlabel')
|
||||
def test_autosectionlabel_html(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
||||
|
@ -13,7 +13,7 @@ from six import iteritems, StringIO
|
||||
|
||||
from sphinx.ext.autosummary import mangle_signature
|
||||
|
||||
from util import with_app
|
||||
import pytest
|
||||
|
||||
html_warnfile = StringIO()
|
||||
|
||||
@ -54,7 +54,7 @@ def test_mangle_signature():
|
||||
assert res == outp, (u"'%s' -> '%s' != '%s'" % (inp, res, outp))
|
||||
|
||||
|
||||
@with_app(buildername='dummy', **default_kw)
|
||||
@pytest.mark.sphinx('dummy', **default_kw)
|
||||
def test_get_items_summary(app, status, warning):
|
||||
# monkey-patch Autosummary.get_items so we can easily get access to it's
|
||||
# results..
|
||||
|
@ -11,10 +11,10 @@
|
||||
|
||||
import pickle
|
||||
|
||||
from util import with_app
|
||||
import pytest
|
||||
|
||||
|
||||
@with_app(buildername='coverage')
|
||||
@pytest.mark.sphinx('coverage')
|
||||
def test_build(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
||||
|
@ -8,13 +8,12 @@
|
||||
:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
from util import with_app
|
||||
import pytest
|
||||
|
||||
cleanup_called = 0
|
||||
|
||||
|
||||
@with_app(buildername='doctest', testroot='doctest')
|
||||
@pytest.mark.sphinx('doctest', testroot='doctest')
|
||||
def test_build(app, status, warning):
|
||||
global cleanup_called
|
||||
cleanup_called = 0
|
||||
|
@ -9,10 +9,10 @@
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
from util import with_app
|
||||
import pytest
|
||||
|
||||
|
||||
@with_app('html', testroot='ext-githubpages')
|
||||
@pytest.mark.sphinx('html', testroot='ext-githubpages')
|
||||
def test_githubpages(app, status, warning):
|
||||
app.builder.build_all()
|
||||
assert (app.outdir / '.nojekyll').exists()
|
||||
|
@ -10,37 +10,12 @@
|
||||
"""
|
||||
|
||||
import re
|
||||
import subprocess
|
||||
from functools import wraps
|
||||
|
||||
from util import with_app, SkipTest
|
||||
import pytest
|
||||
|
||||
|
||||
def skip_if_graphviz_not_found(fn):
|
||||
@wraps(fn)
|
||||
def decorator(app, *args, **kwargs):
|
||||
found = False
|
||||
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()
|
||||
found = True
|
||||
except OSError: # No such file or directory
|
||||
pass
|
||||
|
||||
if not found:
|
||||
raise SkipTest('graphviz "dot" is not available')
|
||||
|
||||
return fn(app, *args, **kwargs)
|
||||
|
||||
return decorator
|
||||
|
||||
|
||||
@with_app('html', testroot='ext-graphviz')
|
||||
@skip_if_graphviz_not_found
|
||||
@pytest.mark.sphinx('html', testroot='ext-graphviz')
|
||||
@pytest.mark.usefixtures('if_graphviz_found')
|
||||
def test_graphviz_html(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
||||
@ -60,8 +35,8 @@ def test_graphviz_html(app, status, warning):
|
||||
assert re.search(html, content, re.S)
|
||||
|
||||
|
||||
@with_app('latex', testroot='ext-graphviz')
|
||||
@skip_if_graphviz_not_found
|
||||
@pytest.mark.sphinx('latex', testroot='ext-graphviz')
|
||||
@pytest.mark.usefixtures('if_graphviz_found')
|
||||
def test_graphviz_latex(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
||||
@ -80,8 +55,8 @@ def test_graphviz_latex(app, status, warning):
|
||||
assert re.search(macro, content, re.S)
|
||||
|
||||
|
||||
@with_app('html', testroot='ext-graphviz', confoverrides={'language': 'xx'})
|
||||
@skip_if_graphviz_not_found
|
||||
@pytest.mark.sphinx('html', testroot='ext-graphviz', confoverrides={'language': 'xx'})
|
||||
@pytest.mark.usefixtures('if_graphviz_found')
|
||||
def test_graphviz_i18n(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
||||
|
@ -9,10 +9,10 @@
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
from util import with_app
|
||||
import pytest
|
||||
|
||||
|
||||
@with_app(buildername='text', testroot='ext-ifconfig')
|
||||
@pytest.mark.sphinx('text', testroot='ext-ifconfig')
|
||||
def test_ifconfig(app, status, warning):
|
||||
app.builder.build_all()
|
||||
result = (app.outdir / 'index.txt').text()
|
||||
|
@ -11,13 +11,13 @@
|
||||
|
||||
import re
|
||||
import sys
|
||||
from util import with_app, rootdir, raises
|
||||
from test_ext_graphviz import skip_if_graphviz_not_found
|
||||
from util import rootdir
|
||||
from sphinx.ext.inheritance_diagram import InheritanceException, import_classes
|
||||
import pytest
|
||||
|
||||
|
||||
@with_app('html', testroot='ext-inheritance_diagram')
|
||||
@skip_if_graphviz_not_found
|
||||
@pytest.mark.sphinx('html', testroot='ext-inheritance_diagram')
|
||||
@pytest.mark.usefixtures('if_graphviz_found')
|
||||
def test_inheritance_diagram_html(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
||||
@ -31,8 +31,8 @@ def test_inheritance_diagram_html(app, status, warning):
|
||||
assert re.search(pattern, content, re.M)
|
||||
|
||||
|
||||
@with_app('latex', testroot='ext-inheritance_diagram')
|
||||
@skip_if_graphviz_not_found
|
||||
@pytest.mark.sphinx('latex', testroot='ext-inheritance_diagram')
|
||||
@pytest.mark.usefixtures('if_graphviz_found')
|
||||
def test_inheritance_diagram_latex(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
||||
@ -53,8 +53,10 @@ def test_import_classes():
|
||||
from example.sphinx import DummyClass
|
||||
|
||||
# got exception for unknown class or module
|
||||
raises(InheritanceException, import_classes, 'unknown', None)
|
||||
raises(InheritanceException, import_classes, 'unknown.Unknown', None)
|
||||
with pytest.raises(InheritanceException):
|
||||
import_classes('unknown', None)
|
||||
with pytest.raises(InheritanceException):
|
||||
import_classes('unknown.Unknown', None)
|
||||
|
||||
# a module having no classes
|
||||
classes = import_classes('sphinx', None)
|
||||
@ -80,7 +82,8 @@ def test_import_classes():
|
||||
assert classes == [CatalogInfo]
|
||||
|
||||
# got exception for functions
|
||||
raises(InheritanceException, import_classes, 'encode_uri', 'sphinx.util')
|
||||
with pytest.raises(InheritanceException):
|
||||
import_classes('encode_uri', 'sphinx.util')
|
||||
|
||||
# import submodule on current module (refs: #3164)
|
||||
classes = import_classes('sphinx', 'example')
|
||||
|
@ -23,8 +23,6 @@ from sphinx.ext.intersphinx import read_inventory, \
|
||||
load_mappings, missing_reference, _strip_basic_auth, _read_from_url, \
|
||||
_get_safe_url, fetch_inventory, INVENTORY_FILENAME
|
||||
|
||||
from util import with_app, with_tempdir
|
||||
|
||||
|
||||
inventory_v1 = '''\
|
||||
# Sphinx inventory version 1
|
||||
@ -82,10 +80,9 @@ def test_read_inventory_v2():
|
||||
'/util/glossary.html#term-a-term-including-colon'
|
||||
|
||||
|
||||
@with_app()
|
||||
@mock.patch('sphinx.ext.intersphinx.read_inventory')
|
||||
@mock.patch('sphinx.ext.intersphinx._read_from_url')
|
||||
def test_fetch_inventory_redirection(app, status, warning, _read_from_url, read_inventory):
|
||||
def test_fetch_inventory_redirection(_read_from_url, read_inventory, app, status, warning):
|
||||
intersphinx_setup(app)
|
||||
_read_from_url().readline.return_value = '# Sphinx inventory version 2'.encode('utf-8')
|
||||
|
||||
@ -127,8 +124,6 @@ def test_fetch_inventory_redirection(app, status, warning, _read_from_url, read_
|
||||
assert read_inventory.call_args[0][1] == 'http://hostname/'
|
||||
|
||||
|
||||
@with_app()
|
||||
@with_tempdir
|
||||
def test_missing_reference(tempdir, app, status, warning):
|
||||
inv_file = tempdir / 'inventory'
|
||||
inv_file.write_bytes(inventory_v2)
|
||||
@ -218,8 +213,6 @@ def test_missing_reference(tempdir, app, status, warning):
|
||||
assert rn['refuri'] == '../../../../py3k/foo.html#module-module1'
|
||||
|
||||
|
||||
@with_app()
|
||||
@with_tempdir
|
||||
def test_load_mappings_warnings(tempdir, app, status, warning):
|
||||
"""
|
||||
load_mappings issues a warning if new-style mapping
|
||||
|
@ -11,10 +11,12 @@
|
||||
|
||||
import re
|
||||
|
||||
from util import with_app, SkipTest
|
||||
import pytest
|
||||
from util import SkipTest
|
||||
|
||||
|
||||
@with_app(buildername='html', testroot='ext-math',
|
||||
@pytest.mark.sphinx(
|
||||
'html', testroot='ext-math',
|
||||
confoverrides = {'extensions': ['sphinx.ext.jsmath'], 'jsmath_path': 'dummy.js'})
|
||||
def test_jsmath(app, status, warning):
|
||||
app.builder.build_all()
|
||||
@ -33,7 +35,7 @@ def test_jsmath(app, status, warning):
|
||||
assert '<div class="math">\na + 1 < b</div>' in content
|
||||
|
||||
|
||||
@with_app('html', testroot='ext-math-simple',
|
||||
@pytest.mark.sphinx('html', testroot='ext-math-simple',
|
||||
confoverrides = {'extensions': ['sphinx.ext.imgmath']})
|
||||
def test_imgmath_png(app, status, warning):
|
||||
app.builder.build_all()
|
||||
@ -48,7 +50,7 @@ def test_imgmath_png(app, status, warning):
|
||||
assert re.search(html, content, re.S)
|
||||
|
||||
|
||||
@with_app('html', testroot='ext-math-simple',
|
||||
@pytest.mark.sphinx('html', testroot='ext-math-simple',
|
||||
confoverrides={'extensions': ['sphinx.ext.imgmath'],
|
||||
'imgmath_image_format': 'svg'})
|
||||
def test_imgmath_svg(app, status, warning):
|
||||
@ -64,7 +66,7 @@ def test_imgmath_svg(app, status, warning):
|
||||
assert re.search(html, content, re.S)
|
||||
|
||||
|
||||
@with_app('html', testroot='ext-math',
|
||||
@pytest.mark.sphinx('html', testroot='ext-math',
|
||||
confoverrides={'extensions': ['sphinx.ext.mathjax']})
|
||||
def test_mathjax_align(app, status, warning):
|
||||
app.builder.build_all()
|
||||
@ -76,7 +78,7 @@ def test_mathjax_align(app, status, warning):
|
||||
assert re.search(html, content, re.S)
|
||||
|
||||
|
||||
@with_app('html', testroot='ext-math',
|
||||
@pytest.mark.sphinx('html', testroot='ext-math',
|
||||
confoverrides={'math_number_all': True,
|
||||
'extensions': ['sphinx.ext.mathjax']})
|
||||
def test_math_number_all_mathjax(app, status, warning):
|
||||
@ -88,7 +90,7 @@ def test_math_number_all_mathjax(app, status, warning):
|
||||
assert re.search(html, content, re.S)
|
||||
|
||||
|
||||
@with_app('latex', testroot='ext-math',
|
||||
@pytest.mark.sphinx('latex', testroot='ext-math',
|
||||
confoverrides={'extensions': ['sphinx.ext.mathjax']})
|
||||
def test_math_number_all_latex(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
@ -10,10 +10,11 @@
|
||||
"""
|
||||
|
||||
import re
|
||||
from util import with_app
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@with_app('html', testroot='ext-todo', freshenv=True,
|
||||
@pytest.mark.sphinx('html', testroot='ext-todo', freshenv=True,
|
||||
confoverrides={'todo_include_todos': True, 'todo_emit_warnings': True})
|
||||
def test_todo(app, status, warning):
|
||||
todos = []
|
||||
@ -49,7 +50,7 @@ def test_todo(app, status, warning):
|
||||
assert set(todo[1].astext() for todo in todos) == set(['todo in foo', 'todo in bar'])
|
||||
|
||||
|
||||
@with_app('html', testroot='ext-todo', freshenv=True,
|
||||
@pytest.mark.sphinx('html', testroot='ext-todo', freshenv=True,
|
||||
confoverrides={'todo_include_todos': False, 'todo_emit_warnings': True})
|
||||
def test_todo_not_included(app, status, warning):
|
||||
todos = []
|
||||
|
@ -11,10 +11,10 @@
|
||||
|
||||
import re
|
||||
|
||||
from util import with_app
|
||||
import pytest
|
||||
|
||||
|
||||
@with_app(testroot='ext-viewcode')
|
||||
@pytest.mark.sphinx(testroot='ext-viewcode')
|
||||
def test_viewcode(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
||||
@ -32,7 +32,7 @@ def test_viewcode(app, status, warning):
|
||||
assert result.count('href="_modules/spam/mod2.html#Class2"') == 2
|
||||
|
||||
|
||||
@with_app(testroot='ext-viewcode', tags=['test_linkcode'])
|
||||
@pytest.mark.sphinx(testroot='ext-viewcode', tags=['test_linkcode'])
|
||||
def test_linkcode(app, status, warning):
|
||||
app.builder.build(['objects'])
|
||||
|
||||
|
@ -16,8 +16,6 @@ from pygments.formatters.html import HtmlFormatter
|
||||
|
||||
from sphinx.highlighting import PygmentsBridge
|
||||
|
||||
from util import with_app
|
||||
|
||||
|
||||
class MyLexer(RegexLexer):
|
||||
name = 'testlexer'
|
||||
@ -41,7 +39,6 @@ class ComplainOnUnhighlighted(PygmentsBridge):
|
||||
raise AssertionError("should highlight %r" % source)
|
||||
|
||||
|
||||
@with_app()
|
||||
def test_add_lexer(app, status, warning):
|
||||
app.add_lexer('test', MyLexer())
|
||||
|
||||
|
@ -18,12 +18,12 @@ from docutils import nodes
|
||||
from subprocess import Popen, PIPE
|
||||
|
||||
from babel.messages import pofile
|
||||
from nose.tools import assert_equal
|
||||
from six import string_types
|
||||
import pytest
|
||||
|
||||
from util import tempdir, rootdir, path, gen_with_app, with_app, SkipTest, \
|
||||
from util import tempdir, rootdir, path, gen_with_app, SkipTest, \
|
||||
assert_re_search, assert_not_re_search, assert_in, assert_not_in, \
|
||||
assert_startswith, assert_node, repr_as, etree_parse, strip_escseq
|
||||
assert_startswith, assert_node, etree_parse, strip_escseq, assert_equal
|
||||
|
||||
|
||||
root = tempdir / 'test-intl'
|
||||
@ -846,7 +846,7 @@ def test_references(app, status, warning):
|
||||
yield assert_count(warning_expr, warnings, 0)
|
||||
|
||||
|
||||
@with_app(buildername='dummy', testroot='image-glob', confoverrides={'language': 'xx'})
|
||||
@pytest.mark.sphinx('dummy', testroot='image-glob', confoverrides={'language': 'xx'})
|
||||
def test_image_glob_intl(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
||||
@ -887,7 +887,7 @@ def test_image_glob_intl(app, status, warning):
|
||||
'image/svg+xml': 'subdir/svgimg.xx.svg'})
|
||||
|
||||
|
||||
@with_app(buildername='dummy', testroot='image-glob',
|
||||
@pytest.mark.sphinx('dummy', testroot='image-glob',
|
||||
confoverrides={'language': 'xx',
|
||||
'figure_language_filename': u'{root}{ext}.{language}'})
|
||||
def test_image_glob_intl_using_figure_language_filename(app, status, warning):
|
||||
@ -931,4 +931,4 @@ def test_image_glob_intl_using_figure_language_filename(app, status, warning):
|
||||
|
||||
|
||||
def getwarning(warnings):
|
||||
return repr_as(strip_escseq(warnings.getvalue().replace(os.sep, '/')), '<warnings>')
|
||||
return strip_escseq(warnings.getvalue().replace(os.sep, '/'))
|
||||
|
@ -20,8 +20,9 @@ from sphinx.util import texescape
|
||||
from sphinx.util.docutils import sphinx_domains
|
||||
from sphinx.writers.html import HTMLWriter, SmartyPantsHTMLTranslator
|
||||
from sphinx.writers.latex import LaTeXWriter, LaTeXTranslator
|
||||
import pytest
|
||||
|
||||
from util import TestApp, with_app, assert_node
|
||||
from util import TestApp, assert_node
|
||||
|
||||
|
||||
app = settings = parser = domain_context = None
|
||||
@ -152,7 +153,7 @@ def test_latex_escaping():
|
||||
r'\\href{http://example.com/~me/}{test}.*')
|
||||
|
||||
|
||||
@with_app(buildername='dummy', testroot='prolog')
|
||||
@pytest.mark.sphinx('dummy', testroot='prolog')
|
||||
def test_rst_prolog(app, status, warning):
|
||||
app.builder.build_all()
|
||||
rst = pickle.loads((app.doctreedir / 'restructuredtext.doctree').bytes())
|
||||
@ -176,7 +177,7 @@ def test_rst_prolog(app, status, warning):
|
||||
assert not md.rawsource.endswith('*Good-bye world*.\n')
|
||||
|
||||
|
||||
@with_app(buildername='dummy', testroot='keep_warnings')
|
||||
@pytest.mark.sphinx('dummy', testroot='keep_warnings')
|
||||
def test_keep_warnings_is_True(app, status, warning):
|
||||
app.builder.build_all()
|
||||
doctree = pickle.loads((app.doctreedir / 'index.doctree').bytes())
|
||||
@ -185,7 +186,7 @@ def test_keep_warnings_is_True(app, status, warning):
|
||||
assert_node(doctree[0][1], nodes.system_message)
|
||||
|
||||
|
||||
@with_app(buildername='dummy', testroot='keep_warnings',
|
||||
@pytest.mark.sphinx('dummy', testroot='keep_warnings',
|
||||
confoverrides={'keep_warnings': False})
|
||||
def test_keep_warnings_is_False(app, status, warning):
|
||||
app.builder.build_all()
|
||||
@ -194,7 +195,7 @@ def test_keep_warnings_is_False(app, status, warning):
|
||||
assert len(doctree[0]) == 1
|
||||
|
||||
|
||||
@with_app(buildername='dummy', testroot='refonly_bullet_list')
|
||||
@pytest.mark.sphinx('dummy', testroot='refonly_bullet_list')
|
||||
def test_compact_refonly_bullet_list(app, status, warning):
|
||||
app.builder.build_all()
|
||||
doctree = pickle.loads((app.doctreedir / 'index.doctree').bytes())
|
||||
|
@ -12,12 +12,10 @@
|
||||
# adapted from an example of bibliographic metadata at
|
||||
# http://docutils.sourceforge.net/docs/user/rst/demo.txt
|
||||
|
||||
from util import with_app
|
||||
|
||||
from nose.tools import assert_equal
|
||||
import pytest
|
||||
|
||||
|
||||
@with_app('pseudoxml')
|
||||
@pytest.mark.sphinx('pseudoxml')
|
||||
def test_docinfo(app, status, warning):
|
||||
"""
|
||||
Inspect the 'docinfo' metadata stored in the first node of the document.
|
||||
@ -53,8 +51,4 @@ def test_docinfo(app, status, warning):
|
||||
'orphan': u'',
|
||||
'nocomments': u'',
|
||||
}
|
||||
# I like this way of comparing dicts - easier to see the error.
|
||||
for key in exampledocinfo:
|
||||
yield assert_equal, exampledocinfo.get(key), expecteddocinfo.get(key)
|
||||
# but then we still have to check for missing keys
|
||||
yield assert_equal, set(expecteddocinfo.keys()), set(exampledocinfo.keys())
|
||||
assert exampledocinfo == expecteddocinfo
|
||||
|
@ -14,8 +14,9 @@ import time
|
||||
|
||||
from six import PY2, text_type, StringIO
|
||||
from six.moves import input
|
||||
import pytest
|
||||
|
||||
from util import raises, with_tempdir, SkipTest
|
||||
from util import SkipTest
|
||||
|
||||
from sphinx import application
|
||||
from sphinx import quickstart as qs
|
||||
@ -107,7 +108,8 @@ def test_do_prompt():
|
||||
assert d['k4'] is True
|
||||
qs.do_prompt(d, 'k5', 'Q5', validator=qs.boolean)
|
||||
assert d['k5'] is False
|
||||
raises(AssertionError, qs.do_prompt, d, 'k6', 'Q6', validator=qs.boolean)
|
||||
with pytest.raises(AssertionError):
|
||||
qs.do_prompt(d, 'k6', 'Q6', validator=qs.boolean)
|
||||
|
||||
|
||||
def test_do_prompt_with_nonascii():
|
||||
@ -125,7 +127,6 @@ def test_do_prompt_with_nonascii():
|
||||
assert d['k1'] == u'\u30c9\u30a4\u30c4'
|
||||
|
||||
|
||||
@with_tempdir
|
||||
def test_quickstart_defaults(tempdir):
|
||||
answers = {
|
||||
'Root path': tempdir,
|
||||
@ -163,7 +164,6 @@ def test_quickstart_defaults(tempdir):
|
||||
assert (tempdir / 'make.bat').isfile()
|
||||
|
||||
|
||||
@with_tempdir
|
||||
def test_quickstart_all_answers(tempdir):
|
||||
answers = {
|
||||
'Root path': tempdir,
|
||||
@ -231,7 +231,6 @@ def test_quickstart_all_answers(tempdir):
|
||||
assert (tempdir / 'source' / 'contents.txt').isfile()
|
||||
|
||||
|
||||
@with_tempdir
|
||||
def test_generated_files_eol(tempdir):
|
||||
answers = {
|
||||
'Root path': tempdir,
|
||||
@ -252,7 +251,6 @@ def test_generated_files_eol(tempdir):
|
||||
assert_eol(tempdir / 'Makefile', '\n')
|
||||
|
||||
|
||||
@with_tempdir
|
||||
def test_quickstart_and_build(tempdir):
|
||||
answers = {
|
||||
'Root path': tempdir,
|
||||
@ -278,7 +276,6 @@ def test_quickstart_and_build(tempdir):
|
||||
assert not warnings
|
||||
|
||||
|
||||
@with_tempdir
|
||||
def test_default_filename(tempdir):
|
||||
answers = {
|
||||
'Root path': tempdir,
|
||||
@ -300,7 +297,6 @@ def test_default_filename(tempdir):
|
||||
assert ns['texinfo_documents'][0][1] == 'sphinx'
|
||||
|
||||
|
||||
@with_tempdir
|
||||
def test_extensions(tempdir):
|
||||
qs.main(['sphinx-quickstart', '-q',
|
||||
'-p', 'project_name', '-a', 'author',
|
||||
|
@ -15,8 +15,7 @@ from docutils.parsers import rst
|
||||
|
||||
from sphinx.search import IndexBuilder
|
||||
from sphinx.util import jsdump
|
||||
|
||||
from util import with_app
|
||||
import pytest
|
||||
|
||||
|
||||
settings = parser = None
|
||||
@ -58,7 +57,7 @@ def test_wordcollector():
|
||||
assert 'fermion' in ix._mapping
|
||||
|
||||
|
||||
@with_app(testroot='ext-viewcode')
|
||||
@pytest.mark.sphinx(testroot='ext-viewcode')
|
||||
def test_objects_are_escaped(app, status, warning):
|
||||
app.builder.build_all()
|
||||
searchindex = (app.outdir / 'searchindex.js').text()
|
||||
@ -68,7 +67,7 @@ def test_objects_are_escaped(app, status, warning):
|
||||
assert 'n::Array<T, d>' in index.get('objects').get('') # n::Array<T,d> is escaped
|
||||
|
||||
|
||||
@with_app(testroot='search')
|
||||
@pytest.mark.sphinx(testroot='search')
|
||||
def test_meta_keys_are_handled_for_language_en(app, status, warning):
|
||||
app.builder.build_all()
|
||||
searchindex = jsload(app.outdir / 'searchindex.js')
|
||||
@ -81,7 +80,7 @@ def test_meta_keys_are_handled_for_language_en(app, status, warning):
|
||||
assert not is_registered_term(searchindex, 'onlytoogerman')
|
||||
|
||||
|
||||
@with_app(testroot='search', confoverrides={'html_search_language': 'de'})
|
||||
@pytest.mark.sphinx(testroot='search', confoverrides={'html_search_language': 'de'})
|
||||
def test_meta_keys_are_handled_for_language_de(app, status, warning):
|
||||
app.builder.build_all()
|
||||
searchindex = jsload(app.outdir / 'searchindex.js')
|
||||
@ -94,14 +93,14 @@ def test_meta_keys_are_handled_for_language_de(app, status, warning):
|
||||
assert is_registered_term(searchindex, 'onlytoogerman')
|
||||
|
||||
|
||||
@with_app(testroot='search')
|
||||
@pytest.mark.sphinx(testroot='search')
|
||||
def test_stemmer_does_not_remove_short_words(app, status, warning):
|
||||
app.builder.build_all()
|
||||
searchindex = (app.outdir / 'searchindex.js').text()
|
||||
assert 'zfs' in searchindex
|
||||
|
||||
|
||||
@with_app(testroot='search')
|
||||
@pytest.mark.sphinx(testroot='search')
|
||||
def test_stemmer(app, status, warning):
|
||||
searchindex = jsload(app.outdir / 'searchindex.js')
|
||||
print(searchindex)
|
||||
@ -109,7 +108,7 @@ def test_stemmer(app, status, warning):
|
||||
assert is_registered_term(searchindex, 'intern')
|
||||
|
||||
|
||||
@with_app(testroot='search')
|
||||
@pytest.mark.sphinx(testroot='search')
|
||||
def test_term_in_heading_and_section(app, status, warning):
|
||||
searchindex = (app.outdir / 'searchindex.js').text()
|
||||
# if search term is in the title of one doc and in the text of another
|
||||
@ -119,7 +118,7 @@ def test_term_in_heading_and_section(app, status, warning):
|
||||
assert 'textinhead:0' in searchindex
|
||||
|
||||
|
||||
@with_app(testroot='search')
|
||||
@pytest.mark.sphinx(testroot='search')
|
||||
def test_term_in_raw_directive(app, status, warning):
|
||||
searchindex = jsload(app.outdir / 'searchindex.js')
|
||||
assert not is_registered_term(searchindex, 'raw')
|
||||
|
@ -12,12 +12,13 @@
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
from functools import wraps
|
||||
import tempfile
|
||||
from collections import namedtuple
|
||||
import sphinx
|
||||
|
||||
from util import rootdir, tempdir, SkipTest
|
||||
from path import path
|
||||
import pytest
|
||||
|
||||
from sphinx.util.osutil import cd
|
||||
from util import rootdir, tempdir
|
||||
from textwrap import dedent
|
||||
|
||||
root = tempdir / 'test-setup'
|
||||
@ -28,57 +29,52 @@ def setup_module():
|
||||
(rootdir / 'roots' / 'test-setup').copytree(root)
|
||||
|
||||
|
||||
def with_setup_command(root, *args, **kwds):
|
||||
@pytest.fixture
|
||||
def setup_command(request, tempdir):
|
||||
"""
|
||||
Run `setup.py build_sphinx` with args and kwargs,
|
||||
pass it to the test and clean up properly.
|
||||
"""
|
||||
def generator(func):
|
||||
@wraps(func)
|
||||
def deco(*args2, **kwargs2):
|
||||
tempdir = path(tempfile.mkdtemp())
|
||||
pkgrootdir = (tempdir / 'root')
|
||||
marker = request.node.get_marker('setup_command')
|
||||
args = marker.args if marker else []
|
||||
|
||||
pkgrootdir = tempdir / 'root'
|
||||
root.copytree(pkgrootdir)
|
||||
cwd = os.getcwd()
|
||||
os.chdir(pkgrootdir)
|
||||
|
||||
with cd(pkgrootdir):
|
||||
pythonpath = os.path.dirname(os.path.dirname(sphinx.__file__))
|
||||
if os.getenv('PYTHONPATH'):
|
||||
pythonpath = os.getenv('PYTHONPATH') + os.pathsep + pythonpath
|
||||
command = [sys.executable, 'setup.py', 'build_sphinx']
|
||||
command.extend(args)
|
||||
try:
|
||||
|
||||
proc = subprocess.Popen(
|
||||
command,
|
||||
env=dict(os.environ, PYTHONPATH=pythonpath),
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
func(pkgrootdir, proc)
|
||||
finally:
|
||||
tempdir.rmtree(ignore_errors=True)
|
||||
os.chdir(cwd)
|
||||
return deco
|
||||
return generator
|
||||
yield namedtuple('setup', 'pkgroot,proc')(pkgrootdir, proc)
|
||||
|
||||
|
||||
@with_setup_command(root)
|
||||
def test_build_sphinx(pkgroot, proc):
|
||||
def test_build_sphinx(setup_command):
|
||||
proc = setup_command.proc
|
||||
out, err = proc.communicate()
|
||||
print(out)
|
||||
print(err)
|
||||
assert proc.returncode == 0
|
||||
|
||||
|
||||
@with_setup_command(root)
|
||||
def test_build_sphinx_with_nonascii_path(pkgroot, proc):
|
||||
@pytest.fixture
|
||||
def nonascii_srcdir(request, setup_command):
|
||||
mb_name = u'\u65e5\u672c\u8a9e'
|
||||
srcdir = (pkgroot / 'doc')
|
||||
srcdir = (setup_command.pkgroot / 'doc')
|
||||
try:
|
||||
(srcdir / mb_name).makedirs()
|
||||
except UnicodeEncodeError:
|
||||
from path import FILESYSTEMENCODING
|
||||
raise SkipTest(
|
||||
pytest.skip(
|
||||
'non-ASCII filename not supported on this filesystem encoding: '
|
||||
'%s', FILESYSTEMENCODING)
|
||||
'%s' % FILESYSTEMENCODING)
|
||||
|
||||
(srcdir / mb_name / (mb_name + '.txt')).write_text(dedent("""
|
||||
multi byte file name page
|
||||
@ -93,39 +89,45 @@ def test_build_sphinx_with_nonascii_path(pkgroot, proc):
|
||||
""" % locals())
|
||||
).encode('utf-8'))
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('nonascii_srcdir')
|
||||
def test_build_sphinx_with_nonascii_path(setup_command):
|
||||
proc = setup_command.proc
|
||||
out, err = proc.communicate()
|
||||
print(out)
|
||||
print(err)
|
||||
assert proc.returncode == 0
|
||||
|
||||
|
||||
@with_setup_command(root, '-b', 'linkcheck')
|
||||
def test_build_sphinx_return_nonzero_status(pkgroot, proc):
|
||||
srcdir = (pkgroot / 'doc')
|
||||
@pytest.mark.setup_command('-b', 'linkcheck')
|
||||
def test_build_sphinx_return_nonzero_status(setup_command):
|
||||
srcdir = (setup_command.pkgroot / 'doc')
|
||||
(srcdir / 'contents.txt').write_text(
|
||||
'http://localhost.unexistentdomain/index.html')
|
||||
proc = setup_command.proc
|
||||
out, err = proc.communicate()
|
||||
print(out)
|
||||
print(err)
|
||||
assert proc.returncode != 0, 'expect non-zero status for setup.py'
|
||||
|
||||
|
||||
@with_setup_command(root)
|
||||
def test_build_sphinx_warning_return_zero_status(pkgroot, proc):
|
||||
srcdir = (pkgroot / 'doc')
|
||||
def test_build_sphinx_warning_return_zero_status(setup_command):
|
||||
srcdir = (setup_command.pkgroot / 'doc')
|
||||
(srcdir / 'contents.txt').write_text(
|
||||
'See :ref:`unexisting-reference-label`')
|
||||
proc = setup_command.proc
|
||||
out, err = proc.communicate()
|
||||
print(out)
|
||||
print(err)
|
||||
assert proc.returncode == 0
|
||||
|
||||
|
||||
@with_setup_command(root, '--warning-is-error')
|
||||
def test_build_sphinx_warning_is_error_return_nonzero_status(pkgroot, proc):
|
||||
srcdir = (pkgroot / 'doc')
|
||||
@pytest.mark.setup_command('--warning-is-error')
|
||||
def test_build_sphinx_warning_is_error_return_nonzero_status(setup_command):
|
||||
srcdir = (setup_command.pkgroot / 'doc')
|
||||
(srcdir / 'contents.txt').write_text(
|
||||
'See :ref:`unexisting-reference-label`')
|
||||
proc = setup_command.proc
|
||||
out, err = proc.communicate()
|
||||
print(out)
|
||||
print(err)
|
||||
|
@ -9,10 +9,10 @@
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
from util import with_app
|
||||
import pytest
|
||||
|
||||
|
||||
@with_app('html', testroot='templating')
|
||||
@pytest.mark.sphinx('html', testroot='templating')
|
||||
def test_layout_overloading(app, status, warning):
|
||||
app.builder.build_update()
|
||||
|
||||
@ -21,7 +21,7 @@ def test_layout_overloading(app, status, warning):
|
||||
assert '<!-- layout overloading -->' in result
|
||||
|
||||
|
||||
@with_app('html', testroot='templating')
|
||||
@pytest.mark.sphinx('html', testroot='templating')
|
||||
def test_autosummary_class_template_overloading(app, status, warning):
|
||||
app.builder.build_update()
|
||||
|
||||
|
@ -13,13 +13,15 @@ import os
|
||||
import zipfile
|
||||
|
||||
import mock
|
||||
import pytest
|
||||
|
||||
from sphinx.theming import Theme, ThemeError
|
||||
|
||||
from util import with_app, raises, path
|
||||
from util import with_app, path
|
||||
|
||||
|
||||
@with_app(confoverrides={'html_theme': 'ziptheme',
|
||||
@pytest.mark.sphinx(
|
||||
confoverrides={'html_theme': 'ziptheme',
|
||||
'html_theme_options.testopt': 'foo'})
|
||||
def test_theme_api(app, status, warning):
|
||||
cfg = app.config
|
||||
@ -46,10 +48,12 @@ def test_theme_api(app, status, warning):
|
||||
assert theme.get_confstr('options', 'nosidebar') == 'false'
|
||||
# nonexisting setting
|
||||
assert theme.get_confstr('theme', 'foobar', 'def') == 'def'
|
||||
raises(ThemeError, theme.get_confstr, 'theme', 'foobar')
|
||||
with pytest.raises(ThemeError):
|
||||
theme.get_confstr('theme', 'foobar')
|
||||
|
||||
# options API
|
||||
raises(ThemeError, theme.get_options, {'nonexisting': 'foo'})
|
||||
with pytest.raises(ThemeError):
|
||||
theme.get_options({'nonexisting': 'foo'})
|
||||
options = theme.get_options(cfg.html_theme_options)
|
||||
assert options['testopt'] == 'foo'
|
||||
assert options['nosidebar'] == 'false'
|
||||
@ -59,7 +63,7 @@ def test_theme_api(app, status, warning):
|
||||
assert not os.path.exists(themedir)
|
||||
|
||||
|
||||
@with_app(testroot='tocdepth') # a minimal root
|
||||
@pytest.mark.sphinx(testroot='tocdepth') # a minimal root
|
||||
def test_js_source(app, status, warning):
|
||||
# Now sphinx provides non-minified JS files for jquery.js and underscore.js
|
||||
# to clarify the source of the minified files. see also #1434.
|
||||
@ -83,7 +87,8 @@ def test_js_source(app, status, warning):
|
||||
assert 'Underscore.js {v}'.format(v=v) in underscore_src, msg
|
||||
|
||||
|
||||
def test_double_inheriting_theme():
|
||||
@pytest.mark.sphinx(testroot='double-inheriting-theme')
|
||||
def test_double_inheriting_theme(make_app, app_params):
|
||||
from sphinx.theming import load_theme_plugins # load original before patching
|
||||
|
||||
def load_themes():
|
||||
@ -92,8 +97,6 @@ def test_double_inheriting_theme():
|
||||
for t in load_theme_plugins():
|
||||
yield t
|
||||
|
||||
@mock.patch('sphinx.theming.load_theme_plugins', side_effect=load_themes)
|
||||
@with_app(testroot='double-inheriting-theme')
|
||||
def test_double_inheriting_theme_(app, status, warning, m_):
|
||||
pass
|
||||
yield test_double_inheriting_theme_
|
||||
with mock.patch('sphinx.theming.load_theme_plugins', side_effect=load_themes):
|
||||
args, kwargs = app_params
|
||||
make_app(*args, **kwargs)
|
||||
|
@ -8,11 +8,9 @@
|
||||
:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
import pytest
|
||||
|
||||
from util import with_app
|
||||
|
||||
|
||||
@with_app(testroot='toctree-glob')
|
||||
@pytest.mark.sphinx(testroot='toctree-glob')
|
||||
def test_relations(app, status, warning):
|
||||
app.builder.build_all()
|
||||
assert app.builder.relations['index'] == [None, None, 'foo']
|
||||
|
@ -12,7 +12,6 @@ from sphinx.util.fileutil import copy_asset, copy_asset_file
|
||||
from sphinx.jinja2glue import BuiltinTemplateLoader
|
||||
|
||||
import mock
|
||||
from util import with_tempdir
|
||||
|
||||
|
||||
class DummyTemplateLoader(BuiltinTemplateLoader):
|
||||
@ -24,33 +23,32 @@ class DummyTemplateLoader(BuiltinTemplateLoader):
|
||||
self.init(builder)
|
||||
|
||||
|
||||
@with_tempdir
|
||||
def test_copy_asset_file(tmpdir):
|
||||
def test_copy_asset_file(tempdir):
|
||||
renderer = DummyTemplateLoader()
|
||||
|
||||
# copy normal file
|
||||
src = (tmpdir / 'asset.txt')
|
||||
src = (tempdir / 'asset.txt')
|
||||
src.write_text('# test data')
|
||||
dest = (tmpdir / 'output.txt')
|
||||
dest = (tempdir / 'output.txt')
|
||||
|
||||
copy_asset_file(src, dest)
|
||||
assert dest.exists()
|
||||
assert src.text() == dest.text()
|
||||
|
||||
# copy template file
|
||||
src = (tmpdir / 'asset.txt_t')
|
||||
src = (tempdir / 'asset.txt_t')
|
||||
src.write_text('# {{var1}} data')
|
||||
dest = (tmpdir / 'output.txt_t')
|
||||
dest = (tempdir / 'output.txt_t')
|
||||
|
||||
copy_asset_file(src, dest, {'var1': 'template'}, renderer)
|
||||
assert not dest.exists()
|
||||
assert (tmpdir / 'output.txt').exists()
|
||||
assert (tmpdir / 'output.txt').text() == '# template data'
|
||||
assert (tempdir / 'output.txt').exists()
|
||||
assert (tempdir / 'output.txt').text() == '# template data'
|
||||
|
||||
# copy template file to subdir
|
||||
src = (tmpdir / 'asset.txt_t')
|
||||
src = (tempdir / 'asset.txt_t')
|
||||
src.write_text('# {{var1}} data')
|
||||
subdir1 = (tmpdir / 'subdir')
|
||||
subdir1 = (tempdir / 'subdir')
|
||||
subdir1.makedirs()
|
||||
|
||||
copy_asset_file(src, subdir1, {'var1': 'template'}, renderer)
|
||||
@ -58,8 +56,8 @@ def test_copy_asset_file(tmpdir):
|
||||
assert (subdir1 / 'asset.txt').text() == '# template data'
|
||||
|
||||
# copy template file without context
|
||||
src = (tmpdir / 'asset.txt_t')
|
||||
subdir2 = (tmpdir / 'subdir2')
|
||||
src = (tempdir / 'asset.txt_t')
|
||||
subdir2 = (tempdir / 'subdir2')
|
||||
subdir2.makedirs()
|
||||
|
||||
copy_asset_file(src, subdir2)
|
||||
@ -68,12 +66,11 @@ def test_copy_asset_file(tmpdir):
|
||||
assert (subdir2 / 'asset.txt_t').text() == '# {{var1}} data'
|
||||
|
||||
|
||||
@with_tempdir
|
||||
def test_copy_asset(tmpdir):
|
||||
def test_copy_asset(tempdir):
|
||||
renderer = DummyTemplateLoader()
|
||||
|
||||
# prepare source files
|
||||
source = (tmpdir / 'source')
|
||||
source = (tempdir / 'source')
|
||||
source.makedirs()
|
||||
(source / 'index.rst').write_text('index.rst')
|
||||
(source / 'foo.rst_t').write_text('{{var1}}.rst')
|
||||
@ -84,13 +81,13 @@ def test_copy_asset(tmpdir):
|
||||
(source / '_templates' / 'sidebar.html_t').write_text('sidebar: {{var2}}')
|
||||
|
||||
# copy a single file
|
||||
assert not (tmpdir / 'test1').exists()
|
||||
copy_asset(source / 'index.rst', tmpdir / 'test1')
|
||||
assert (tmpdir / 'test1').exists()
|
||||
assert (tmpdir / 'test1/index.rst').exists()
|
||||
assert not (tempdir / 'test1').exists()
|
||||
copy_asset(source / 'index.rst', tempdir / 'test1')
|
||||
assert (tempdir / 'test1').exists()
|
||||
assert (tempdir / 'test1/index.rst').exists()
|
||||
|
||||
# copy directories
|
||||
destdir = tmpdir / 'test2'
|
||||
destdir = tempdir / 'test2'
|
||||
copy_asset(source, destdir, context=dict(var1='bar', var2='baz'), renderer=renderer)
|
||||
assert (destdir / 'index.rst').exists()
|
||||
assert (destdir / 'foo.rst').exists()
|
||||
@ -104,7 +101,7 @@ def test_copy_asset(tmpdir):
|
||||
def excluded(path):
|
||||
return ('sidebar.html' in path or 'basic.css' in path)
|
||||
|
||||
destdir = tmpdir / 'test3'
|
||||
destdir = tempdir / 'test3'
|
||||
copy_asset(source, destdir, excluded,
|
||||
context=dict(var1='bar', var2='baz'), renderer=renderer)
|
||||
assert (destdir / 'index.rst').exists()
|
||||
|
@ -17,8 +17,9 @@ from os import path
|
||||
from babel.messages.mofile import read_mo
|
||||
from sphinx.util import i18n
|
||||
from sphinx.errors import SphinxError
|
||||
import pytest
|
||||
|
||||
from util import TestApp, with_tempdir, raises
|
||||
from util import TestApp
|
||||
|
||||
|
||||
def test_catalog_info_for_file_and_path():
|
||||
@ -37,13 +38,12 @@ def test_catalog_info_for_sub_domain_file_and_path():
|
||||
assert cat.mo_path == path.join('path', 'sub/domain.mo')
|
||||
|
||||
|
||||
@with_tempdir
|
||||
def test_catalog_outdated(dir):
|
||||
(dir / 'test.po').write_text('#')
|
||||
cat = i18n.CatalogInfo(dir, 'test', 'utf-8')
|
||||
def test_catalog_outdated(tempdir):
|
||||
(tempdir / 'test.po').write_text('#')
|
||||
cat = i18n.CatalogInfo(tempdir, 'test', 'utf-8')
|
||||
assert cat.is_outdated() # if mo is not exist
|
||||
|
||||
mo_file = (dir / 'test.mo')
|
||||
mo_file = (tempdir / 'test.mo')
|
||||
mo_file.write_text('#')
|
||||
assert not cat.is_outdated() # if mo is exist and newer than po
|
||||
|
||||
@ -51,31 +51,29 @@ def test_catalog_outdated(dir):
|
||||
assert cat.is_outdated() # if mo is exist and older than po
|
||||
|
||||
|
||||
@with_tempdir
|
||||
def test_catalog_write_mo(dir):
|
||||
(dir / 'test.po').write_text('#')
|
||||
cat = i18n.CatalogInfo(dir, 'test', 'utf-8')
|
||||
def test_catalog_write_mo(tempdir):
|
||||
(tempdir / 'test.po').write_text('#')
|
||||
cat = i18n.CatalogInfo(tempdir, 'test', 'utf-8')
|
||||
cat.write_mo('en')
|
||||
assert path.exists(cat.mo_path)
|
||||
with open(cat.mo_path, 'rb') as f:
|
||||
assert read_mo(f) is not None
|
||||
|
||||
|
||||
@with_tempdir
|
||||
def test_get_catalogs_for_xx(dir):
|
||||
(dir / 'loc1' / 'xx' / 'LC_MESSAGES').makedirs()
|
||||
(dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test1.po').write_text('#')
|
||||
(dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test2.po').write_text('#')
|
||||
(dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test3.pot').write_text('#')
|
||||
(dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub').makedirs()
|
||||
(dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub' / 'test4.po').write_text('#')
|
||||
(dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub' / 'test5.po').write_text('#')
|
||||
(dir / 'loc1' / 'en' / 'LC_MESSAGES').makedirs()
|
||||
(dir / 'loc1' / 'en' / 'LC_MESSAGES' / 'test6.po').write_text('#')
|
||||
(dir / 'loc1' / 'xx' / 'LC_ALL').makedirs()
|
||||
(dir / 'loc1' / 'xx' / 'LC_ALL' / 'test7.po').write_text('#')
|
||||
def test_get_catalogs_for_xx(tempdir):
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_MESSAGES').makedirs()
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test1.po').write_text('#')
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test2.po').write_text('#')
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test3.pot').write_text('#')
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub').makedirs()
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub' / 'test4.po').write_text('#')
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub' / 'test5.po').write_text('#')
|
||||
(tempdir / 'loc1' / 'en' / 'LC_MESSAGES').makedirs()
|
||||
(tempdir / 'loc1' / 'en' / 'LC_MESSAGES' / 'test6.po').write_text('#')
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_ALL').makedirs()
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_ALL' / 'test7.po').write_text('#')
|
||||
|
||||
catalogs = i18n.find_catalog_source_files([dir / 'loc1'], 'xx', force_all=False)
|
||||
catalogs = i18n.find_catalog_source_files([tempdir / 'loc1'], 'xx', force_all=False)
|
||||
domains = set(c.domain for c in catalogs)
|
||||
assert domains == set([
|
||||
'test1',
|
||||
@ -85,24 +83,22 @@ def test_get_catalogs_for_xx(dir):
|
||||
])
|
||||
|
||||
|
||||
@with_tempdir
|
||||
def test_get_catalogs_for_en(dir):
|
||||
(dir / 'loc1' / 'xx' / 'LC_MESSAGES').makedirs()
|
||||
(dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'xx_dom.po').write_text('#')
|
||||
(dir / 'loc1' / 'en' / 'LC_MESSAGES').makedirs()
|
||||
(dir / 'loc1' / 'en' / 'LC_MESSAGES' / 'en_dom.po').write_text('#')
|
||||
def test_get_catalogs_for_en(tempdir):
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_MESSAGES').makedirs()
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'xx_dom.po').write_text('#')
|
||||
(tempdir / 'loc1' / 'en' / 'LC_MESSAGES').makedirs()
|
||||
(tempdir / 'loc1' / 'en' / 'LC_MESSAGES' / 'en_dom.po').write_text('#')
|
||||
|
||||
catalogs = i18n.find_catalog_source_files([dir / 'loc1'], 'en', force_all=False)
|
||||
catalogs = i18n.find_catalog_source_files([tempdir / 'loc1'], 'en', force_all=False)
|
||||
domains = set(c.domain for c in catalogs)
|
||||
assert domains == set(['en_dom'])
|
||||
|
||||
|
||||
@with_tempdir
|
||||
def test_get_catalogs_with_non_existent_locale(dir):
|
||||
catalogs = i18n.find_catalog_source_files([dir / 'loc1'], 'xx')
|
||||
def test_get_catalogs_with_non_existent_locale(tempdir):
|
||||
catalogs = i18n.find_catalog_source_files([tempdir / 'loc1'], 'xx')
|
||||
assert not catalogs
|
||||
|
||||
catalogs = i18n.find_catalog_source_files([dir / 'loc1'], None)
|
||||
catalogs = i18n.find_catalog_source_files([tempdir / 'loc1'], None)
|
||||
assert not catalogs
|
||||
|
||||
|
||||
@ -111,25 +107,24 @@ def test_get_catalogs_with_non_existent_locale_dirs():
|
||||
assert not catalogs
|
||||
|
||||
|
||||
@with_tempdir
|
||||
def test_get_catalogs_for_xx_without_outdated(dir):
|
||||
(dir / 'loc1' / 'xx' / 'LC_MESSAGES').makedirs()
|
||||
(dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test1.po').write_text('#')
|
||||
(dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test1.mo').write_text('#')
|
||||
(dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test2.po').write_text('#')
|
||||
(dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test2.mo').write_text('#')
|
||||
(dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test3.pot').write_text('#')
|
||||
(dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test3.mo').write_text('#')
|
||||
(dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub').makedirs()
|
||||
(dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub' / 'test4.po').write_text('#')
|
||||
(dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub' / 'test4.mo').write_text('#')
|
||||
(dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub' / 'test5.po').write_text('#')
|
||||
(dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub' / 'test5.mo').write_text('#')
|
||||
def test_get_catalogs_for_xx_without_outdated(tempdir):
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_MESSAGES').makedirs()
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test1.po').write_text('#')
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test1.mo').write_text('#')
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test2.po').write_text('#')
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test2.mo').write_text('#')
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test3.pot').write_text('#')
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test3.mo').write_text('#')
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub').makedirs()
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub' / 'test4.po').write_text('#')
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub' / 'test4.mo').write_text('#')
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub' / 'test5.po').write_text('#')
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub' / 'test5.mo').write_text('#')
|
||||
|
||||
catalogs = i18n.find_catalog_source_files([dir / 'loc1'], 'xx', force_all=False)
|
||||
catalogs = i18n.find_catalog_source_files([tempdir / 'loc1'], 'xx', force_all=False)
|
||||
assert not catalogs
|
||||
|
||||
catalogs = i18n.find_catalog_source_files([dir / 'loc1'], 'xx', force_all=True)
|
||||
catalogs = i18n.find_catalog_source_files([tempdir / 'loc1'], 'xx', force_all=True)
|
||||
domains = set(c.domain for c in catalogs)
|
||||
assert domains == set([
|
||||
'test1',
|
||||
@ -139,29 +134,27 @@ def test_get_catalogs_for_xx_without_outdated(dir):
|
||||
])
|
||||
|
||||
|
||||
@with_tempdir
|
||||
def test_get_catalogs_from_multiple_locale_dirs(dir):
|
||||
(dir / 'loc1' / 'xx' / 'LC_MESSAGES').makedirs()
|
||||
(dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test1.po').write_text('#')
|
||||
(dir / 'loc2' / 'xx' / 'LC_MESSAGES').makedirs()
|
||||
(dir / 'loc2' / 'xx' / 'LC_MESSAGES' / 'test1.po').write_text('#')
|
||||
(dir / 'loc2' / 'xx' / 'LC_MESSAGES' / 'test2.po').write_text('#')
|
||||
def test_get_catalogs_from_multiple_locale_dirs(tempdir):
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_MESSAGES').makedirs()
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test1.po').write_text('#')
|
||||
(tempdir / 'loc2' / 'xx' / 'LC_MESSAGES').makedirs()
|
||||
(tempdir / 'loc2' / 'xx' / 'LC_MESSAGES' / 'test1.po').write_text('#')
|
||||
(tempdir / 'loc2' / 'xx' / 'LC_MESSAGES' / 'test2.po').write_text('#')
|
||||
|
||||
catalogs = i18n.find_catalog_source_files([dir / 'loc1', dir / 'loc2'], 'xx')
|
||||
catalogs = i18n.find_catalog_source_files([tempdir / 'loc1', tempdir / 'loc2'], 'xx')
|
||||
domains = sorted(c.domain for c in catalogs)
|
||||
assert domains == ['test1', 'test1', 'test2']
|
||||
|
||||
|
||||
@with_tempdir
|
||||
def test_get_catalogs_with_compact(dir):
|
||||
(dir / 'loc1' / 'xx' / 'LC_MESSAGES').makedirs()
|
||||
(dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test1.po').write_text('#')
|
||||
(dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test2.po').write_text('#')
|
||||
(dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub').makedirs()
|
||||
(dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub' / 'test3.po').write_text('#')
|
||||
(dir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub' / 'test4.po').write_text('#')
|
||||
def test_get_catalogs_with_compact(tempdir):
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_MESSAGES').makedirs()
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test1.po').write_text('#')
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'test2.po').write_text('#')
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub').makedirs()
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub' / 'test3.po').write_text('#')
|
||||
(tempdir / 'loc1' / 'xx' / 'LC_MESSAGES' / 'sub' / 'test4.po').write_text('#')
|
||||
|
||||
catalogs = i18n.find_catalog_source_files([dir / 'loc1'], 'xx', gettext_compact=True)
|
||||
catalogs = i18n.find_catalog_source_files([tempdir / 'loc1'], 'xx', gettext_compact=True)
|
||||
domains = set(c.domain for c in catalogs)
|
||||
assert domains == set(['test1', 'test2', 'sub'])
|
||||
|
||||
@ -251,4 +244,5 @@ def test_get_filename_for_language():
|
||||
|
||||
# invalid figure_language_filename
|
||||
app.env.config.figure_language_filename = '{root}.{invalid}{ext}'
|
||||
raises(SphinxError, i18n.get_image_filename_for_language, 'foo.png', app.env)
|
||||
with pytest.raises(SphinxError):
|
||||
i18n.get_image_filename_for_language('foo.png', app.env)
|
||||
|
@ -9,10 +9,6 @@
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
from functools import wraps
|
||||
|
||||
from six import StringIO
|
||||
|
||||
from sphinx.websupport import WebSupport
|
||||
from sphinx.websupport.errors import DocumentNotFoundError, \
|
||||
CommentNotAllowedError, UserNotAuthorizedError
|
||||
@ -26,26 +22,28 @@ try:
|
||||
except ImportError:
|
||||
sqlalchemy_missing = True
|
||||
|
||||
from util import rootdir, tempdir, raises, skip_if
|
||||
import pytest
|
||||
from util import rootdir, tempdir, skip_if
|
||||
|
||||
|
||||
default_settings = {'builddir': tempdir / 'websupport',
|
||||
'status': StringIO(),
|
||||
'warning': StringIO()}
|
||||
@pytest.fixture
|
||||
def support(request):
|
||||
settings = {
|
||||
'srcdir': rootdir / 'root',
|
||||
# to use same directory for 'builddir' in each 'support' fixture, using
|
||||
# 'tempdir' (static) value instead of 'tempdir' fixture value.
|
||||
# each test expect result of db value at previous test case.
|
||||
'builddir': tempdir / 'websupport'
|
||||
}
|
||||
marker = request.node.get_marker('support')
|
||||
if marker:
|
||||
settings.update(marker.kwargs)
|
||||
|
||||
|
||||
def with_support(*args, **kwargs):
|
||||
"""Make a WebSupport object and pass it the test."""
|
||||
settings = default_settings.copy()
|
||||
settings.update(kwargs)
|
||||
|
||||
def generator(func):
|
||||
@wraps(func)
|
||||
def new_func(*args2, **kwargs2):
|
||||
support = WebSupport(**settings)
|
||||
func(support, *args2, **kwargs2)
|
||||
return new_func
|
||||
return generator
|
||||
yield support
|
||||
|
||||
|
||||
with_support = pytest.mark.support
|
||||
|
||||
|
||||
class NullStorage(StorageBackend):
|
||||
@ -55,11 +53,12 @@ class NullStorage(StorageBackend):
|
||||
@with_support(storage=NullStorage())
|
||||
def test_no_srcdir(support):
|
||||
# make sure the correct exception is raised if srcdir is not given.
|
||||
raises(RuntimeError, support.build)
|
||||
with pytest.raises(RuntimeError):
|
||||
support.build()
|
||||
|
||||
|
||||
@skip_if(sqlalchemy_missing, 'needs sqlalchemy')
|
||||
@with_support(srcdir=rootdir / 'root')
|
||||
@with_support()
|
||||
def test_build(support):
|
||||
support.build()
|
||||
|
||||
@ -67,7 +66,8 @@ def test_build(support):
|
||||
@skip_if(sqlalchemy_missing, 'needs sqlalchemy')
|
||||
@with_support()
|
||||
def test_get_document(support):
|
||||
raises(DocumentNotFoundError, support.get_document, 'nonexisting')
|
||||
with pytest.raises(DocumentNotFoundError):
|
||||
support.get_document('nonexisting')
|
||||
|
||||
contents = support.get_document('contents')
|
||||
assert contents['title'] and contents['body'] \
|
||||
@ -92,8 +92,8 @@ def test_comments(support):
|
||||
# Make sure that comments can't be added to a comment where
|
||||
# displayed == False, since it could break the algorithm that
|
||||
# converts a nodes comments to a tree.
|
||||
raises(CommentNotAllowedError, support.add_comment, 'Not allowed',
|
||||
parent_id=str(hidden_comment['id']))
|
||||
with pytest.raises(CommentNotAllowedError):
|
||||
support.add_comment('Not allowed', parent_id=str(hidden_comment['id']))
|
||||
# Add a displayed and not displayed child to the displayed comment.
|
||||
support.add_comment('Child test comment', parent_id=str(comment['id']),
|
||||
username='user_one')
|
||||
@ -123,56 +123,6 @@ def test_comments(support):
|
||||
assert children[0]['text'] == '<p>Child test comment</p>\n'
|
||||
|
||||
|
||||
@skip_if(sqlalchemy_missing, 'needs sqlalchemy')
|
||||
@with_support()
|
||||
def test_voting(support):
|
||||
session = Session()
|
||||
nodes = session.query(Node).all()
|
||||
node = nodes[0]
|
||||
|
||||
comment = support.get_data(node.id)['comments'][0]
|
||||
|
||||
def check_rating(val):
|
||||
data = support.get_data(node.id)
|
||||
comment = data['comments'][0]
|
||||
assert comment['rating'] == val, '%s != %s' % (comment['rating'], val)
|
||||
|
||||
support.process_vote(comment['id'], 'user_one', '1')
|
||||
support.process_vote(comment['id'], 'user_two', '1')
|
||||
support.process_vote(comment['id'], 'user_three', '1')
|
||||
check_rating(3)
|
||||
support.process_vote(comment['id'], 'user_one', '-1')
|
||||
check_rating(1)
|
||||
support.process_vote(comment['id'], 'user_one', '0')
|
||||
check_rating(2)
|
||||
|
||||
# Make sure a vote with value > 1 or < -1 can't be cast.
|
||||
raises(ValueError, support.process_vote, comment['id'], 'user_one', '2')
|
||||
raises(ValueError, support.process_vote, comment['id'], 'user_one', '-2')
|
||||
|
||||
# Make sure past voting data is associated with comments when they are
|
||||
# fetched.
|
||||
data = support.get_data(str(node.id), username='user_two')
|
||||
comment = data['comments'][0]
|
||||
assert comment['vote'] == 1, '%s != 1' % comment['vote']
|
||||
|
||||
|
||||
@skip_if(sqlalchemy_missing, 'needs sqlalchemy')
|
||||
@with_support()
|
||||
def test_proposals(support):
|
||||
session = Session()
|
||||
node = session.query(Node).first()
|
||||
|
||||
data = support.get_data(node.id)
|
||||
|
||||
source = data['source']
|
||||
proposal = source[:5] + source[10:15] + 'asdf' + source[15:]
|
||||
|
||||
support.add_comment('Proposal comment',
|
||||
node_id=node.id,
|
||||
proposal=proposal)
|
||||
|
||||
|
||||
@skip_if(sqlalchemy_missing, 'needs sqlalchemy')
|
||||
@with_support()
|
||||
def test_user_delete_comments(support):
|
||||
@ -185,8 +135,8 @@ def test_user_delete_comments(support):
|
||||
comment = get_comment()
|
||||
assert comment['username'] == 'user_one'
|
||||
# Make sure other normal users can't delete someone elses comments.
|
||||
raises(UserNotAuthorizedError, support.delete_comment,
|
||||
comment['id'], username='user_two')
|
||||
with pytest.raises(UserNotAuthorizedError):
|
||||
support.delete_comment(comment['id'], username='user_two')
|
||||
# Now delete the comment using the correct username.
|
||||
support.delete_comment(comment['id'], username='user_one')
|
||||
comment = get_comment()
|
||||
@ -194,40 +144,6 @@ def test_user_delete_comments(support):
|
||||
assert comment['text'] == '[deleted]'
|
||||
|
||||
|
||||
@skip_if(sqlalchemy_missing, 'needs sqlalchemy')
|
||||
@with_support()
|
||||
def test_moderator_delete_comments(support):
|
||||
def get_comment():
|
||||
session = Session()
|
||||
node = session.query(Node).first()
|
||||
session.close()
|
||||
return support.get_data(node.id, moderator=True)['comments'][1]
|
||||
|
||||
comment = get_comment()
|
||||
support.delete_comment(comment['id'], username='user_two',
|
||||
moderator=True)
|
||||
raises(IndexError, get_comment)
|
||||
|
||||
|
||||
@skip_if(sqlalchemy_missing, 'needs sqlalchemy')
|
||||
@with_support()
|
||||
def test_update_username(support):
|
||||
support.update_username('user_two', 'new_user_two')
|
||||
session = Session()
|
||||
comments = session.query(Comment).\
|
||||
filter(Comment.username == 'user_two').all()
|
||||
assert len(comments) == 0
|
||||
votes = session.query(CommentVote).\
|
||||
filter(CommentVote.username == 'user_two').all()
|
||||
assert len(votes) == 0
|
||||
comments = session.query(Comment).\
|
||||
filter(Comment.username == 'new_user_two').all()
|
||||
assert len(comments) == 1
|
||||
votes = session.query(CommentVote).\
|
||||
filter(CommentVote.username == 'new_user_two').all()
|
||||
assert len(votes) == 0
|
||||
|
||||
|
||||
called = False
|
||||
|
||||
|
||||
@ -250,8 +166,10 @@ def test_moderation(support):
|
||||
# Make sure the moderation_callback is called.
|
||||
assert called
|
||||
# Make sure the user must be a moderator.
|
||||
raises(UserNotAuthorizedError, support.accept_comment, accepted['id'])
|
||||
raises(UserNotAuthorizedError, support.delete_comment, deleted['id'])
|
||||
with pytest.raises(UserNotAuthorizedError):
|
||||
support.accept_comment(accepted['id'])
|
||||
with pytest.raises(UserNotAuthorizedError):
|
||||
support.delete_comment(deleted['id'])
|
||||
support.accept_comment(accepted['id'], moderator=True)
|
||||
support.delete_comment(deleted['id'], moderator=True)
|
||||
comments = support.get_data(node.id)['comments']
|
||||
@ -260,6 +178,93 @@ def test_moderation(support):
|
||||
assert len(comments) == 1
|
||||
|
||||
|
||||
@skip_if(sqlalchemy_missing, 'needs sqlalchemy')
|
||||
@with_support()
|
||||
def test_moderator_delete_comments(support):
|
||||
def get_comment():
|
||||
session = Session()
|
||||
node = session.query(Node).first()
|
||||
session.close()
|
||||
return support.get_data(node.id, moderator=True)['comments'][1]
|
||||
|
||||
comment = get_comment()
|
||||
support.delete_comment(comment['id'], username='user_two',
|
||||
moderator=True)
|
||||
with pytest.raises(IndexError):
|
||||
get_comment()
|
||||
|
||||
|
||||
@skip_if(sqlalchemy_missing, 'needs sqlalchemy')
|
||||
@with_support()
|
||||
def test_update_username(support):
|
||||
support.update_username('user_two', 'new_user_two')
|
||||
session = Session()
|
||||
comments = session.query(Comment).\
|
||||
filter(Comment.username == 'user_two').all()
|
||||
assert len(comments) == 0
|
||||
votes = session.query(CommentVote).\
|
||||
filter(CommentVote.username == 'user_two').all()
|
||||
assert len(votes) == 0
|
||||
comments = session.query(Comment).\
|
||||
filter(Comment.username == 'new_user_two').all()
|
||||
assert len(comments) == 1
|
||||
votes = session.query(CommentVote).\
|
||||
filter(CommentVote.username == 'new_user_two').all()
|
||||
assert len(votes) == 0
|
||||
|
||||
|
||||
@skip_if(sqlalchemy_missing, 'needs sqlalchemy')
|
||||
@with_support()
|
||||
def test_proposals(support):
|
||||
session = Session()
|
||||
node = session.query(Node).first()
|
||||
|
||||
data = support.get_data(node.id)
|
||||
|
||||
source = data['source']
|
||||
proposal = source[:5] + source[10:15] + 'asdf' + source[15:]
|
||||
|
||||
support.add_comment('Proposal comment',
|
||||
node_id=node.id,
|
||||
proposal=proposal)
|
||||
|
||||
|
||||
@skip_if(sqlalchemy_missing, 'needs sqlalchemy')
|
||||
@with_support()
|
||||
def test_voting(support):
|
||||
session = Session()
|
||||
nodes = session.query(Node).all()
|
||||
node = nodes[0]
|
||||
|
||||
comment = support.get_data(node.id)['comments'][0]
|
||||
|
||||
def check_rating(val):
|
||||
data = support.get_data(node.id)
|
||||
comment = data['comments'][0]
|
||||
assert comment['rating'] == val, '%s != %s' % (comment['rating'], val)
|
||||
|
||||
support.process_vote(comment['id'], 'user_one', '1')
|
||||
support.process_vote(comment['id'], 'user_two', '1')
|
||||
support.process_vote(comment['id'], 'user_three', '1')
|
||||
check_rating(3)
|
||||
support.process_vote(comment['id'], 'user_one', '-1')
|
||||
check_rating(1)
|
||||
support.process_vote(comment['id'], 'user_one', '0')
|
||||
check_rating(2)
|
||||
|
||||
# Make sure a vote with value > 1 or < -1 can't be cast.
|
||||
with pytest.raises(ValueError):
|
||||
support.process_vote(comment['id'], 'user_one', '2')
|
||||
with pytest.raises(ValueError):
|
||||
support.process_vote(comment['id'], 'user_one', '-2')
|
||||
|
||||
# Make sure past voting data is associated with comments when they are
|
||||
# fetched.
|
||||
data = support.get_data(str(node.id), username='user_two')
|
||||
comment = data['comments'][0]
|
||||
assert comment['vote'] == 1, '%s != 1' % comment['vote']
|
||||
|
||||
|
||||
def test_differ():
|
||||
source = 'Lorem ipsum dolor sit amet,\nconsectetur adipisicing elit,\n' \
|
||||
'sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'
|
||||
|
@ -11,7 +11,7 @@
|
||||
from __future__ import print_function
|
||||
from sphinx.writers.latex import rstdim_to_latexdim
|
||||
|
||||
from util import raises
|
||||
import pytest
|
||||
|
||||
|
||||
def test_rstdim_to_latexdim():
|
||||
@ -32,5 +32,6 @@ def test_rstdim_to_latexdim():
|
||||
assert rstdim_to_latexdim('.5em') == '.5em'
|
||||
|
||||
# unknown values (it might be generated by 3rd party extension)
|
||||
raises(ValueError, rstdim_to_latexdim, 'unknown')
|
||||
with pytest.raises(ValueError):
|
||||
rstdim_to_latexdim('unknown')
|
||||
assert rstdim_to_latexdim('160.0unknown') == '160.0unknown'
|
||||
|
315
tests/util.py
315
tests/util.py
@ -10,14 +10,13 @@
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import tempfile
|
||||
import warnings
|
||||
from functools import wraps
|
||||
from xml.etree import ElementTree
|
||||
|
||||
from six import StringIO, string_types
|
||||
from six import string_types
|
||||
|
||||
from nose import tools, SkipTest
|
||||
import pytest
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst import directives, roles
|
||||
@ -27,16 +26,17 @@ from sphinx.builders.latex import LaTeXBuilder
|
||||
from sphinx.theming import Theme
|
||||
from sphinx.ext.autodoc import AutoDirective
|
||||
from sphinx.pycode import ModuleAnalyzer
|
||||
from sphinx.deprecation import RemovedInSphinx17Warning
|
||||
|
||||
from path import path, repr_as # NOQA
|
||||
from path import path
|
||||
|
||||
|
||||
__all__ = [
|
||||
'rootdir', 'tempdir', 'raises', 'raises_msg',
|
||||
'skip_if', 'skip_unless', 'skip_unless_importable', 'Struct',
|
||||
'ListOutput', 'TestApp', 'with_app', 'gen_with_app',
|
||||
'path', 'with_tempdir',
|
||||
'sprint', 'remove_unicode_literals',
|
||||
'rootdir', 'tempdir',
|
||||
'skip_unless_importable', 'Struct',
|
||||
'SphinxTestApp',
|
||||
'path',
|
||||
'remove_unicode_literals',
|
||||
]
|
||||
|
||||
|
||||
@ -44,36 +44,6 @@ rootdir = path(os.path.dirname(__file__) or '.').abspath()
|
||||
tempdir = path(os.environ['SPHINX_TEST_TEMPDIR']).abspath()
|
||||
|
||||
|
||||
def _excstr(exc):
|
||||
if type(exc) is tuple:
|
||||
return str(tuple(map(_excstr, exc)))
|
||||
return exc.__name__
|
||||
|
||||
|
||||
def raises(exc, func, *args, **kwds):
|
||||
"""Raise AssertionError if ``func(*args, **kwds)`` does not raise *exc*."""
|
||||
try:
|
||||
func(*args, **kwds)
|
||||
except exc:
|
||||
pass
|
||||
else:
|
||||
raise AssertionError('%s did not raise %s' %
|
||||
(func.__name__, _excstr(exc)))
|
||||
|
||||
|
||||
def raises_msg(exc, msg, func, *args, **kwds):
|
||||
"""Raise AssertionError if ``func(*args, **kwds)`` does not raise *exc*,
|
||||
and check if the message contains *msg*.
|
||||
"""
|
||||
try:
|
||||
func(*args, **kwds)
|
||||
except exc as err:
|
||||
assert msg in str(err), "\"%s\" not in \"%s\"" % (msg, err)
|
||||
else:
|
||||
raise AssertionError('%s did not raise %s' %
|
||||
(func.__name__, _excstr(exc)))
|
||||
|
||||
|
||||
def assert_re_search(regex, text, flags=0):
|
||||
if not re.search(regex, text, flags):
|
||||
assert False, '%r did not match %r' % (regex, text)
|
||||
@ -118,43 +88,14 @@ def assert_node(node, cls=None, xpath="", **kwargs):
|
||||
'The node%s[%s] is not %r: %r' % (xpath, key, value, node[key])
|
||||
|
||||
|
||||
try:
|
||||
from nose.tools import assert_in, assert_not_in
|
||||
except ImportError:
|
||||
def assert_in(x, thing, msg=''):
|
||||
if x not in thing:
|
||||
assert False, msg or '%r is not in %r' % (x, thing)
|
||||
|
||||
def assert_not_in(x, thing, msg=''):
|
||||
if x in thing:
|
||||
assert False, msg or '%r is in %r' % (x, thing)
|
||||
|
||||
|
||||
def skip_if(condition, msg=None):
|
||||
"""Decorator to skip test if condition is true."""
|
||||
def deco(test):
|
||||
@tools.make_decorator(test)
|
||||
def skipper(*args, **kwds):
|
||||
if condition:
|
||||
raise SkipTest(msg or 'conditional skip')
|
||||
return test(*args, **kwds)
|
||||
return skipper
|
||||
return deco
|
||||
|
||||
|
||||
def skip_unless(condition, msg=None):
|
||||
"""Decorator to skip test if condition is false."""
|
||||
return skip_if(not condition, msg)
|
||||
|
||||
|
||||
def skip_unless_importable(module, msg=None):
|
||||
"""Decorator to skip test if module is not importable."""
|
||||
try:
|
||||
__import__(module)
|
||||
except ImportError:
|
||||
return skip_if(True, msg)
|
||||
return pytest.mark.skipif(True, reason=(msg or 'conditional skip'))
|
||||
else:
|
||||
return skip_if(False, msg)
|
||||
return pytest.mark.skipif(False, reason=(msg or 'conditional skip'))
|
||||
|
||||
|
||||
def etree_parse(path):
|
||||
@ -168,22 +109,7 @@ class Struct(object):
|
||||
self.__dict__.update(kwds)
|
||||
|
||||
|
||||
class ListOutput(object):
|
||||
"""
|
||||
File-like object that collects written text in a list.
|
||||
"""
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.content = []
|
||||
|
||||
def reset(self):
|
||||
del self.content[:]
|
||||
|
||||
def write(self, text):
|
||||
self.content.append(text)
|
||||
|
||||
|
||||
class TestApp(application.Sphinx):
|
||||
class SphinxTestApp(application.Sphinx):
|
||||
"""
|
||||
A subclass of :class:`Sphinx` that runs on the test root, with some
|
||||
better default values for the initialization parameters.
|
||||
@ -222,10 +148,6 @@ class TestApp(application.Sphinx):
|
||||
doctreedir.makedirs()
|
||||
if confoverrides is None:
|
||||
confoverrides = {}
|
||||
if status is None:
|
||||
status = StringIO()
|
||||
if warning is None:
|
||||
warning = ListOutput('stderr')
|
||||
# if warningiserror is None:
|
||||
warningiserror = False
|
||||
|
||||
@ -263,59 +185,6 @@ class TestApp(application.Sphinx):
|
||||
return '<%s buildername=%r>' % (self.__class__.__name__, self.builder.name)
|
||||
|
||||
|
||||
def with_app(*args, **kwargs):
|
||||
"""
|
||||
Make a TestApp with args and kwargs, pass it to the test and clean up
|
||||
properly.
|
||||
"""
|
||||
def generator(func):
|
||||
@wraps(func)
|
||||
def deco(*args2, **kwargs2):
|
||||
status, warning = StringIO(), StringIO()
|
||||
kwargs['status'] = status
|
||||
kwargs['warning'] = warning
|
||||
app = TestApp(*args, **kwargs)
|
||||
try:
|
||||
func(app, status, warning, *args2, **kwargs2)
|
||||
finally:
|
||||
app.cleanup()
|
||||
return deco
|
||||
return generator
|
||||
|
||||
|
||||
def gen_with_app(*args, **kwargs):
|
||||
"""
|
||||
Decorate a test generator to pass a TestApp as the first argument to the
|
||||
test generator when it's executed.
|
||||
"""
|
||||
def generator(func):
|
||||
@wraps(func)
|
||||
def deco(*args2, **kwargs2):
|
||||
status, warning = StringIO(), StringIO()
|
||||
kwargs['status'] = status
|
||||
kwargs['warning'] = warning
|
||||
app = TestApp(*args, **kwargs)
|
||||
try:
|
||||
for item in func(app, status, warning, *args2, **kwargs2):
|
||||
yield item
|
||||
finally:
|
||||
app.cleanup()
|
||||
return deco
|
||||
return generator
|
||||
|
||||
|
||||
def with_tempdir(func):
|
||||
def new_func(*args, **kwds):
|
||||
new_tempdir = path(tempfile.mkdtemp(dir=tempdir))
|
||||
func(new_tempdir, *args, **kwds)
|
||||
new_func.__name__ = func.__name__
|
||||
return new_func
|
||||
|
||||
|
||||
def sprint(*args):
|
||||
sys.stderr.write(' '.join(map(str, args)) + '\n')
|
||||
|
||||
|
||||
_unicode_literals_re = re.compile(r'u(".*?")|u(\'.*?\')')
|
||||
|
||||
|
||||
@ -333,3 +202,163 @@ def find_files(root, suffix=None):
|
||||
|
||||
def strip_escseq(text):
|
||||
return re.sub('\x1b.*?m', '', text)
|
||||
|
||||
|
||||
# #############################################
|
||||
# DEPRECATED implementations
|
||||
|
||||
import tempfile
|
||||
from six import StringIO
|
||||
|
||||
|
||||
def gen_with_app(*args, **kwargs):
|
||||
"""
|
||||
**DEPRECATED**: use pytest.mark.parametrize instead.
|
||||
|
||||
Decorate a test generator to pass a SphinxTestApp as the first argument to
|
||||
the test generator when it's executed.
|
||||
"""
|
||||
def generator(func):
|
||||
@wraps(func)
|
||||
def deco(*args2, **kwargs2):
|
||||
status, warning = StringIO(), StringIO()
|
||||
kwargs['status'] = status
|
||||
kwargs['warning'] = warning
|
||||
app = SphinxTestApp(*args, **kwargs)
|
||||
try:
|
||||
for item in func(app, status, warning, *args2, **kwargs2):
|
||||
yield item
|
||||
finally:
|
||||
app.cleanup()
|
||||
return deco
|
||||
return generator
|
||||
|
||||
|
||||
def skip_if(condition, msg=None):
|
||||
"""
|
||||
**DEPRECATED**: use pytest.mark.skipif instead.
|
||||
|
||||
Decorator to skip test if condition is true.
|
||||
"""
|
||||
return pytest.mark.skipif(condition, reason=(msg or 'conditional skip'))
|
||||
|
||||
|
||||
def skip_unless(condition, msg=None):
|
||||
"""
|
||||
**DEPRECATED**: use pytest.mark.skipif instead.
|
||||
|
||||
Decorator to skip test if condition is false.
|
||||
"""
|
||||
return pytest.mark.skipif(not condition, reason=(msg or 'conditional skip'))
|
||||
|
||||
|
||||
def with_tempdir(func):
|
||||
"""
|
||||
**DEPRECATED**: use tempdir fixture instead.
|
||||
"""
|
||||
return func
|
||||
|
||||
|
||||
def raises(exc, func, *args, **kwds):
|
||||
"""
|
||||
**DEPRECATED**: use pytest.raises instead.
|
||||
|
||||
Raise AssertionError if ``func(*args, **kwds)`` does not raise *exc*.
|
||||
"""
|
||||
with pytest.raises(exc):
|
||||
func(*args, **kwds)
|
||||
|
||||
|
||||
def raises_msg(exc, msg, func, *args, **kwds):
|
||||
"""
|
||||
**DEPRECATED**: use pytest.raises instead.
|
||||
|
||||
Raise AssertionError if ``func(*args, **kwds)`` does not raise *exc*,
|
||||
and check if the message contains *msg*.
|
||||
"""
|
||||
with pytest.raises(exc) as excinfo:
|
||||
func(*args, **kwds)
|
||||
assert msg in str(excinfo.value)
|
||||
|
||||
|
||||
def assert_true(v1, msg=''):
|
||||
"""
|
||||
**DEPRECATED**: use assert instead.
|
||||
"""
|
||||
assert v1, msg
|
||||
|
||||
|
||||
def assert_equal(v1, v2, msg=''):
|
||||
"""
|
||||
**DEPRECATED**: use assert instead.
|
||||
"""
|
||||
assert v1 == v2, msg
|
||||
|
||||
|
||||
def assert_in(x, thing, msg=''):
|
||||
"""
|
||||
**DEPRECATED**: use assert instead.
|
||||
"""
|
||||
if x not in thing:
|
||||
assert False, msg or '%r is not in %r' % (x, thing)
|
||||
|
||||
|
||||
def assert_not_in(x, thing, msg=''):
|
||||
"""
|
||||
**DEPRECATED**: use assert instead.
|
||||
"""
|
||||
if x in thing:
|
||||
assert False, msg or '%r is in %r' % (x, thing)
|
||||
|
||||
|
||||
class ListOutput(object):
|
||||
"""
|
||||
File-like object that collects written text in a list.
|
||||
"""
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.content = []
|
||||
|
||||
def reset(self):
|
||||
del self.content[:]
|
||||
|
||||
def write(self, text):
|
||||
self.content.append(text)
|
||||
|
||||
|
||||
# **DEPRECATED**: use pytest.skip instead.
|
||||
SkipTest = pytest.skip.Exception
|
||||
|
||||
|
||||
class _DeprecationWrapper(object):
|
||||
def __init__(self, mod, deprecated):
|
||||
self._mod = mod
|
||||
self._deprecated = deprecated
|
||||
|
||||
def __getattr__(self, attr):
|
||||
if attr in self._deprecated:
|
||||
obj, instead = self._deprecated[attr]
|
||||
warnings.warn("tests/util.py::%s is deprecated and will be "
|
||||
"removed in Sphinx 1.7, please use %s instead."
|
||||
% (attr, instead),
|
||||
RemovedInSphinx17Warning, stacklevel=2)
|
||||
return obj
|
||||
return getattr(self._mod, attr)
|
||||
|
||||
|
||||
sys.modules[__name__] = _DeprecationWrapper(sys.modules[__name__], dict( # type: ignore
|
||||
with_app=(pytest.mark.sphinx, 'pytest.mark.sphinx'),
|
||||
TestApp=(SphinxTestApp, 'SphinxTestApp'),
|
||||
gen_with_app=(gen_with_app, 'pytest.mark.parametrize'),
|
||||
skip_if=(skip_if, 'pytest.skipif'),
|
||||
skip_unless=(skip_unless, 'pytest.skipif'),
|
||||
with_tempdir=(with_tempdir, 'tmpdir pytest fixture'),
|
||||
raises=(raises, 'pytest.raises'),
|
||||
raises_msg=(raises_msg, 'pytest.raises'),
|
||||
assert_true=(assert_true, 'assert'),
|
||||
assert_equal=(assert_equal, 'assert'),
|
||||
assert_in=(assert_in, 'assert'),
|
||||
assert_not_in=(assert_not_in, 'assert'),
|
||||
ListOutput=(ListOutput, 'StringIO'),
|
||||
SkipTest=(SkipTest, 'pytest.skip'),
|
||||
))
|
||||
|
Loading…
Reference in New Issue
Block a user