mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge branch 'stable' into 3256_update_release_script
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,6 +4,7 @@
|
||||
*.swp
|
||||
|
||||
.dir-locals.el
|
||||
.cache/
|
||||
.mypy_cache/
|
||||
.ropeproject/
|
||||
TAGS
|
||||
|
||||
@@ -4,15 +4,15 @@ cache:
|
||||
directories:
|
||||
- $HOME/.cache/pip
|
||||
python:
|
||||
- "pypy"
|
||||
- "2.7"
|
||||
- "3.4"
|
||||
- "3.5"
|
||||
- "3.6"
|
||||
- "nightly"
|
||||
- "pypy"
|
||||
env:
|
||||
global:
|
||||
- TEST='-v --with-timer --timer-top-n 25'
|
||||
- TEST='-v --durations 25'
|
||||
- PYTHONFAULTHANDLER=x
|
||||
- PYTHONWARNINGS=all
|
||||
matrix:
|
||||
|
||||
12
CHANGES
12
CHANGES
@@ -1,12 +1,18 @@
|
||||
Release 1.5.2 (in development)
|
||||
===============================
|
||||
|
||||
Incompatible changes
|
||||
--------------------
|
||||
|
||||
* Dependency requirement updates: requests 2.4.0 or above (refs: #3268, #3310)
|
||||
|
||||
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)
|
||||
* #978: `intersphinx_mapping` also allows a list as a parameter
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
@@ -21,6 +27,12 @@ Bugs fixed
|
||||
* 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)
|
||||
* #3268: Sphinx crashes with requests package from Debian jessie
|
||||
* #3284: Sphinx crashes on parallel build with an extension which raises
|
||||
unserializable exception
|
||||
* #3315: Bibliography crashes on latex build with docclass 'memoir'
|
||||
* #3328: Could not refer rubric implicitly
|
||||
* #3329: emit warnings if po file is invalid and can't read it. Also writing mo too.
|
||||
|
||||
|
||||
Release 1.5.1 (released Dec 13, 2016)
|
||||
|
||||
10
Makefile
10
Makefile
@@ -6,7 +6,7 @@ PYTHON ?= python
|
||||
DONT_CHECK = -i build -i dist -i sphinx/style/jquery.js \
|
||||
-i sphinx/pycode/pgen2 -i sphinx/util/smartypants.py \
|
||||
-i .ropeproject -i doc/_build -i tests/path.py \
|
||||
-i tests/coverage.py -i utils/convert.py \
|
||||
-i utils/convert.py \
|
||||
-i tests/typing_test_data.py \
|
||||
-i tests/test_autodoc_py35.py \
|
||||
-i tests/roots/test-warnings/undecodable.rst \
|
||||
@@ -65,6 +65,7 @@ clean-testfiles:
|
||||
rm -rf tests/.coverage
|
||||
rm -rf tests/build
|
||||
rm -rf .tox/
|
||||
rm -rf .cache/
|
||||
|
||||
clean-buildfiles:
|
||||
rm -rf build
|
||||
@@ -79,14 +80,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
|
||||
|
||||
@@ -94,14 +94,14 @@ This section describe a easy way to translate with sphinx-intl.
|
||||
|
||||
$ make gettext
|
||||
|
||||
As a result, many pot files are generated under ``_build/locale``
|
||||
As a result, many pot files are generated under ``_build/gettext``
|
||||
directory.
|
||||
|
||||
#. Setup/Update your `locale_dir`:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ sphinx-intl update -p _build/locale -l de -l ja
|
||||
$ sphinx-intl update -p _build/gettext -l de -l ja
|
||||
|
||||
Done. You got these directories that contain po files:
|
||||
|
||||
|
||||
@@ -25,5 +25,5 @@ universal = 1
|
||||
|
||||
[flake8]
|
||||
max-line-length = 95
|
||||
ignore = E113,E116,E221,E226,E241,E251,E901
|
||||
ignore = E116,E241,E251
|
||||
exclude = .git,.tox,tests/*,build/*,sphinx/search/*,sphinx/pycode/pgen2/*,doc/ext/example*.py
|
||||
2
setup.py
2
setup.py
@@ -50,7 +50,7 @@ requires = [
|
||||
'babel>=1.3,!=2.0',
|
||||
'alabaster>=0.7,<0.8',
|
||||
'imagesize',
|
||||
'requests',
|
||||
'requests>=2.4.0',
|
||||
]
|
||||
extras_require = {
|
||||
# Environment Marker works for wheel 0.24 or later
|
||||
|
||||
@@ -30,7 +30,7 @@ if 'PYTHONWARNINGS' not in os.environ:
|
||||
warnings.filterwarnings('ignore', "'U' mode is deprecated",
|
||||
DeprecationWarning, module='docutils.io')
|
||||
|
||||
__version__ = '1.5.2+'
|
||||
__version__ = '1.5.2+'
|
||||
__released__ = '1.5.2' # used when Sphinx builds its own docs
|
||||
|
||||
# version info for better programmatic use
|
||||
|
||||
@@ -368,8 +368,8 @@ Note: By default this script will not overwrite already created files.""")
|
||||
text += ' %s\n' % module
|
||||
d = dict(
|
||||
path = opts.destdir,
|
||||
sep = False,
|
||||
dot = '_',
|
||||
sep = False,
|
||||
dot = '_',
|
||||
project = opts.header,
|
||||
author = opts.author or 'Author',
|
||||
version = opts.version or '',
|
||||
|
||||
@@ -258,7 +258,7 @@ class Sphinx(object):
|
||||
for catinfo in find_catalog_source_files(
|
||||
user_locale_dirs, self.config.language, domains=['sphinx'],
|
||||
charset=self.config.source_encoding):
|
||||
catinfo.write_mo(self.config.language)
|
||||
catinfo.write_mo(self.config.language, self.warn)
|
||||
locale_dirs = [None, path.join(package_dir, 'locale')] + user_locale_dirs
|
||||
else:
|
||||
locale_dirs = []
|
||||
@@ -484,7 +484,7 @@ class Sphinx(object):
|
||||
summary = bold(summary)
|
||||
for item in iterable:
|
||||
l += 1
|
||||
s = '%s[%3d%%] %s' % (summary, 100*l/length,
|
||||
s = '%s[%3d%%] %s' % (summary, 100 * l / length,
|
||||
colorfunc(stringify_func(item)))
|
||||
if self.verbosity:
|
||||
s += '\n'
|
||||
@@ -660,9 +660,9 @@ class Sphinx(object):
|
||||
else:
|
||||
# ignore invalid keys for compatibility
|
||||
continue
|
||||
setattr(translator, 'visit_'+node.__name__, visit)
|
||||
setattr(translator, 'visit_' + node.__name__, visit)
|
||||
if depart:
|
||||
setattr(translator, 'depart_'+node.__name__, depart)
|
||||
setattr(translator, 'depart_' + node.__name__, depart)
|
||||
|
||||
def add_enumerable_node(self, node, figtype, title_getter=None, **kwds):
|
||||
self.enumerable_nodes[node] = (figtype, title_getter)
|
||||
|
||||
@@ -167,7 +167,7 @@ class Builder(object):
|
||||
for catalog in self.app.status_iterator(
|
||||
catalogs, 'writing output... ', darkgreen, len(catalogs),
|
||||
cat2relpath):
|
||||
catalog.write_mo(self.config.language)
|
||||
catalog.write_mo(self.config.language, self.warn)
|
||||
|
||||
def compile_all_catalogs(self):
|
||||
catalogs = i18n.find_catalog_source_files(
|
||||
|
||||
@@ -130,7 +130,7 @@ class ChangesBuilder(Builder):
|
||||
targetfn = path.join(self.outdir, 'rst', os_path(docname)) + '.html'
|
||||
ensuredir(path.dirname(targetfn))
|
||||
with codecs.open(targetfn, 'w', 'utf-8') as f:
|
||||
text = ''.join(hl(i+1, line) for (i, line) in enumerate(lines))
|
||||
text = ''.join(hl(i + 1, line) for (i, line) in enumerate(lines))
|
||||
ctx = {
|
||||
'filename': self.env.doc2path(docname, None),
|
||||
'text': text
|
||||
|
||||
@@ -498,7 +498,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
|
||||
# additional pages from conf.py
|
||||
for pagename, template in self.config.html_additional_pages.items():
|
||||
self.info(' '+pagename, nonl=1)
|
||||
self.info(' ' + pagename, nonl=1)
|
||||
self.handle_page(pagename, {}, template)
|
||||
|
||||
# the search page
|
||||
@@ -953,7 +953,7 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder):
|
||||
hashindex = refuri.find('#')
|
||||
if hashindex < 0:
|
||||
continue
|
||||
hashindex = refuri.find('#', hashindex+1)
|
||||
hashindex = refuri.find('#', hashindex + 1)
|
||||
if hashindex >= 0:
|
||||
refnode['refuri'] = fname + refuri[hashindex:]
|
||||
|
||||
@@ -1059,7 +1059,7 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder):
|
||||
|
||||
# additional pages from conf.py
|
||||
for pagename, template in self.config.html_additional_pages.items():
|
||||
self.info(' '+pagename, nonl=1)
|
||||
self.info(' ' + pagename, nonl=1)
|
||||
self.handle_page(pagename, {}, template)
|
||||
|
||||
if self.config.html_use_opensearch:
|
||||
|
||||
@@ -208,12 +208,12 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
|
||||
|
||||
def build_hhx(self, outdir, outname):
|
||||
self.info('dumping stopword list...')
|
||||
with self.open_file(outdir, outname+'.stp') as f:
|
||||
with self.open_file(outdir, outname + '.stp') as f:
|
||||
for word in sorted(stopwords):
|
||||
print(word, file=f)
|
||||
|
||||
self.info('writing project file...')
|
||||
with self.open_file(outdir, outname+'.hhp') as f:
|
||||
with self.open_file(outdir, outname + '.hhp') as f:
|
||||
f.write(project_template % {
|
||||
'outname': outname,
|
||||
'title': self.config.html_title,
|
||||
@@ -234,7 +234,7 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
|
||||
file=f)
|
||||
|
||||
self.info('writing TOC file...')
|
||||
with self.open_file(outdir, outname+'.hhc') as f:
|
||||
with self.open_file(outdir, outname + '.hhc') as f:
|
||||
f.write(contents_header)
|
||||
# special books
|
||||
f.write('<LI> ' + object_sitemap % (self.config.html_short_title,
|
||||
@@ -259,7 +259,7 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
|
||||
if ullevel != 0:
|
||||
f.write('<UL>\n')
|
||||
for subnode in node:
|
||||
write_toc(subnode, ullevel+1)
|
||||
write_toc(subnode, ullevel + 1)
|
||||
if ullevel != 0:
|
||||
f.write('</UL>\n')
|
||||
elif isinstance(node, addnodes.compact_paragraph):
|
||||
@@ -275,7 +275,7 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
|
||||
|
||||
self.info('writing index file...')
|
||||
index = self.env.create_index(self)
|
||||
with self.open_file(outdir, outname+'.hhk') as f:
|
||||
with self.open_file(outdir, outname + '.hhk') as f:
|
||||
f.write('<UL>\n')
|
||||
|
||||
def write_index(title, refs, subitems):
|
||||
|
||||
@@ -74,7 +74,7 @@ class LaTeXBuilder(Builder):
|
||||
'document %s' % docname)
|
||||
continue
|
||||
self.document_data.append(entry)
|
||||
if docname.endswith(SEP+'index'):
|
||||
if docname.endswith(SEP + 'index'):
|
||||
docname = docname[:-5]
|
||||
self.titles.append((docname, entry[2]))
|
||||
|
||||
@@ -188,7 +188,7 @@ class LaTeXBuilder(Builder):
|
||||
if self.images:
|
||||
self.info(bold('copying images...'), nonl=1)
|
||||
for src, dest in iteritems(self.images):
|
||||
self.info(' '+src, nonl=1)
|
||||
self.info(' ' + src, nonl=1)
|
||||
copy_asset_file(path.join(self.srcdir, src),
|
||||
path.join(self.outdir, dest))
|
||||
self.info()
|
||||
@@ -206,7 +206,7 @@ class LaTeXBuilder(Builder):
|
||||
if self.config.latex_additional_files:
|
||||
self.info(bold('copying additional files...'), nonl=1)
|
||||
for filename in self.config.latex_additional_files:
|
||||
self.info(' '+filename, nonl=1)
|
||||
self.info(' ' + filename, nonl=1)
|
||||
copy_asset_file(path.join(self.confdir, filename), self.outdir)
|
||||
self.info()
|
||||
|
||||
|
||||
@@ -225,7 +225,7 @@ class CheckExternalLinksBuilder(Builder):
|
||||
self.info(darkgray('-local- ') + uri)
|
||||
self.write_entry('local', docname, lineno, uri)
|
||||
elif status == 'working':
|
||||
self.info(darkgreen('ok ') + uri + info)
|
||||
self.info(darkgreen('ok ') + uri + info)
|
||||
elif status == 'broken':
|
||||
self.write_entry('broken', docname, lineno, uri + ': ' + info)
|
||||
if self.app.quiet or self.app.warningiserror:
|
||||
@@ -243,7 +243,7 @@ class CheckExternalLinksBuilder(Builder):
|
||||
}[code]
|
||||
self.write_entry('redirected ' + text, docname, lineno,
|
||||
uri + ' to ' + info)
|
||||
self.info(color('redirect ') + uri + color(' - ' + text + ' to ' + info))
|
||||
self.info(color('redirect ') + uri + color(' - ' + text + ' to ' + info))
|
||||
|
||||
def get_target_uri(self, docname, typ=None):
|
||||
return ''
|
||||
|
||||
@@ -89,7 +89,7 @@ project_template = u'''\
|
||||
'''
|
||||
|
||||
section_template = '<section title="%(title)s" ref="%(ref)s"/>'
|
||||
file_template = ' '*12 + '<file>%(filename)s</file>'
|
||||
file_template = ' ' * 12 + '<file>%(filename)s</file>'
|
||||
|
||||
|
||||
class QtHelpBuilder(StandaloneHTMLBuilder):
|
||||
@@ -190,7 +190,7 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
|
||||
nspace = nspace.lower()
|
||||
|
||||
# write the project file
|
||||
with codecs.open(path.join(outdir, outname+'.qhp'), 'w', 'utf-8') as f:
|
||||
with codecs.open(path.join(outdir, outname + '.qhp'), 'w', 'utf-8') as f:
|
||||
f.write(project_template % {
|
||||
'outname': htmlescape(outname),
|
||||
'title': htmlescape(self.config.html_title),
|
||||
@@ -207,7 +207,7 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
|
||||
startpage = 'qthelp://' + posixpath.join(nspace, 'doc', 'index.html')
|
||||
|
||||
self.info('writing collection project file...')
|
||||
with codecs.open(path.join(outdir, outname+'.qhcp'), 'w', 'utf-8') as f:
|
||||
with codecs.open(path.join(outdir, outname + '.qhcp'), 'w', 'utf-8') as f:
|
||||
f.write(collection_template % {
|
||||
'outname': htmlescape(outname),
|
||||
'title': htmlescape(self.config.html_short_title),
|
||||
@@ -236,10 +236,10 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
|
||||
title = htmlescape(refnode.astext()).replace('"', '"')
|
||||
item = '<section title="%(title)s" ref="%(ref)s">' % \
|
||||
{'title': title, 'ref': link}
|
||||
parts.append(' '*4*indentlevel + item)
|
||||
parts.append(' ' * 4 * indentlevel + item)
|
||||
for subnode in node.children[1]:
|
||||
parts.extend(self.write_toc(subnode, indentlevel+1))
|
||||
parts.append(' '*4*indentlevel + '</section>')
|
||||
parts.extend(self.write_toc(subnode, indentlevel + 1))
|
||||
parts.append(' ' * 4 * indentlevel + '</section>')
|
||||
elif isinstance(node, nodes.list_item):
|
||||
for subnode in node:
|
||||
parts.extend(self.write_toc(subnode, indentlevel))
|
||||
@@ -272,10 +272,10 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
|
||||
id = None
|
||||
|
||||
if id:
|
||||
item = ' '*12 + '<keyword name="%s" id="%s" ref="%s"/>' % (
|
||||
item = ' ' * 12 + '<keyword name="%s" id="%s" ref="%s"/>' % (
|
||||
name, id, ref[1])
|
||||
else:
|
||||
item = ' '*12 + '<keyword name="%s" ref="%s"/>' % (name, ref[1])
|
||||
item = ' ' * 12 + '<keyword name="%s" ref="%s"/>' % (name, ref[1])
|
||||
item.encode('ascii', 'xmlcharrefreplace')
|
||||
return item
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ class TexinfoBuilder(Builder):
|
||||
'document %s' % docname)
|
||||
continue
|
||||
self.document_data.append(entry)
|
||||
if docname.endswith(SEP+'index'):
|
||||
if docname.endswith(SEP + 'index'):
|
||||
docname = docname[:-5]
|
||||
self.titles.append((docname, entry[2]))
|
||||
|
||||
@@ -210,7 +210,7 @@ class TexinfoBuilder(Builder):
|
||||
if self.images:
|
||||
self.info(bold('copying images...'), nonl=1)
|
||||
for src, dest in iteritems(self.images):
|
||||
self.info(' '+src, nonl=1)
|
||||
self.info(' ' + src, nonl=1)
|
||||
copyfile(path.join(self.srcdir, src),
|
||||
path.join(self.outdir, dest))
|
||||
self.info()
|
||||
|
||||
@@ -141,7 +141,7 @@ class WebSupportBuilder(PickleHTMLBuilder):
|
||||
# "show source" link
|
||||
if ctx.get('sourcename'):
|
||||
source_name = path.join(self.staticdir,
|
||||
'_sources', os_path(ctx['sourcename']))
|
||||
'_sources', os_path(ctx['sourcename']))
|
||||
ensuredir(path.dirname(source_name))
|
||||
copyfile(self.env.doc2path(pagename), source_name)
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ class CodeBlock(Directive):
|
||||
if linespec:
|
||||
try:
|
||||
nlines = len(self.content)
|
||||
hl_lines = [x+1 for x in parselinenos(linespec, nlines)]
|
||||
hl_lines = [x + 1 for x in parselinenos(linespec, nlines)]
|
||||
except ValueError as err:
|
||||
document = self.state.document
|
||||
return [document.reporter.warning(str(err), line=self.lineno)]
|
||||
@@ -266,7 +266,7 @@ class LiteralInclude(Directive):
|
||||
'Object named %r not found in include file %r' %
|
||||
(objectname, filename), line=self.lineno)]
|
||||
else:
|
||||
lines = lines[tags[objectname][1]-1: tags[objectname][2]-1]
|
||||
lines = lines[tags[objectname][1] - 1: tags[objectname][2] - 1]
|
||||
if 'lineno-match' in self.options:
|
||||
linenostart = tags[objectname][1]
|
||||
|
||||
@@ -298,7 +298,7 @@ class LiteralInclude(Directive):
|
||||
linespec = self.options.get('emphasize-lines')
|
||||
if linespec:
|
||||
try:
|
||||
hl_lines = [x+1 for x in parselinenos(linespec, len(lines))]
|
||||
hl_lines = [x + 1 for x in parselinenos(linespec, len(lines))]
|
||||
except ValueError as err:
|
||||
return [document.reporter.warning(str(err), line=self.lineno)]
|
||||
else:
|
||||
|
||||
@@ -204,7 +204,7 @@ class VersionChange(Directive):
|
||||
text = versionlabels[self.name] % self.arguments[0]
|
||||
if len(self.arguments) == 2:
|
||||
inodes, messages = self.state.inline_text(self.arguments[1],
|
||||
self.lineno+1)
|
||||
self.lineno + 1)
|
||||
para = nodes.paragraph(self.arguments[1], '', *inodes, translatable=False)
|
||||
set_source_info(self, para)
|
||||
node.append(para)
|
||||
@@ -325,7 +325,7 @@ class HList(Directive):
|
||||
index = 0
|
||||
newnode = addnodes.hlist()
|
||||
for column in range(ncolumns):
|
||||
endindex = index + (column < nmore and (npercol+1) or npercol)
|
||||
endindex = index + (column < nmore and (npercol + 1) or npercol)
|
||||
col = addnodes.hlistcol()
|
||||
col += nodes.bullet_list()
|
||||
col[0] += fulllist.children[index:endindex]
|
||||
|
||||
@@ -77,7 +77,7 @@ class CObject(ObjectDescription):
|
||||
# add cross-ref nodes for all words
|
||||
for part in [_f for _f in wsplit_re.split(ctype) if _f]:
|
||||
tnode = nodes.Text(part, part)
|
||||
if part[0] in string.ascii_letters+'_' and \
|
||||
if part[0] in string.ascii_letters + '_' and \
|
||||
part not in self.stopwords:
|
||||
pnode = addnodes.pending_xref(
|
||||
'', refdomain='c', reftype='type', reftarget=part,
|
||||
@@ -162,7 +162,7 @@ class CObject(ObjectDescription):
|
||||
ctype, argname = arg.rsplit(' ', 1)
|
||||
self._parse_type(param, ctype)
|
||||
# separate by non-breaking space in the output
|
||||
param += nodes.emphasis(' '+argname, u'\xa0'+argname)
|
||||
param += nodes.emphasis(' ' + argname, u'\xa0' + argname)
|
||||
except ValueError:
|
||||
# no argument name given, only the type
|
||||
self._parse_type(param, arg)
|
||||
@@ -230,7 +230,7 @@ class CXRefRole(XRefRole):
|
||||
title = title[1:]
|
||||
dot = title.rfind('.')
|
||||
if dot != -1:
|
||||
title = title[dot+1:]
|
||||
title = title[dot + 1:]
|
||||
return title, target
|
||||
|
||||
|
||||
|
||||
@@ -2885,14 +2885,14 @@ class Symbol(object):
|
||||
assert False # should have returned in the loop
|
||||
|
||||
def to_string(self, indent):
|
||||
res = ['\t'*indent]
|
||||
res = ['\t' * indent]
|
||||
if not self.parent:
|
||||
res.append('::')
|
||||
else:
|
||||
if self.templateParams:
|
||||
res.append(text_type(self.templateParams))
|
||||
res.append('\n')
|
||||
res.append('\t'*indent)
|
||||
res.append('\t' * indent)
|
||||
if self.identifier:
|
||||
res.append(text_type(self.identifier))
|
||||
else:
|
||||
|
||||
@@ -148,7 +148,7 @@ class JSXRefRole(XRefRole):
|
||||
title = title[1:]
|
||||
dot = title.rfind('.')
|
||||
if dot != -1:
|
||||
title = title[dot+1:]
|
||||
title = title[dot + 1:]
|
||||
if target[0:1] == '.':
|
||||
target = target[1:]
|
||||
refnode['refspecific'] = True
|
||||
|
||||
@@ -527,7 +527,7 @@ class PyXRefRole(XRefRole):
|
||||
title = title[1:]
|
||||
dot = title.rfind('.')
|
||||
if dot != -1:
|
||||
title = title[dot+1:]
|
||||
title = title[dot + 1:]
|
||||
# if the first character is a dot, search more specific namespaces first
|
||||
# else search builtins first
|
||||
if target[0:1] == '.':
|
||||
|
||||
@@ -58,7 +58,7 @@ class GenericObject(ObjectDescription):
|
||||
colon = self.indextemplate.find(':')
|
||||
if colon != -1:
|
||||
indextype = self.indextemplate[:colon].strip()
|
||||
indexentry = self.indextemplate[colon+1:].strip() % (name,)
|
||||
indexentry = self.indextemplate[colon + 1:].strip() % (name,)
|
||||
else:
|
||||
indextype = 'single'
|
||||
indexentry = self.indextemplate % (name,)
|
||||
@@ -118,7 +118,7 @@ class Target(Directive):
|
||||
colon = indexentry.find(':')
|
||||
if colon != -1:
|
||||
indextype = indexentry[:colon].strip()
|
||||
indexentry = indexentry[colon+1:].strip()
|
||||
indexentry = indexentry[colon + 1:].strip()
|
||||
inode = addnodes.index(entries=[(indextype, indexentry,
|
||||
targetname, '', None)])
|
||||
ret.insert(0, inode)
|
||||
@@ -566,7 +566,7 @@ class StandardDomain(Domain):
|
||||
env.warn_node('duplicate label %s, ' % name + 'other instance '
|
||||
'in ' + env.doc2path(labels[name][0]), node)
|
||||
anonlabels[name] = docname, labelid
|
||||
if node.tagname == 'section':
|
||||
if node.tagname in ('section', 'rubric'):
|
||||
sectname = clean_astext(node[0]) # node[0] == title node
|
||||
elif self.is_enumerable_node(node):
|
||||
sectname = self.get_numfig_title(node)
|
||||
@@ -673,13 +673,13 @@ class StandardDomain(Domain):
|
||||
else:
|
||||
title = env.config.numfig_format.get(figtype, '')
|
||||
|
||||
if figname is None and '%{name}' in title:
|
||||
if figname is None and '{name}' in title:
|
||||
env.warn_node('the link has no caption: %s' % title, node)
|
||||
return contnode
|
||||
else:
|
||||
fignum = '.'.join(map(str, fignumber))
|
||||
if '{name}' in title or 'number' in title:
|
||||
# new style format (cf. "Fig.%{number}")
|
||||
# new style format (cf. "Fig.{number}")
|
||||
if figname:
|
||||
newtitle = title.format(name=figname, number=fignum)
|
||||
else:
|
||||
|
||||
@@ -632,7 +632,7 @@ class BuildEnvironment(object):
|
||||
lineno = error.object.count(b'\n', 0, error.start) + 1
|
||||
self.warn(self.docname, 'undecodable source characters, '
|
||||
'replacing with "?": %r' %
|
||||
(error.object[linestart+1:error.start] + b'>>>' +
|
||||
(error.object[linestart + 1:error.start] + b'>>>' +
|
||||
error.object[error.start:error.end] + b'<<<' +
|
||||
error.object[error.end:lineend]), lineno)
|
||||
return (u'?', error.end)
|
||||
|
||||
@@ -224,11 +224,11 @@ class Toctree(EnvironmentManager):
|
||||
if isinstance(subnode, (addnodes.compact_paragraph,
|
||||
nodes.list_item)):
|
||||
# for <p> and <li>, indicate the depth level and recurse
|
||||
subnode['classes'].append('toctree-l%d' % (depth-1))
|
||||
subnode['classes'].append('toctree-l%d' % (depth - 1))
|
||||
_toctree_add_classes(subnode, depth)
|
||||
elif isinstance(subnode, nodes.bullet_list):
|
||||
# for <ul>, just recurse
|
||||
_toctree_add_classes(subnode, depth+1)
|
||||
_toctree_add_classes(subnode, depth + 1)
|
||||
elif isinstance(subnode, nodes.reference):
|
||||
# for <a>, identify which entries point to the current
|
||||
# document and therefore may not be collapsed
|
||||
@@ -417,7 +417,7 @@ class Toctree(EnvironmentManager):
|
||||
subnode.parent.remove(subnode)
|
||||
else:
|
||||
# recurse on visible children
|
||||
self._toctree_prune(subnode, depth+1, maxdepth, collapse)
|
||||
self._toctree_prune(subnode, depth + 1, maxdepth, collapse)
|
||||
|
||||
def assign_section_numbers(self):
|
||||
"""Assign a section number to each heading under a numbered toctree."""
|
||||
@@ -434,7 +434,7 @@ class Toctree(EnvironmentManager):
|
||||
for subnode in node.children:
|
||||
if isinstance(subnode, nodes.bullet_list):
|
||||
numstack.append(0)
|
||||
_walk_toc(subnode, secnums, depth-1, titlenode)
|
||||
_walk_toc(subnode, secnums, depth - 1, titlenode)
|
||||
numstack.pop()
|
||||
titlenode = None
|
||||
elif isinstance(subnode, nodes.list_item):
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
import traceback
|
||||
|
||||
|
||||
class SphinxError(Exception):
|
||||
"""
|
||||
@@ -71,10 +69,9 @@ class SphinxParallelError(SphinxError):
|
||||
|
||||
category = 'Sphinx parallel build error'
|
||||
|
||||
def __init__(self, orig_exc, traceback):
|
||||
self.orig_exc = orig_exc
|
||||
def __init__(self, message, traceback):
|
||||
self.message = message
|
||||
self.traceback = traceback
|
||||
|
||||
def __str__(self):
|
||||
return traceback.format_exception_only(
|
||||
self.orig_exc.__class__, self.orig_exc)[0].strip()
|
||||
return self.message
|
||||
|
||||
@@ -100,7 +100,7 @@ def process_autosummary_toc(app, doctree):
|
||||
if not isinstance(subnode, nodes.section):
|
||||
continue
|
||||
if subnode not in crawled:
|
||||
crawl_toc(subnode, depth+1)
|
||||
crawl_toc(subnode, depth + 1)
|
||||
crawl_toc(doctree)
|
||||
|
||||
|
||||
@@ -266,7 +266,7 @@ class Autosummary(Directive):
|
||||
if not isinstance(obj, ModuleType):
|
||||
# give explicitly separated module name, so that members
|
||||
# of inner classes can be documented
|
||||
full_name = modname + '::' + full_name[len(modname)+1:]
|
||||
full_name = modname + '::' + full_name[len(modname) + 1:]
|
||||
# NB. using full_name here is important, since Documenters
|
||||
# handle module prefixes slightly differently
|
||||
documenter = get_documenter(obj, parent)(self, full_name)
|
||||
@@ -403,13 +403,13 @@ def mangle_signature(sig, max_chars=30):
|
||||
s = m.group(1)[:-2]
|
||||
|
||||
# Produce a more compact signature
|
||||
sig = limited_join(", ", args, max_chars=max_chars-2)
|
||||
sig = limited_join(", ", args, max_chars=max_chars - 2)
|
||||
if opts:
|
||||
if not sig:
|
||||
sig = "[%s]" % limited_join(", ", opts, max_chars=max_chars-4)
|
||||
sig = "[%s]" % limited_join(", ", opts, max_chars=max_chars - 4)
|
||||
elif len(sig) < max_chars - 4 - 2 - 3:
|
||||
sig += "[, %s]" % limited_join(", ", opts,
|
||||
max_chars=max_chars-len(sig)-4-2)
|
||||
max_chars=max_chars - len(sig) - 4 - 2)
|
||||
|
||||
return u"(%s)" % sig
|
||||
|
||||
@@ -497,7 +497,7 @@ def _import_by_name(name):
|
||||
# ... then as MODNAME, MODNAME.OBJ1, MODNAME.OBJ1.OBJ2, ...
|
||||
last_j = 0
|
||||
modname = None
|
||||
for j in reversed(range(1, len(name_parts)+1)):
|
||||
for j in reversed(range(1, len(name_parts) + 1)):
|
||||
last_j = j
|
||||
modname = '.'.join(name_parts[:j])
|
||||
try:
|
||||
|
||||
@@ -241,7 +241,7 @@ class DocTestBuilder(Builder):
|
||||
self.outfile.write('''\
|
||||
Results of doctest builder run on %s
|
||||
==================================%s
|
||||
''' % (date, '='*len(date)))
|
||||
''' % (date, '=' * len(date)))
|
||||
|
||||
def _out(self, text):
|
||||
self.info(text, nonl=True)
|
||||
@@ -348,7 +348,7 @@ Doctest summary
|
||||
return
|
||||
|
||||
self._out('\nDocument: %s\n----------%s\n' %
|
||||
(docname, '-'*len(docname)))
|
||||
(docname, '-' * len(docname)))
|
||||
for group in itervalues(groups):
|
||||
self.test_group(group, self.env.doc2path(docname, base=None))
|
||||
# Separately count results from setup code
|
||||
|
||||
@@ -217,7 +217,7 @@ def get_tooltip(self, node):
|
||||
|
||||
def html_visit_math(self, node):
|
||||
try:
|
||||
fname, depth = render_math(self, '$'+node['latex']+'$')
|
||||
fname, depth = render_math(self, '$' + node['latex'] + '$')
|
||||
except MathExtError as exc:
|
||||
msg = text_type(exc)
|
||||
sm = nodes.system_message(msg, type='WARNING', level=2,
|
||||
|
||||
@@ -68,7 +68,7 @@ def read_inventory_v1(f, uri, join):
|
||||
return invdata
|
||||
|
||||
|
||||
def read_inventory_v2(f, uri, join, bufsize=16*1024):
|
||||
def read_inventory_v2(f, uri, join, bufsize=16 * 1024):
|
||||
invdata = {}
|
||||
line = f.readline()
|
||||
projname = line.rstrip()[11:].decode('utf-8')
|
||||
@@ -91,7 +91,7 @@ def read_inventory_v2(f, uri, join, bufsize=16*1024):
|
||||
lineend = buf.find(b'\n')
|
||||
while lineend != -1:
|
||||
yield buf[:lineend].decode('utf-8')
|
||||
buf = buf[lineend+1:]
|
||||
buf = buf[lineend + 1:]
|
||||
lineend = buf.find(b'\n')
|
||||
assert not buf
|
||||
|
||||
@@ -116,7 +116,7 @@ def read_inventory_v2(f, uri, join, bufsize=16*1024):
|
||||
return invdata
|
||||
|
||||
|
||||
def read_inventory(f, uri, join, bufsize=16*1024):
|
||||
def read_inventory(f, uri, join, bufsize=16 * 1024):
|
||||
line = f.readline().rstrip().decode('utf-8')
|
||||
if line == '# Sphinx inventory version 1':
|
||||
return read_inventory_v1(f, uri, join)
|
||||
@@ -221,8 +221,8 @@ def fetch_inventory(app, uri, inv):
|
||||
try:
|
||||
join = localuri and path.join or posixpath.join
|
||||
invdata = read_inventory(f, uri, join)
|
||||
except ValueError:
|
||||
raise ValueError('unknown or unsupported inventory version')
|
||||
except ValueError as exc:
|
||||
raise ValueError('unknown or unsupported inventory version: %r' % exc)
|
||||
except Exception as err:
|
||||
app.warn('intersphinx inventory %r not readable due to '
|
||||
'%s: %s' % (inv, err.__class__.__name__, err))
|
||||
@@ -242,7 +242,7 @@ def load_mappings(app):
|
||||
cache = env.intersphinx_cache
|
||||
update = False
|
||||
for key, value in iteritems(app.config.intersphinx_mapping):
|
||||
if isinstance(value, tuple):
|
||||
if isinstance(value, (list, tuple)):
|
||||
# new format
|
||||
name, (uri, inv) = key, value
|
||||
if not isinstance(name, string_types):
|
||||
@@ -342,9 +342,9 @@ def missing_reference(app, env, node, contnode):
|
||||
(domain == 'std' and node['reftype'] == 'keyword'):
|
||||
# use whatever title was given, but strip prefix
|
||||
title = contnode.astext()
|
||||
if in_set and title.startswith(in_set+':'):
|
||||
newnode.append(contnode.__class__(title[len(in_set)+1:],
|
||||
title[len(in_set)+1:]))
|
||||
if in_set and title.startswith(in_set + ':'):
|
||||
newnode.append(contnode.__class__(title[len(in_set) + 1:],
|
||||
title[len(in_set) + 1:]))
|
||||
else:
|
||||
newnode.append(contnode)
|
||||
else:
|
||||
|
||||
@@ -189,7 +189,7 @@ def get_tooltip(self, node):
|
||||
|
||||
def html_visit_math(self, node):
|
||||
try:
|
||||
fname, depth = render_math(self, '$'+node['latex']+'$')
|
||||
fname, depth = render_math(self, '$' + node['latex'] + '$')
|
||||
except MathExtError as exc:
|
||||
msg = text_type(exc)
|
||||
sm = nodes.system_message(msg, type='WARNING', level=2,
|
||||
|
||||
@@ -138,7 +138,7 @@ def process_todo_nodes(app, doctree, fromdocname):
|
||||
(todo_info['source'], todo_info['lineno'])
|
||||
)
|
||||
desc1 = description[:description.find('<<')]
|
||||
desc2 = description[description.find('>>')+2:]
|
||||
desc2 = description[description.find('>>') + 2:]
|
||||
para += nodes.Text(desc1, desc1)
|
||||
|
||||
# Create a reference
|
||||
|
||||
@@ -79,7 +79,7 @@ class Make(object):
|
||||
|
||||
def build_help(self):
|
||||
print(bold("Sphinx v%s" % sphinx.__display_version__))
|
||||
print("Please use `make %s' where %s is one of" % ((blue('target'),)*2))
|
||||
print("Please use `make %s' where %s is one of" % ((blue('target'),) * 2))
|
||||
for osname, bname, description in BUILDERS:
|
||||
if not osname or os.name == osname:
|
||||
print(' %s %s' % (blue(bname.ljust(10)), description))
|
||||
|
||||
@@ -364,4 +364,4 @@ if __name__ == '__main__':
|
||||
pprint.pprint(ma.find_tags())
|
||||
x3 = time.time()
|
||||
# print nodes.nice_repr(ma.parsetree, number2name)
|
||||
print("tokenizing %.4f, parsing %.4f, finding %.4f" % (x1-x0, x2-x1, x3-x2))
|
||||
print("tokenizing %.4f, parsing %.4f, finding %.4f" % (x1 - x0, x2 - x1, x3 - x2))
|
||||
|
||||
@@ -39,7 +39,7 @@ class BaseNode(object):
|
||||
if child is self:
|
||||
if i == 0:
|
||||
return None
|
||||
return self.parent.children[i-1]
|
||||
return self.parent.children[i - 1]
|
||||
|
||||
def get_next_sibling(self):
|
||||
"""Return next child in parent's children, or None."""
|
||||
@@ -48,7 +48,7 @@ class BaseNode(object):
|
||||
for i, child in enumerate(self.parent.children):
|
||||
if child is self:
|
||||
try:
|
||||
return self.parent.children[i+1]
|
||||
return self.parent.children[i + 1]
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
|
||||
@@ -301,11 +301,11 @@ document is a custom template, you can also set this to another filename.''')
|
||||
do_prompt(d, 'master', 'Name of your master document (without suffix)',
|
||||
'index')
|
||||
|
||||
while path.isfile(path.join(d['path'], d['master']+d['suffix'])) or \
|
||||
path.isfile(path.join(d['path'], 'source', d['master']+d['suffix'])):
|
||||
while path.isfile(path.join(d['path'], d['master'] + d['suffix'])) or \
|
||||
path.isfile(path.join(d['path'], 'source', d['master'] + d['suffix'])):
|
||||
print()
|
||||
print(bold('Error: the master file %s has already been found in the '
|
||||
'selected root path.' % (d['master']+d['suffix'])))
|
||||
'selected root path.' % (d['master'] + d['suffix'])))
|
||||
print('sphinx-quickstart will not overwrite the existing file.')
|
||||
print()
|
||||
do_prompt(d, 'master', 'Please enter a new file name, or rename the '
|
||||
@@ -632,7 +632,7 @@ def main(argv=sys.argv):
|
||||
d.setdefault('version', '')
|
||||
d.setdefault('release', d['version'])
|
||||
d2 = DEFAULT_VALUE.copy()
|
||||
d2.update(dict(("ext_"+ext, False) for ext in EXTENSIONS))
|
||||
d2.update(dict(("ext_" + ext, False) for ext in EXTENSIONS))
|
||||
d2.update(d)
|
||||
d = d2
|
||||
if 'no_makefile' in d:
|
||||
|
||||
@@ -201,7 +201,7 @@ def indexmarkup_role(typ, rawtext, text, lineno, inliner,
|
||||
return [prb], [msg]
|
||||
ref = inliner.document.settings.pep_base_url + 'pep-%04d' % pepnum
|
||||
sn = nodes.strong(title, title)
|
||||
rn = nodes.reference('', '', internal=False, refuri=ref+anchor,
|
||||
rn = nodes.reference('', '', internal=False, refuri=ref + anchor,
|
||||
classes=[typ])
|
||||
rn += sn
|
||||
return [indexnode, targetnode, rn], []
|
||||
@@ -223,7 +223,7 @@ def indexmarkup_role(typ, rawtext, text, lineno, inliner,
|
||||
return [prb], [msg]
|
||||
ref = inliner.document.settings.rfc_base_url + inliner.rfc_url % rfcnum
|
||||
sn = nodes.strong(title, title)
|
||||
rn = nodes.reference('', '', internal=False, refuri=ref+anchor,
|
||||
rn = nodes.reference('', '', internal=False, refuri=ref + anchor,
|
||||
classes=[typ])
|
||||
rn += sn
|
||||
return [indexnode, targetnode, rn], []
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
%
|
||||
|
||||
\NeedsTeXFormat{LaTeX2e}[1995/12/01]
|
||||
\ProvidesPackage{sphinx}[2016/12/14 v1.5.2 LaTeX package (Sphinx markup)]
|
||||
\ProvidesPackage{sphinx}[2017/01/09 v1.5.2 LaTeX package (Sphinx markup)]
|
||||
|
||||
% we delay handling of options to after having loaded packages, because
|
||||
% of the need to use \definecolor.
|
||||
@@ -1090,8 +1090,14 @@
|
||||
|
||||
% make commands known to non-Sphinx document classes
|
||||
\providecommand*{\sphinxtableofcontents}{\tableofcontents}
|
||||
\providecommand*{\sphinxthebibliography}{\thebibliography}
|
||||
\providecommand*{\sphinxtheindex}{\theindex}
|
||||
\spx@ifundefined{sphinxthebibliography}
|
||||
{\newenvironment
|
||||
{sphinxthebibliography}{\begin{thebibliography}}{\end{thebibliography}}%
|
||||
}
|
||||
{}% else clause of ifundefined
|
||||
\spx@ifundefined{sphinxtheindex}
|
||||
{\newenvironment{sphinxtheindex}{\begin{theindex}}{\end{theindex}}}%
|
||||
{}% else clause of ifundefined
|
||||
|
||||
% remove LaTeX's cap on nesting depth if 'maxlistdepth' key used.
|
||||
% This is a hack, which works with the standard classes: it assumes \@toodeep
|
||||
@@ -1122,7 +1128,7 @@
|
||||
\expandafter\let
|
||||
\csname @list\romannumeral\the\count@\expandafter\endcsname
|
||||
\csname @list\romannumeral\the\numexpr\count@-\@ne\endcsname
|
||||
% higher \leftmargin... needed to fix issue with babel-french (v2.6--...)
|
||||
% work around 2.6--3.2d babel-french issue (fixed in 3.2e; no change needed)
|
||||
\spx@ifundefined{leftmargin\romannumeral\the\count@}
|
||||
{\expandafter\let
|
||||
\csname leftmargin\romannumeral\the\count@\expandafter\endcsname
|
||||
|
||||
@@ -112,7 +112,7 @@ class Locale(Transform):
|
||||
# literalblock need literal block notation to avoid it become
|
||||
# paragraph.
|
||||
if isinstance(node, LITERAL_TYPE_NODES):
|
||||
msgstr = '::\n\n' + indent(msgstr, ' '*3)
|
||||
msgstr = '::\n\n' + indent(msgstr, ' ' * 3)
|
||||
|
||||
patch = publish_msgstr(
|
||||
env.app, msgstr, source, node.line, env.config, settings)
|
||||
@@ -237,7 +237,7 @@ class Locale(Transform):
|
||||
# literalblock need literal block notation to avoid it become
|
||||
# paragraph.
|
||||
if isinstance(node, LITERAL_TYPE_NODES):
|
||||
msgstr = '::\n\n' + indent(msgstr, ' '*3)
|
||||
msgstr = '::\n\n' + indent(msgstr, ' ' * 3)
|
||||
|
||||
patch = publish_msgstr(
|
||||
env.app, msgstr, source, node.line, env.config, settings)
|
||||
|
||||
@@ -98,7 +98,7 @@ def get_matching_docs(dirname, suffixes, exclude_matchers=()):
|
||||
for filename in get_matching_files(dirname, exclude_matchers):
|
||||
for suffixpattern in suffixpatterns:
|
||||
if fnmatch.fnmatch(filename, suffixpattern):
|
||||
yield filename[:-len(suffixpattern)+1]
|
||||
yield filename[:-len(suffixpattern) + 1]
|
||||
break
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@ def copy_static_entry(source, targetdir, builder, context={},
|
||||
if path.isdir(path.join(source, entry)):
|
||||
newtarget = path.join(targetdir, entry)
|
||||
copy_static_entry(path.join(source, entry), newtarget,
|
||||
builder, context, level=level+1,
|
||||
builder, context, level=level + 1,
|
||||
exclude_matchers=exclude_matchers)
|
||||
|
||||
|
||||
@@ -360,9 +360,9 @@ def parselinenos(spec, total):
|
||||
if len(begend) > 2:
|
||||
raise ValueError
|
||||
if len(begend) == 1:
|
||||
items.append(int(begend[0])-1)
|
||||
items.append(int(begend[0]) - 1)
|
||||
else:
|
||||
start = (begend[0] == '') and 0 or int(begend[0])-1
|
||||
start = (begend[0] == '') and 0 or int(begend[0]) - 1
|
||||
end = (begend[1] == '') and total or int(begend[1])
|
||||
items.extend(range(start, end))
|
||||
except Exception:
|
||||
@@ -400,13 +400,13 @@ def rpartition(s, t):
|
||||
"""Similar to str.rpartition from 2.5, but doesn't return the separator."""
|
||||
i = s.rfind(t)
|
||||
if i != -1:
|
||||
return s[:i], s[i+len(t):]
|
||||
return s[:i], s[i + len(t):]
|
||||
return '', s
|
||||
|
||||
|
||||
def split_into(n, type, value):
|
||||
"""Split an index entry into a given number of parts at semicolons."""
|
||||
parts = [x.strip() for x in value.split(';', n-1)]
|
||||
parts = [x.strip() for x in value.split(';', n - 1)]
|
||||
if sum(1 for part in parts if part) < n:
|
||||
raise ValueError('invalid %s index entry %r' % (type, value))
|
||||
return parts
|
||||
|
||||
@@ -115,8 +115,8 @@ _colors = [
|
||||
]
|
||||
|
||||
for i, (dark, light) in enumerate(_colors):
|
||||
codes[dark] = '\x1b[%im' % (i+30)
|
||||
codes[light] = '\x1b[%i;01m' % (i+30)
|
||||
codes[dark] = '\x1b[%im' % (i + 30)
|
||||
codes[light] = '\x1b[%i;01m' % (i + 30)
|
||||
|
||||
_orig_codes = codes.copy()
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import docutils
|
||||
from docutils.parsers.rst import directives, roles
|
||||
|
||||
|
||||
__version_info__ = tuple(map(int, docutils.__version__.split('.')))
|
||||
__version_info__ = tuple(map(int, docutils.__version__.split('.')))
|
||||
|
||||
|
||||
@contextmanager
|
||||
|
||||
@@ -41,7 +41,9 @@ def copy_asset_file(source, destination, context=None, renderer=None):
|
||||
renderer = SphinxRenderer()
|
||||
|
||||
with codecs.open(source, 'r', encoding='utf-8') as fsrc:
|
||||
with codecs.open(destination[:-2], 'w', encoding='utf-8') as fdst:
|
||||
if destination.lower().endswith('_t'):
|
||||
destination = destination[:-2]
|
||||
with codecs.open(destination, 'w', encoding='utf-8') as fdst:
|
||||
fdst.write(renderer.render_string(fsrc.read(), context))
|
||||
else:
|
||||
copyfile(source, destination)
|
||||
|
||||
@@ -53,10 +53,19 @@ class CatalogInfo(LocaleFileInfoBase):
|
||||
not path.exists(self.mo_path) or
|
||||
path.getmtime(self.mo_path) < path.getmtime(self.po_path))
|
||||
|
||||
def write_mo(self, locale):
|
||||
with io.open(self.po_path, 'rt', encoding=self.charset) as po:
|
||||
with io.open(self.mo_path, 'wb') as mo:
|
||||
write_mo(mo, read_po(po, locale))
|
||||
def write_mo(self, locale, warnfunc):
|
||||
with io.open(self.po_path, 'rt', encoding=self.charset) as file_po:
|
||||
try:
|
||||
po = read_po(file_po, locale)
|
||||
except Exception:
|
||||
warnfunc('reading error: %s' % self.po_path)
|
||||
return
|
||||
|
||||
with io.open(self.mo_path, 'wb') as file_mo:
|
||||
try:
|
||||
write_mo(file_mo, po)
|
||||
except Exception:
|
||||
warnfunc('writing error: %s' % self.mo_path)
|
||||
|
||||
|
||||
def find_catalog(docname, compaction):
|
||||
|
||||
@@ -16,8 +16,8 @@ from six import iteritems, integer_types, string_types
|
||||
|
||||
from sphinx.util.pycompat import u
|
||||
|
||||
_str_re = re.compile(r'"(\\\\|\\"|[^"])*"')
|
||||
_int_re = re.compile(r'\d+')
|
||||
_str_re = re.compile(r'"(\\\\|\\"|[^"])*"')
|
||||
_int_re = re.compile(r'\d+')
|
||||
_name_re = re.compile(r'[a-zA-Z_]\w*')
|
||||
_nameonly_re = re.compile(r'[a-zA-Z_][a-zA-Z0-9_]*$')
|
||||
|
||||
|
||||
@@ -243,15 +243,15 @@ def process_index_entry(entry, targetid):
|
||||
main = 'main'
|
||||
entry = entry[1:].lstrip()
|
||||
for type in pairindextypes:
|
||||
if entry.startswith(type+':'):
|
||||
value = entry[len(type)+1:].strip()
|
||||
if entry.startswith(type + ':'):
|
||||
value = entry[len(type) + 1:].strip()
|
||||
value = pairindextypes[type] + '; ' + value
|
||||
indexentries.append(('pair', value, targetid, main, None))
|
||||
break
|
||||
else:
|
||||
for type in indextypes:
|
||||
if entry.startswith(type+':'):
|
||||
value = entry[len(type)+1:].strip()
|
||||
if entry.startswith(type + ':'):
|
||||
value = entry[len(type) + 1:].strip()
|
||||
if type == 'double':
|
||||
type = 'pair'
|
||||
indexentries.append((type, value, targetid, main, None))
|
||||
|
||||
@@ -27,7 +27,7 @@ from six import PY2, text_type
|
||||
# Errnos that we need.
|
||||
EEXIST = getattr(errno, 'EEXIST', 0)
|
||||
ENOENT = getattr(errno, 'ENOENT', 0)
|
||||
EPIPE = getattr(errno, 'EPIPE', 0)
|
||||
EPIPE = getattr(errno, 'EPIPE', 0)
|
||||
EINVAL = getattr(errno, 'EINVAL', 0)
|
||||
|
||||
# SEP separates path elements in the canonical file names
|
||||
@@ -67,7 +67,7 @@ def relative_uri(base, to):
|
||||
# Special case: relative_uri('f/index.html','f/') should
|
||||
# return './', not ''
|
||||
return '.' + SEP
|
||||
return ('..' + SEP) * (len(b2)-1) + SEP.join(t2)
|
||||
return ('..' + SEP) * (len(b2) - 1) + SEP.join(t2)
|
||||
|
||||
|
||||
def ensuredir(path):
|
||||
|
||||
@@ -73,7 +73,8 @@ class ParallelTasks(object):
|
||||
ret = func(arg)
|
||||
pipe.send((False, ret))
|
||||
except BaseException as err:
|
||||
pipe.send((True, (err, traceback.format_exc())))
|
||||
errmsg = traceback.format_exception_only(err.__class__, err)[0].strip()
|
||||
pipe.send((True, (errmsg, traceback.format_exc())))
|
||||
|
||||
def add_task(self, task_func, arg=None, result_func=None):
|
||||
tid = self._taskid
|
||||
@@ -116,11 +117,11 @@ def make_chunks(arguments, nproc, maxbatch=10):
|
||||
chunksize = nargs // nproc
|
||||
if chunksize >= maxbatch:
|
||||
# try to improve batch size vs. number of batches
|
||||
chunksize = int(sqrt(nargs/nproc * maxbatch))
|
||||
chunksize = int(sqrt(nargs / nproc * maxbatch))
|
||||
if chunksize == 0:
|
||||
chunksize = 1
|
||||
nchunks, rest = divmod(nargs, chunksize)
|
||||
if rest:
|
||||
nchunks += 1
|
||||
# partition documents in "chunks" that will be written by one Process
|
||||
return [arguments[i*chunksize:(i+1)*chunksize] for i in range(nchunks)]
|
||||
return [arguments[i * chunksize:(i + 1) * chunksize] for i in range(nchunks)]
|
||||
|
||||
@@ -17,7 +17,12 @@ import pkg_resources
|
||||
|
||||
from six import string_types
|
||||
from six.moves.urllib.parse import urlsplit
|
||||
from requests.packages.urllib3.exceptions import SSLError, InsecureRequestWarning
|
||||
try:
|
||||
from requests.packages.urllib3.exceptions import SSLError, InsecureRequestWarning
|
||||
except ImportError:
|
||||
# python-requests package in Debian jessie does not provide ``requests.packages.urllib3``.
|
||||
# So try to import the exceptions from urllib3 package.
|
||||
from urllib3.exceptions import SSLError, InsecureRequestWarning
|
||||
|
||||
# try to load requests[security]
|
||||
try:
|
||||
|
||||
@@ -107,7 +107,7 @@ class PorterStemmer(object):
|
||||
"""doublec(j) is TRUE <=> j,(j-1) contain a double consonant."""
|
||||
if j < (self.k0 + 1):
|
||||
return 0
|
||||
if (self.b[j] != self.b[j-1]):
|
||||
if (self.b[j] != self.b[j - 1]):
|
||||
return 0
|
||||
return self.cons(j)
|
||||
|
||||
@@ -120,8 +120,8 @@ class PorterStemmer(object):
|
||||
cav(e), lov(e), hop(e), crim(e), but
|
||||
snow, box, tray.
|
||||
"""
|
||||
if i < (self.k0 + 2) or not self.cons(i) or self.cons(i-1) \
|
||||
or not self.cons(i-2):
|
||||
if i < (self.k0 + 2) or not self.cons(i) or self.cons(i - 1) \
|
||||
or not self.cons(i - 2):
|
||||
return 0
|
||||
ch = self.b[i]
|
||||
if ch == 'w' or ch == 'x' or ch == 'y':
|
||||
@@ -135,7 +135,7 @@ class PorterStemmer(object):
|
||||
return 0
|
||||
if length > (self.k - self.k0 + 1):
|
||||
return 0
|
||||
if self.b[self.k-length+1:self.k+1] != s:
|
||||
if self.b[self.k - length + 1:self.k + 1] != s:
|
||||
return 0
|
||||
self.j = self.k - length
|
||||
return 1
|
||||
@@ -144,7 +144,7 @@ class PorterStemmer(object):
|
||||
"""setto(s) sets (j+1),...k to the characters in the string s,
|
||||
readjusting k."""
|
||||
length = len(s)
|
||||
self.b = self.b[:self.j+1] + s + self.b[self.j+length+1:]
|
||||
self.b = self.b[:self.j + 1] + s + self.b[self.j + length + 1:]
|
||||
self.k = self.j + length
|
||||
|
||||
def r(self, s):
|
||||
@@ -203,7 +203,7 @@ class PorterStemmer(object):
|
||||
"""step1c() turns terminal y to i when there is another vowel in
|
||||
the stem."""
|
||||
if (self.ends("y") and self.vowelinstem()):
|
||||
self.b = self.b[:self.k] + 'i' + self.b[self.k+1:]
|
||||
self.b = self.b[:self.k] + 'i' + self.b[self.k + 1:]
|
||||
|
||||
def step2(self):
|
||||
"""step2() maps double suffices to single ones.
|
||||
@@ -376,7 +376,7 @@ class PorterStemmer(object):
|
||||
self.j = self.k
|
||||
if self.b[self.k] == 'e':
|
||||
a = self.m()
|
||||
if a > 1 or (a == 1 and not self.cvc(self.k-1)):
|
||||
if a > 1 or (a == 1 and not self.cvc(self.k - 1)):
|
||||
self.k = self.k - 1
|
||||
if self.b[self.k] == 'l' and self.doublec(self.k) and self.m() > 1:
|
||||
self.k = self.k - 1
|
||||
@@ -408,4 +408,4 @@ class PorterStemmer(object):
|
||||
self.step3()
|
||||
self.step4()
|
||||
self.step5()
|
||||
return self.b[self.k0:self.k+1]
|
||||
return self.b[self.k0:self.k + 1]
|
||||
|
||||
@@ -106,7 +106,7 @@ class BaseSearch(object):
|
||||
res = self.context_re.search(text)
|
||||
if res is None:
|
||||
return ''
|
||||
context_start = max(res.start() - int(length/2), 0)
|
||||
context_start = max(res.start() - int(length / 2), 0)
|
||||
context_end = context_start + length
|
||||
context = ''.join([context_start > 0 and '...' or '',
|
||||
text[context_start:context_end],
|
||||
|
||||
@@ -454,7 +454,7 @@ class HTMLTranslator(BaseTranslator):
|
||||
self.body.append(self.starttag(production, 'strong', ''))
|
||||
self.body.append(lastname + '</strong> ::= ')
|
||||
elif lastname is not None:
|
||||
self.body.append('%s ' % (' '*len(lastname)))
|
||||
self.body.append('%s ' % (' ' * len(lastname)))
|
||||
production.walkabout(self)
|
||||
self.body.append('\n')
|
||||
self.body.append('</pre>\n')
|
||||
@@ -614,7 +614,7 @@ class HTMLTranslator(BaseTranslator):
|
||||
self.body.append(token)
|
||||
else:
|
||||
# protect runs of multiple spaces; the last one can wrap
|
||||
self.body.append(' ' * (len(token)-1) + ' ')
|
||||
self.body.append(' ' * (len(token) - 1) + ' ')
|
||||
else:
|
||||
if self.in_mailto and self.settings.cloak_email_addresses:
|
||||
encoded = self.cloak_email(encoded)
|
||||
|
||||
@@ -1641,7 +1641,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
parindex = node.parent.index(node)
|
||||
try:
|
||||
try:
|
||||
next = node.parent[parindex+1]
|
||||
next = node.parent[parindex + 1]
|
||||
except IndexError:
|
||||
# last node in parent, look at next after parent
|
||||
# (for section of equal level) if it exists
|
||||
@@ -1700,14 +1700,14 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
elif type == 'pair':
|
||||
p1, p2 = [self.encode(x) for x in split_into(2, 'pair', string)]
|
||||
self.body.append(r'\index{%s!%s%s}\index{%s!%s%s}' %
|
||||
(p1, p2, m, p2, p1, m))
|
||||
(p1, p2, m, p2, p1, m))
|
||||
elif type == 'triple':
|
||||
p1, p2, p3 = [self.encode(x)
|
||||
for x in split_into(3, 'triple', string)]
|
||||
self.body.append(
|
||||
r'\index{%s!%s %s%s}\index{%s!%s, %s%s}'
|
||||
r'\index{%s!%s %s%s}' %
|
||||
(p1, p2, p3, m, p2, p3, p1, m, p3, p1, p2, m))
|
||||
(p1, p2, p3, m, p2, p3, p1, m, p3, p1, p2, m))
|
||||
elif type == 'see':
|
||||
p1, p2 = [self.encode(x) for x in split_into(2, 'see', string)]
|
||||
self.body.append(r'\index{%s|see{%s}}' % (p1, p2))
|
||||
|
||||
@@ -271,7 +271,7 @@ class ManualPageTranslator(BaseTranslator):
|
||||
self.body.append(self.defs['strong'][1])
|
||||
self.body.append(' ::= ')
|
||||
elif lastname is not None:
|
||||
self.body.append('%s ' % (' '*len(lastname)))
|
||||
self.body.append('%s ' % (' ' * len(lastname)))
|
||||
production.walkabout(self)
|
||||
self.body.append('\n')
|
||||
self.body.append('\n.fi\n')
|
||||
|
||||
@@ -318,10 +318,10 @@ class TexinfoTranslator(nodes.NodeVisitor):
|
||||
for i, id in enumerate(entries):
|
||||
# First child's prev is empty
|
||||
if i != 0:
|
||||
rellinks[id][1] = entries[i-1]
|
||||
rellinks[id][1] = entries[i - 1]
|
||||
# Last child's next is empty
|
||||
if i != len(entries) - 1:
|
||||
rellinks[id][0] = entries[i+1]
|
||||
rellinks[id][0] = entries[i + 1]
|
||||
# top's next is its first child
|
||||
try:
|
||||
first = node_menus['Top'][0]
|
||||
@@ -383,7 +383,7 @@ class TexinfoTranslator(nodes.NodeVisitor):
|
||||
s = '* %s: %s. ' % (name, node_name)
|
||||
offset = max((24, (len(name) + 4) % 78))
|
||||
wdesc = '\n'.join(' ' * offset + l for l in
|
||||
textwrap.wrap(desc, width=78-offset))
|
||||
textwrap.wrap(desc, width=78 - offset))
|
||||
return s + wdesc.strip() + '\n'
|
||||
|
||||
def add_menu_entries(self, entries, reg=re.compile(r'\s+---?\s+')):
|
||||
@@ -641,7 +641,7 @@ class TexinfoTranslator(nodes.NodeVisitor):
|
||||
parindex = node.parent.index(node)
|
||||
try:
|
||||
try:
|
||||
next = node.parent[parindex+1]
|
||||
next = node.parent[parindex + 1]
|
||||
except IndexError:
|
||||
# last node in parent, look at next after parent
|
||||
# (for section of equal level)
|
||||
@@ -996,7 +996,7 @@ class TexinfoTranslator(nodes.NodeVisitor):
|
||||
return
|
||||
self.body.append('\n\n@multitable ')
|
||||
for i, n in enumerate(self.colwidths):
|
||||
self.body.append('{%s} ' % ('x' * (n+2)))
|
||||
self.body.append('{%s} ' % ('x' * (n + 2)))
|
||||
|
||||
def depart_colspec(self, node):
|
||||
pass
|
||||
@@ -1274,7 +1274,7 @@ class TexinfoTranslator(nodes.NodeVisitor):
|
||||
self.add_anchor(id, production)
|
||||
s = production['tokenname'].ljust(maxlen) + ' ::='
|
||||
else:
|
||||
s = '%s ' % (' '*maxlen)
|
||||
s = '%s ' % (' ' * maxlen)
|
||||
self.body.append(self.escape(s))
|
||||
self.body.append(self.escape(production.astext() + '\n'))
|
||||
self.depart_literal_block(None)
|
||||
|
||||
@@ -90,7 +90,7 @@ class TextWrapper(textwrap.TextWrapper):
|
||||
for i, c in enumerate(word):
|
||||
total += column_width(c)
|
||||
if total > space_left:
|
||||
return word[:i-1], word[i-1:]
|
||||
return word[:i - 1], word[i - 1:]
|
||||
return word, ''
|
||||
|
||||
def _split(self, text):
|
||||
@@ -194,7 +194,7 @@ class TextTranslator(nodes.NodeVisitor):
|
||||
if not toformat:
|
||||
return
|
||||
if wrap:
|
||||
res = my_wrap(''.join(toformat), width=MAXWIDTH-maxindent)
|
||||
res = my_wrap(''.join(toformat), width=MAXWIDTH - maxindent)
|
||||
else:
|
||||
res = ''.join(toformat).splitlines()
|
||||
if end:
|
||||
@@ -225,7 +225,7 @@ class TextTranslator(nodes.NodeVisitor):
|
||||
|
||||
def depart_document(self, node):
|
||||
self.end_state()
|
||||
self.body = self.nl.join(line and (' '*indent + line)
|
||||
self.body = self.nl.join(line and (' ' * indent + line)
|
||||
for indent, lines in self.states[0]
|
||||
for line in lines)
|
||||
# XXX header/footer?
|
||||
@@ -271,7 +271,7 @@ class TextTranslator(nodes.NodeVisitor):
|
||||
|
||||
def visit_title(self, node):
|
||||
if isinstance(node.parent, nodes.Admonition):
|
||||
self.add_text(node.astext()+': ')
|
||||
self.add_text(node.astext() + ': ')
|
||||
raise nodes.SkipNode
|
||||
self.new_state(0)
|
||||
|
||||
@@ -401,7 +401,7 @@ class TextTranslator(nodes.NodeVisitor):
|
||||
self.add_text(production['tokenname'].ljust(maxlen) + ' ::=')
|
||||
lastname = production['tokenname']
|
||||
elif lastname is not None:
|
||||
self.add_text('%s ' % (' '*len(lastname)))
|
||||
self.add_text('%s ' % (' ' * len(lastname)))
|
||||
self.add_text(production.astext() + self.nl)
|
||||
self.end_state(wrap=False)
|
||||
raise nodes.SkipNode
|
||||
@@ -552,7 +552,7 @@ class TextTranslator(nodes.NodeVisitor):
|
||||
def writesep(char='-'):
|
||||
out = ['+']
|
||||
for width in realwidths:
|
||||
out.append(char * (width+2))
|
||||
out.append(char * (width + 2))
|
||||
out.append('+')
|
||||
self.add_text(''.join(out) + self.nl)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
flake8
|
||||
nose
|
||||
nose-timer
|
||||
pytest>=3.0
|
||||
pytest-cov
|
||||
mock
|
||||
six>=1.4
|
||||
Jinja2>=2.3
|
||||
|
||||
230
tests/conftest.py
Normal file
230
tests/conftest.py
Normal file
@@ -0,0 +1,230 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
import subprocess
|
||||
from collections import namedtuple
|
||||
|
||||
import pytest
|
||||
from six import StringIO, string_types
|
||||
|
||||
import util
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def app_params(request, test_params, shared_result):
|
||||
"""
|
||||
parameters that is specified by 'pytest.mark.sphinx' for
|
||||
sphinx.application.Sphinx initialization
|
||||
"""
|
||||
|
||||
# ##### process pytest.mark.sphinx
|
||||
|
||||
markers = request.node.get_marker("sphinx")
|
||||
pargs = {}
|
||||
kwargs = {}
|
||||
|
||||
if markers is not None:
|
||||
# to avoid stacking positional args
|
||||
for info in reversed(list(markers)):
|
||||
for i, a in enumerate(info.args):
|
||||
pargs[i] = a
|
||||
kwargs.update(info.kwargs)
|
||||
|
||||
args = [pargs[i] for i in sorted(pargs.keys())]
|
||||
|
||||
# ##### process pytest.mark.test_params
|
||||
|
||||
if test_params['shared_result']:
|
||||
if 'srcdir' in kwargs:
|
||||
raise pytest.Exception('You can not spcify shared_result and '
|
||||
'srcdir in same time.')
|
||||
kwargs['srcdir'] = test_params['shared_result']
|
||||
restore = shared_result.restore(test_params['shared_result'])
|
||||
kwargs.update(restore)
|
||||
|
||||
# ##### prepare Application params
|
||||
|
||||
if 'srcdir' in kwargs:
|
||||
srcdir = util.tempdir / kwargs['srcdir']
|
||||
else:
|
||||
srcdir = util.tempdir / kwargs.get('testroot', 'root')
|
||||
kwargs['srcdir'] = srcdir
|
||||
|
||||
if kwargs.get('testroot') is None:
|
||||
testroot_path = util.rootdir / 'root'
|
||||
else:
|
||||
testroot_path = util.rootdir / 'roots' / ('test-' + kwargs['testroot'])
|
||||
|
||||
if not srcdir.exists():
|
||||
testroot_path.copytree(srcdir)
|
||||
|
||||
return namedtuple('app_params', 'args,kwargs')(args, kwargs)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def test_params(request):
|
||||
"""
|
||||
test parameters that is specified by 'pytest.mark.test_params'
|
||||
|
||||
:param Union[str] shared_result:
|
||||
If the value is provided, app._status and app._warning objects will be
|
||||
shared in the parametrized test functions and/or test functions that
|
||||
have same 'shared_result' value.
|
||||
**NOTE**: You can not specify shared_result and srcdir in same time.
|
||||
"""
|
||||
env = request.node.get_marker('test_params')
|
||||
kwargs = env.kwargs if env else {}
|
||||
result = {
|
||||
'shared_result': None,
|
||||
}
|
||||
result.update(kwargs)
|
||||
|
||||
if (result['shared_result'] and
|
||||
not isinstance(result['shared_result'], string_types)):
|
||||
raise pytest.Exception('You can only provide a string type of value '
|
||||
'for "shared_result" ')
|
||||
return result
|
||||
|
||||
|
||||
class SphinxTestAppWrapperForSkipBuilding(object):
|
||||
"""
|
||||
This class is a wrapper for SphinxTestApp to speed up the test by skipping
|
||||
`app.build` process if it is already built and there is even one output
|
||||
file.
|
||||
"""
|
||||
|
||||
def __init__(self, app_):
|
||||
self.app = app_
|
||||
|
||||
def __getattr__(self, name):
|
||||
return getattr(self.app, name)
|
||||
|
||||
def build(self, *args, **kw):
|
||||
if not self.app.outdir.listdir():
|
||||
# if listdir is empty, do build.
|
||||
self.app.build(*args, **kw)
|
||||
# otherwise, we can use built cache
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def app(test_params, app_params, make_app, shared_result):
|
||||
"""
|
||||
provides sphinx.application.Sphinx object
|
||||
"""
|
||||
args, kwargs = app_params
|
||||
app_ = make_app(*args, **kwargs)
|
||||
yield app_
|
||||
|
||||
print('# testroot:', kwargs.get('testroot', 'root'))
|
||||
print('# builder:', app_.buildername)
|
||||
print('# srcdir:', app_.srcdir)
|
||||
print('# outdir:', app_.outdir)
|
||||
print('# status:', '\n' + app_._status.getvalue())
|
||||
print('# warning:', '\n' + app_._warning.getvalue())
|
||||
|
||||
if test_params['shared_result']:
|
||||
shared_result.store(test_params['shared_result'], app_)
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def status(app):
|
||||
"""
|
||||
compat for testing with previous @with_app decorator
|
||||
"""
|
||||
return app._status
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def warning(app):
|
||||
"""
|
||||
compat for testing with previous @with_app decorator
|
||||
"""
|
||||
return app._warning
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def make_app(test_params):
|
||||
"""
|
||||
provides make_app function to initialize SphinxTestApp instance.
|
||||
if you want to initialize 'app' in your test function. please use this
|
||||
instead of using SphinxTestApp class directory.
|
||||
"""
|
||||
apps = []
|
||||
syspath = sys.path[:]
|
||||
|
||||
def make(*args, **kwargs):
|
||||
status, warning = StringIO(), StringIO()
|
||||
kwargs.setdefault('status', status)
|
||||
kwargs.setdefault('warning', warning)
|
||||
app_ = util.SphinxTestApp(*args, **kwargs)
|
||||
apps.append(app_)
|
||||
if test_params['shared_result']:
|
||||
app_ = SphinxTestAppWrapperForSkipBuilding(app_)
|
||||
return app_
|
||||
yield make
|
||||
|
||||
sys.path[:] = syspath
|
||||
for app_ in apps:
|
||||
app_.cleanup()
|
||||
|
||||
|
||||
class SharedResult(object):
|
||||
cache = {}
|
||||
|
||||
def store(self, key, app_):
|
||||
if key in self.cache:
|
||||
return
|
||||
data = {
|
||||
'status': app_._status.getvalue(),
|
||||
'warning': app_._warning.getvalue(),
|
||||
}
|
||||
self.cache[key] = data
|
||||
|
||||
def restore(self, key):
|
||||
if key not in self.cache:
|
||||
return {}
|
||||
data = self.cache[key]
|
||||
return {
|
||||
'status': StringIO(data['status']),
|
||||
'warning': StringIO(data['warning']),
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def shared_result():
|
||||
return SharedResult()
|
||||
|
||||
|
||||
@pytest.fixture(scope='module', autouse=True)
|
||||
def _shared_result_cache():
|
||||
SharedResult.cache.clear()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def if_graphviz_found(app):
|
||||
"""
|
||||
The test will be skipped when using 'if_graphviz_found' fixture and graphviz
|
||||
dot command is not found.
|
||||
"""
|
||||
graphviz_dot = getattr(app.config, 'graphviz_dot', '')
|
||||
try:
|
||||
if graphviz_dot:
|
||||
dot = subprocess.Popen([graphviz_dot, '-V'],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE) # show version
|
||||
dot.communicate()
|
||||
return
|
||||
except OSError: # No such file or directory
|
||||
pass
|
||||
|
||||
pytest.skip('graphviz "dot" is not available')
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def tempdir(tmpdir):
|
||||
"""
|
||||
temporary directory that wrapped with `path` class.
|
||||
this fixture is for compat with old test implementation.
|
||||
"""
|
||||
return util.path(tmpdir)
|
||||
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
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
# "raises" imported for usage by autodoc
|
||||
import six
|
||||
import sys
|
||||
from util import TestApp, Struct, raises, SkipTest
|
||||
from nose.tools import with_setup, eq_
|
||||
from util import SphinxTestApp, Struct
|
||||
import pytest
|
||||
|
||||
from six import StringIO
|
||||
from docutils.statemachine import ViewList
|
||||
@@ -27,7 +27,7 @@ app = None
|
||||
|
||||
def setup_module():
|
||||
global app
|
||||
app = TestApp()
|
||||
app = SphinxTestApp()
|
||||
app.builder.env.app = app
|
||||
app.builder.env.temp_data['docname'] = 'dummy'
|
||||
app.connect('autodoc-process-docstring', process_docstring)
|
||||
@@ -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)
|
||||
@@ -184,7 +185,7 @@ def test_generate():
|
||||
'Class.meth', more_content=add_content)
|
||||
|
||||
# test check_module
|
||||
inst = FunctionDocumenter(directive, 'raises')
|
||||
inst = FunctionDocumenter(directive, 'add_documenter')
|
||||
inst.generate(check_module=True)
|
||||
assert len(directive.result) == 0
|
||||
|
||||
@@ -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
|
||||
|
||||
22
tests/run.py
22
tests/run.py
@@ -17,14 +17,18 @@ import warnings
|
||||
import traceback
|
||||
|
||||
from path import path
|
||||
import nose
|
||||
|
||||
testroot = os.path.dirname(__file__) or '.'
|
||||
sys.path.insert(0, os.path.abspath(os.path.join(testroot, os.path.pardir)))
|
||||
|
||||
# filter warnings of test dependencies
|
||||
warnings.filterwarnings('ignore', category=DeprecationWarning, module='site') # virtualenv
|
||||
warnings.filterwarnings('ignore', category=ImportWarning, module='backports')
|
||||
warnings.filterwarnings('ignore', category=PendingDeprecationWarning, module=r'_pytest\..*')
|
||||
|
||||
# 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)
|
||||
@@ -49,8 +53,14 @@ tempdir.makedirs()
|
||||
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
|
||||
# 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])
|
||||
|
||||
nose.main(argv=sys.argv)
|
||||
import pytest
|
||||
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(), no html_translator_class
|
||||
translator_class = app.builder.translator_class
|
||||
@@ -30,7 +31,7 @@ def test_html_translator(app, status, warning):
|
||||
assert translator_class.__name__ == 'SmartyPantsHTMLTranslator'
|
||||
|
||||
|
||||
@with_app('html', confoverrides={
|
||||
@pytest.mark.sphinx('html', confoverrides={
|
||||
'html_translator_class': 'translator.ExtHTMLTranslator'})
|
||||
def test_html_with_html_translator_class(app, status, warning):
|
||||
# no set_translator(), but html_translator_class
|
||||
@@ -39,8 +40,8 @@ def test_html_with_html_translator_class(app, status, warning):
|
||||
assert translator_class.__name__ == 'ExtHTMLTranslator'
|
||||
|
||||
|
||||
@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
|
||||
@@ -48,7 +49,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(), no html_translator_class
|
||||
translator_class = app.builder.translator_class
|
||||
@@ -56,8 +57,8 @@ def test_html_with_set_translator_for_html_(app, status, warning):
|
||||
assert translator_class.__name__ == 'ConfHTMLTranslator'
|
||||
|
||||
|
||||
@with_app('html', testroot='api-set-translator',
|
||||
confoverrides={'html_translator_class': 'translator.ExtHTMLTranslator'})
|
||||
@pytest.mark.sphinx('html', testroot='api-set-translator', confoverrides={
|
||||
'html_translator_class': 'translator.ExtHTMLTranslator'})
|
||||
def test_html_with_set_translator_for_html_and_html_translator_class(
|
||||
app, status, warning):
|
||||
# use set_translator() and html_translator_class.
|
||||
@@ -68,7 +69,7 @@ def test_html_with_set_translator_for_html_and_html_translator_class(
|
||||
|
||||
|
||||
# this test break test_websupport.test_comments test. why?
|
||||
# @with_app(
|
||||
# @pytest.mark.sphinx(
|
||||
# buildername='dirhtml',
|
||||
# srcdir=(test_roots / 'test-api-set-translator'),
|
||||
# )
|
||||
@@ -78,63 +79,63 @@ def test_html_with_set_translator_for_html_and_html_translator_class(
|
||||
# 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.build()
|
||||
print(status.getvalue())
|
||||
print(warning.getvalue())
|
||||
|
||||
sys.path.append(codedir)
|
||||
try:
|
||||
assert_build()
|
||||
finally:
|
||||
sys.path.remove(codedir)
|
||||
app = make_app('text', srcdir=outdir)
|
||||
app.build()
|
||||
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.build()
|
||||
print(status.getvalue())
|
||||
print(warning.getvalue())
|
||||
|
||||
sys.path.append(codedir)
|
||||
try:
|
||||
assert_build()
|
||||
finally:
|
||||
sys.path.remove(codedir)
|
||||
app = make_app('text', srcdir=outdir)
|
||||
app.build()
|
||||
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.build()
|
||||
print(status.getvalue())
|
||||
print(warning.getvalue())
|
||||
app = make_app('text', srcdir=outdir)
|
||||
app.build()
|
||||
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.build()
|
||||
print(status.getvalue())
|
||||
print(warning.getvalue())
|
||||
app = make_app('text', srcdir=outdir)
|
||||
app.build()
|
||||
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,
|
||||
'--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)
|
||||
|
||||
@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'),
|
||||
],
|
||||
)
|
||||
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.build()
|
||||
print(status.getvalue())
|
||||
print(warning.getvalue())
|
||||
|
||||
sys.path.append(codedir)
|
||||
try:
|
||||
assert_build()
|
||||
finally:
|
||||
sys.path.remove(codedir)
|
||||
app = make_app('text', srcdir=outdir)
|
||||
app.build()
|
||||
print(app._status.getvalue())
|
||||
print(app._warning.getvalue())
|
||||
|
||||
@@ -15,19 +15,21 @@ 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
|
||||
@@ -42,13 +44,11 @@ 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_output(app, status, warning):
|
||||
# info with newline
|
||||
status.truncate(0) # __init__ writes to status
|
||||
@@ -68,7 +68,6 @@ def test_output(app, status, warning):
|
||||
assert app._warncount == old_count + 1
|
||||
|
||||
|
||||
@with_app()
|
||||
def test_output_with_unencodable_char(app, status, warning):
|
||||
|
||||
class StreamWriter(codecs.StreamWriter):
|
||||
@@ -84,20 +83,17 @@ def test_output_with_unencodable_char(app, status, warning):
|
||||
assert status.getvalue() == "unicode ?...\n"
|
||||
|
||||
|
||||
@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'
|
||||
@@ -109,15 +105,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'])
|
||||
@@ -125,7 +124,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'])
|
||||
|
||||
@@ -10,9 +10,8 @@
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
# "raises" imported for usage by autodoc
|
||||
from util import TestApp, Struct, raises, SkipTest # NOQA
|
||||
from nose.tools import with_setup, eq_
|
||||
from util import SphinxTestApp, Struct # NOQA
|
||||
import pytest
|
||||
|
||||
import enum
|
||||
from six import StringIO, add_metaclass
|
||||
@@ -26,7 +25,7 @@ app = None
|
||||
|
||||
def setup_module():
|
||||
global app
|
||||
app = TestApp()
|
||||
app = SphinxTestApp()
|
||||
app.builder.env.app = app
|
||||
app.builder.env.temp_data['docname'] = 'dummy'
|
||||
app.connect('autodoc-process-docstring', process_docstring)
|
||||
@@ -41,6 +40,7 @@ def teardown_module():
|
||||
directive = options = None
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def setup_test():
|
||||
global options, directive
|
||||
global processed_docstrings, processed_signatures, _warnings
|
||||
@@ -74,6 +74,10 @@ def setup_test():
|
||||
processed_signatures = []
|
||||
_warnings = []
|
||||
|
||||
yield
|
||||
|
||||
AutoDirective._special_attrgetters.clear()
|
||||
|
||||
|
||||
_warnings = []
|
||||
processed_docstrings = []
|
||||
@@ -105,7 +109,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)
|
||||
@@ -120,26 +124,27 @@ def test_parse_name():
|
||||
del _warnings[:]
|
||||
|
||||
# for functions/classes
|
||||
verify('function', 'util.raises', ('util', ['raises'], None, None))
|
||||
verify('function', 'util.raises(exc) -> None',
|
||||
('util', ['raises'], 'exc', 'None'))
|
||||
directive.env.temp_data['autodoc:module'] = 'util'
|
||||
verify('function', 'raises', ('util', ['raises'], None, None))
|
||||
verify('function', 'test_autodoc.raises',
|
||||
('test_autodoc', ['raises'], None, None))
|
||||
verify('function', 'test_autodoc.raises(exc) -> None',
|
||||
('test_autodoc', ['raises'], 'exc', 'None'))
|
||||
directive.env.temp_data['autodoc:module'] = 'test_autodoc'
|
||||
verify('function', 'raises', ('test_autodoc', ['raises'], None, None))
|
||||
del directive.env.temp_data['autodoc:module']
|
||||
directive.env.ref_context['py:module'] = 'util'
|
||||
verify('function', 'raises', ('util', ['raises'], None, None))
|
||||
verify('class', 'TestApp', ('util', ['TestApp'], None, None))
|
||||
directive.env.ref_context['py:module'] = 'test_autodoc'
|
||||
verify('function', 'raises', ('test_autodoc', ['raises'], None, None))
|
||||
verify('class', 'Base', ('test_autodoc', ['Base'], None, None))
|
||||
|
||||
# for members
|
||||
directive.env.ref_context['py:module'] = 'foo'
|
||||
verify('method', 'util.TestApp.cleanup',
|
||||
('util', ['TestApp', 'cleanup'], None, None))
|
||||
verify('method', 'util.SphinxTestApp.cleanup',
|
||||
('util', ['SphinxTestApp', 'cleanup'], None, None))
|
||||
directive.env.ref_context['py:module'] = 'util'
|
||||
directive.env.ref_context['py:class'] = 'Foo'
|
||||
directive.env.temp_data['autodoc:class'] = 'TestApp'
|
||||
verify('method', 'cleanup', ('util', ['TestApp', 'cleanup'], None, None))
|
||||
verify('method', 'TestApp.cleanup',
|
||||
('util', ['TestApp', 'cleanup'], None, None))
|
||||
directive.env.temp_data['autodoc:class'] = 'SphinxTestApp'
|
||||
verify('method', 'cleanup', ('util', ['SphinxTestApp', 'cleanup'], None, None))
|
||||
verify('method', 'SphinxTestApp.cleanup',
|
||||
('util', ['SphinxTestApp', 'cleanup'], None, None))
|
||||
|
||||
# and clean up
|
||||
del directive.env.ref_context['py:module']
|
||||
@@ -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)
|
||||
@@ -653,7 +658,7 @@ def test_generate():
|
||||
'Class.meth', more_content=add_content)
|
||||
|
||||
# test check_module
|
||||
inst = FunctionDocumenter(directive, 'raises')
|
||||
inst = FunctionDocumenter(directive, 'add_documenter')
|
||||
inst.generate(check_module=True)
|
||||
assert len(directive.result) == 0
|
||||
|
||||
@@ -873,6 +878,11 @@ __all__ = ['Class']
|
||||
integer = 1
|
||||
|
||||
|
||||
def raises(exc, func, *args, **kwds):
|
||||
"""Raise AssertionError if ``func(*args, **kwds)`` does not raise *exc*."""
|
||||
pass
|
||||
|
||||
|
||||
class CustomEx(Exception):
|
||||
"""My custom exception."""
|
||||
|
||||
@@ -1081,10 +1091,10 @@ def test_type_hints():
|
||||
try:
|
||||
from typing_test_data import f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11
|
||||
except (ImportError, SyntaxError):
|
||||
raise SkipTest('Cannot import Python code with function annotations')
|
||||
pytest.skip('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,21 +9,14 @@
|
||||
: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
|
||||
|
||||
try:
|
||||
from docutils.writers.manpage import Writer as ManWriter
|
||||
except ImportError:
|
||||
ManWriter = None
|
||||
from util import rootdir, tempdir, path
|
||||
|
||||
|
||||
def request_session_head(url, **kwargs):
|
||||
@@ -33,24 +26,17 @@ def request_session_head(url, **kwargs):
|
||||
return response
|
||||
|
||||
|
||||
def verify_build(buildername, srcdir):
|
||||
if buildername == 'man' and ManWriter is None:
|
||||
raise SkipTest('man writer is not available')
|
||||
app = TestApp(buildername=buildername, srcdir=srcdir)
|
||||
try:
|
||||
app.builder.build_all()
|
||||
finally:
|
||||
app.cleanup()
|
||||
|
||||
|
||||
def test_build_all():
|
||||
@pytest.fixture
|
||||
def nonascii_srcdir(request):
|
||||
# If supported, build in a non-ASCII source dir
|
||||
test_name = u'\u65e5\u672c\u8a9e'
|
||||
basedir = tempdir / request.node.originalname
|
||||
try:
|
||||
srcdir = tempdir / test_name
|
||||
(rootdir / 'root').copytree(tempdir / test_name)
|
||||
srcdir = basedir / test_name
|
||||
if not srcdir.exists():
|
||||
(rootdir / 'root').copytree(srcdir)
|
||||
except UnicodeEncodeError:
|
||||
srcdir = tempdir / 'all'
|
||||
srcdir = basedir / 'all'
|
||||
else:
|
||||
# add a doc with a non-ASCII file name to the source dir
|
||||
(srcdir / (test_name + '.txt')).write_text(dedent("""
|
||||
@@ -64,35 +50,36 @@ def test_build_all():
|
||||
|
||||
%(test_name)s/%(test_name)s
|
||||
""" % {'test_name': test_name})
|
||||
)
|
||||
)
|
||||
return srcdir
|
||||
|
||||
with mock.patch('sphinx.builders.linkcheck.requests') as requests:
|
||||
requests.head = request_session_head
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"buildername",
|
||||
[
|
||||
# note: no 'html' - if it's ok with dirhtml it's ok with html
|
||||
for buildername in ['dirhtml', 'singlehtml', 'latex', 'texinfo', 'pickle',
|
||||
'json', 'text', 'htmlhelp', 'qthelp', 'epub2', 'epub',
|
||||
'applehelp', 'changes', 'xml', 'pseudoxml', 'man',
|
||||
'linkcheck']:
|
||||
yield verify_build, buildername, srcdir
|
||||
'dirhtml', 'singlehtml', 'latex', 'texinfo', 'pickle', 'json', 'text',
|
||||
'htmlhelp', 'qthelp', 'epub2', 'epub', 'applehelp', 'changes', 'xml',
|
||||
'pseudoxml', 'man', 'linkcheck',
|
||||
],
|
||||
)
|
||||
@mock.patch('sphinx.builders.linkcheck.requests.head',
|
||||
side_effect=request_session_head)
|
||||
def test_build_all(requests_head, make_app, nonascii_srcdir, buildername):
|
||||
app = make_app(buildername, srcdir=nonascii_srcdir)
|
||||
app.build()
|
||||
|
||||
|
||||
@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, make_app):
|
||||
(tempdir / 'conf.py').write_text('master_doc = "index"')
|
||||
assert tempdir.listdir() == ['conf.py']
|
||||
|
||||
try:
|
||||
app = TestApp(buildername='dummy', srcdir=tmpdir)
|
||||
app = make_app('dummy', srcdir=tempdir)
|
||||
with pytest.raises(SphinxError):
|
||||
app.builder.build_all()
|
||||
assert False # SphinxError not raised
|
||||
except Exception as exc:
|
||||
assert isinstance(exc, SphinxError)
|
||||
finally:
|
||||
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 +91,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 +103,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,9 +43,10 @@ def check_localization(outdir):
|
||||
assert (lprojdir / 'localized.txt').isfile()
|
||||
|
||||
|
||||
@with_app(buildername='applehelp', testroot='basic', srcdir='applehelp_output',
|
||||
confoverrides={'applehelp_bundle_id': 'org.sphinx-doc.Sphinx.help',
|
||||
'applehelp_disable_external_tools': True})
|
||||
@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):
|
||||
(app.srcdir / 'en.lproj').makedirs()
|
||||
(app.srcdir / 'en.lproj' / 'localized.txt').write_text('')
|
||||
|
||||
@@ -15,36 +15,38 @@ 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 sphinx.util.osutil import cd
|
||||
|
||||
|
||||
@gen_with_app('gettext', srcdir='root-gettext')
|
||||
def test_all(app, status, warning):
|
||||
@pytest.mark.sphinx('gettext', srcdir='root-gettext')
|
||||
def test_build_gettext(app):
|
||||
# Generic build; should fail only when the builder is horribly broken.
|
||||
app.builder.build_all()
|
||||
|
||||
# Do messages end up in the correct location?
|
||||
# top-level documents end up in a message catalog
|
||||
yield assert_true, (app.outdir / 'extapi.pot').isfile()
|
||||
assert (app.outdir / 'extapi.pot').isfile()
|
||||
# directory items are grouped into sections
|
||||
yield assert_true, (app.outdir / 'subdir.pot').isfile()
|
||||
assert (app.outdir / 'subdir.pot').isfile()
|
||||
|
||||
# regression test for issue #960
|
||||
catalog = (app.outdir / 'markup.pot').text(encoding='utf-8')
|
||||
yield assert_in, 'msgid "something, something else, something more"', catalog
|
||||
assert 'msgid "something, something else, something more"' in catalog
|
||||
|
||||
|
||||
@pytest.mark.sphinx('gettext', srcdir='root-gettext')
|
||||
def test_msgfmt(app):
|
||||
app.builder.build_all()
|
||||
(app.outdir / 'en' / 'LC_MESSAGES').makedirs()
|
||||
cwd = os.getcwd()
|
||||
os.chdir(app.outdir)
|
||||
try:
|
||||
with cd(app.outdir):
|
||||
try:
|
||||
p = Popen(['msginit', '--no-translator', '-i', 'markup.pot',
|
||||
'--locale', 'en_US'],
|
||||
stdout=PIPE, stderr=PIPE)
|
||||
except OSError:
|
||||
raise SkipTest # most likely msginit was not found
|
||||
pytest.skip() # most likely msginit was not found
|
||||
else:
|
||||
stdout, stderr = p.communicate()
|
||||
if p.returncode != 0:
|
||||
@@ -52,13 +54,13 @@ def test_all(app, status, warning):
|
||||
print(stderr)
|
||||
assert False, 'msginit exited with return code %s' % \
|
||||
p.returncode
|
||||
yield assert_true, (app.outdir / 'en_US.po').isfile(), 'msginit failed'
|
||||
assert (app.outdir / 'en_US.po').isfile(), 'msginit failed'
|
||||
try:
|
||||
p = Popen(['msgfmt', 'en_US.po', '-o',
|
||||
os.path.join('en', 'LC_MESSAGES', 'test_root.mo')],
|
||||
stdout=PIPE, stderr=PIPE)
|
||||
except OSError:
|
||||
raise SkipTest # most likely msgfmt was not found
|
||||
pytest.skip() # most likely msgfmt was not found
|
||||
else:
|
||||
stdout, stderr = p.communicate()
|
||||
if p.returncode != 0:
|
||||
@@ -66,19 +68,17 @@ def test_all(app, status, warning):
|
||||
print(stderr)
|
||||
assert False, 'msgfmt exited with return code %s' % \
|
||||
p.returncode
|
||||
yield (assert_true,
|
||||
(app.outdir / 'en' / 'LC_MESSAGES' / 'test_root.mo').isfile(),
|
||||
'msgfmt failed')
|
||||
finally:
|
||||
os.chdir(cwd)
|
||||
mo = app.outdir / 'en' / 'LC_MESSAGES' / 'test_root.mo'
|
||||
assert mo.isfile(), 'msgfmt failed'
|
||||
|
||||
_ = gettext.translation('test_root', app.outdir, languages=['en']).gettext
|
||||
yield assert_equal, _("Testing various markup"), u"Testing various markup"
|
||||
assert _("Testing various markup") == u"Testing various markup"
|
||||
|
||||
|
||||
@with_app('gettext', testroot='intl',
|
||||
confoverrides={'gettext_compact': False})
|
||||
def test_gettext_index_entries(app, status, warning):
|
||||
@pytest.mark.sphinx(
|
||||
'gettext', testroot='intl', srcdir='gettext',
|
||||
confoverrides={'gettext_compact': False})
|
||||
def test_gettext_index_entries(app):
|
||||
# regression test for #976
|
||||
app.builder.build(['index_entries'])
|
||||
|
||||
@@ -123,9 +123,11 @@ def test_gettext_index_entries(app, status, warning):
|
||||
assert msgids == []
|
||||
|
||||
|
||||
@with_app('gettext', testroot='intl',
|
||||
confoverrides={'gettext_compact': False, 'gettext_additional_targets': []})
|
||||
def test_gettext_disable_index_entries(app, status, warning):
|
||||
@pytest.mark.sphinx(
|
||||
'gettext', testroot='intl', srcdir='gettext',
|
||||
confoverrides={'gettext_compact': False,
|
||||
'gettext_additional_targets': []})
|
||||
def test_gettext_disable_index_entries(app):
|
||||
# regression test for #976
|
||||
app.builder.build(['index_entries'])
|
||||
|
||||
@@ -155,8 +157,8 @@ def test_gettext_disable_index_entries(app, status, warning):
|
||||
assert msgids == []
|
||||
|
||||
|
||||
@with_app(buildername='gettext', testroot='intl')
|
||||
def test_gettext_template(app, status, warning):
|
||||
@pytest.mark.sphinx('gettext', testroot='intl', srcdir='gettext')
|
||||
def test_gettext_template(app):
|
||||
app.builder.build_all()
|
||||
assert (app.outdir / 'sphinx.pot').isfile()
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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,12 +203,13 @@ def test_numref(app, status, warning):
|
||||
'\\nameref{\\detokenize{foo:foo}}}') in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='numfig',
|
||||
confoverrides={'numfig': True,
|
||||
'numfig_format': {'figure': 'Figure:%s',
|
||||
'table': 'Tab_%s',
|
||||
'code-block': 'Code-%s',
|
||||
'section': 'SECTION-%s'}})
|
||||
@pytest.mark.sphinx(
|
||||
'latex', testroot='numfig',
|
||||
confoverrides={'numfig': True,
|
||||
'numfig_format': {'figure': 'Figure:%s',
|
||||
'table': 'Tab_%s',
|
||||
'code-block': 'Code-%s',
|
||||
'section': 'SECTION-%s'}})
|
||||
def test_numref_with_prefix1(app, status, warning):
|
||||
app.builder.build_all()
|
||||
result = (app.outdir / 'Python.tex').text(encoding='utf8')
|
||||
@@ -247,12 +247,13 @@ def test_numref_with_prefix1(app, status, warning):
|
||||
'\\nameref{\\detokenize{foo:foo}}}') in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='numfig',
|
||||
confoverrides={'numfig': True,
|
||||
'numfig_format': {'figure': 'Figure:%s.',
|
||||
'table': 'Tab_%s:',
|
||||
'code-block': 'Code-%s | ',
|
||||
'section': 'SECTION_%s_'}})
|
||||
@pytest.mark.sphinx(
|
||||
'latex', testroot='numfig',
|
||||
confoverrides={'numfig': True,
|
||||
'numfig_format': {'figure': 'Figure:%s.',
|
||||
'table': 'Tab_%s:',
|
||||
'code-block': 'Code-%s | ',
|
||||
'section': 'SECTION_%s_'}})
|
||||
def test_numref_with_prefix2(app, status, warning):
|
||||
app.builder.build_all()
|
||||
result = (app.outdir / 'Python.tex').text(encoding='utf8')
|
||||
@@ -286,8 +287,9 @@ def test_numref_with_prefix2(app, status, warning):
|
||||
'\\nameref{\\detokenize{foo:foo}}}') in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='numfig',
|
||||
confoverrides={'numfig': True, 'language': 'ja'})
|
||||
@pytest.mark.sphinx(
|
||||
'latex', testroot='numfig',
|
||||
confoverrides={'numfig': True, 'language': 'ja'})
|
||||
def test_numref_with_language_ja(app, status, warning):
|
||||
app.builder.build_all()
|
||||
result = (app.outdir / 'Python.tex').text(encoding='utf8')
|
||||
@@ -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,8 +350,9 @@ def test_babel_with_no_language_settings(app, status, warning):
|
||||
assert '\\shorthandoff' not in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='latex-babel',
|
||||
confoverrides={'language': 'de'})
|
||||
@pytest.mark.sphinx(
|
||||
'latex', testroot='latex-babel',
|
||||
confoverrides={'language': 'de'})
|
||||
def test_babel_with_language_de(app, status, warning):
|
||||
app.builder.build_all()
|
||||
result = (app.outdir / 'Python.tex').text(encoding='utf8')
|
||||
@@ -368,8 +371,9 @@ def test_babel_with_language_de(app, status, warning):
|
||||
assert '\\shorthandoff{"}' in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='latex-babel',
|
||||
confoverrides={'language': 'ru'})
|
||||
@pytest.mark.sphinx(
|
||||
'latex', testroot='latex-babel',
|
||||
confoverrides={'language': 'ru'})
|
||||
def test_babel_with_language_ru(app, status, warning):
|
||||
app.builder.build_all()
|
||||
result = (app.outdir / 'Python.tex').text(encoding='utf8')
|
||||
@@ -389,8 +393,9 @@ def test_babel_with_language_ru(app, status, warning):
|
||||
assert '\\shorthandoff' not in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='latex-babel',
|
||||
confoverrides={'language': 'tr'})
|
||||
@pytest.mark.sphinx(
|
||||
'latex', testroot='latex-babel',
|
||||
confoverrides={'language': 'tr'})
|
||||
def test_babel_with_language_tr(app, status, warning):
|
||||
app.builder.build_all()
|
||||
result = (app.outdir / 'Python.tex').text(encoding='utf8')
|
||||
@@ -409,8 +414,9 @@ def test_babel_with_language_tr(app, status, warning):
|
||||
assert '\\shorthandoff{=}' in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='latex-babel',
|
||||
confoverrides={'language': 'ja'})
|
||||
@pytest.mark.sphinx(
|
||||
'latex', testroot='latex-babel',
|
||||
confoverrides={'language': 'ja'})
|
||||
def test_babel_with_language_ja(app, status, warning):
|
||||
app.builder.build_all()
|
||||
result = (app.outdir / 'Python.tex').text(encoding='utf8')
|
||||
@@ -428,8 +434,9 @@ def test_babel_with_language_ja(app, status, warning):
|
||||
assert '\\shorthandoff' not in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='latex-babel',
|
||||
confoverrides={'language': 'unknown'})
|
||||
@pytest.mark.sphinx(
|
||||
'latex', testroot='latex-babel',
|
||||
confoverrides={'language': 'unknown'})
|
||||
def test_babel_with_unknown_language(app, status, warning):
|
||||
app.builder.build_all()
|
||||
result = (app.outdir / 'Python.tex').text(encoding='utf8')
|
||||
@@ -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,8 +524,9 @@ def test_reference_in_caption_and_codeblock_in_footnote(app, status, warning):
|
||||
assert '\\begin{sphinxVerbatim}[commandchars=\\\\\\{\\}]' in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='footnotes',
|
||||
confoverrides={'latex_show_urls': 'inline'})
|
||||
@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()
|
||||
result = (app.outdir / 'Python.tex').text(encoding='utf8')
|
||||
@@ -560,8 +568,9 @@ def test_latex_show_urls_is_inline(app, status, warning):
|
||||
'{sphinx-dev@googlegroups.com}') in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='footnotes',
|
||||
confoverrides={'latex_show_urls': 'footnote'})
|
||||
@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()
|
||||
result = (app.outdir / 'Python.tex').text(encoding='utf8')
|
||||
@@ -611,8 +620,9 @@ def test_latex_show_urls_is_footnote(app, status, warning):
|
||||
'{sphinx-dev@googlegroups.com}\n') in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='footnotes',
|
||||
confoverrides={'latex_show_urls': 'no'})
|
||||
@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()
|
||||
result = (app.outdir / 'Python.tex').text(encoding='utf8')
|
||||
@@ -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,11 +702,12 @@ def test_toctree_maxdepth_manual(app, status, warning):
|
||||
assert '\\setcounter{secnumdepth}' not in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='toctree-maxdepth',
|
||||
confoverrides={'latex_documents': [
|
||||
('index', 'SphinxTests.tex', 'Sphinx Tests Documentation',
|
||||
'Georg Brandl', 'howto'),
|
||||
]})
|
||||
@pytest.mark.sphinx(
|
||||
'latex', testroot='toctree-maxdepth',
|
||||
confoverrides={'latex_documents': [
|
||||
('index', 'SphinxTests.tex', 'Sphinx Tests Documentation',
|
||||
'Georg Brandl', 'howto'),
|
||||
]})
|
||||
def test_toctree_maxdepth_howto(app, status, warning):
|
||||
app.builder.build_all()
|
||||
result = (app.outdir / 'SphinxTests.tex').text(encoding='utf8')
|
||||
@@ -707,8 +718,9 @@ def test_toctree_maxdepth_howto(app, status, warning):
|
||||
assert '\\setcounter{secnumdepth}' not in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='toctree-maxdepth',
|
||||
confoverrides={'master_doc': 'foo'})
|
||||
@pytest.mark.sphinx(
|
||||
'latex', testroot='toctree-maxdepth',
|
||||
confoverrides={'master_doc': 'foo'})
|
||||
def test_toctree_not_found(app, status, warning):
|
||||
app.builder.build_all()
|
||||
result = (app.outdir / 'Python.tex').text(encoding='utf8')
|
||||
@@ -719,8 +731,9 @@ def test_toctree_not_found(app, status, warning):
|
||||
assert '\\setcounter{secnumdepth}' not in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='toctree-maxdepth',
|
||||
confoverrides={'master_doc': 'bar'})
|
||||
@pytest.mark.sphinx(
|
||||
'latex', testroot='toctree-maxdepth',
|
||||
confoverrides={'master_doc': 'bar'})
|
||||
def test_toctree_without_maxdepth(app, status, warning):
|
||||
app.builder.build_all()
|
||||
result = (app.outdir / 'Python.tex').text(encoding='utf8')
|
||||
@@ -731,8 +744,9 @@ def test_toctree_without_maxdepth(app, status, warning):
|
||||
assert '\\setcounter{secnumdepth}' not in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='toctree-maxdepth',
|
||||
confoverrides={'master_doc': 'qux'})
|
||||
@pytest.mark.sphinx(
|
||||
'latex', testroot='toctree-maxdepth',
|
||||
confoverrides={'master_doc': 'qux'})
|
||||
def test_toctree_with_deeper_maxdepth(app, status, warning):
|
||||
app.builder.build_all()
|
||||
result = (app.outdir / 'Python.tex').text(encoding='utf8')
|
||||
@@ -743,8 +757,9 @@ def test_toctree_with_deeper_maxdepth(app, status, warning):
|
||||
assert '\\setcounter{secnumdepth}{3}' in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='toctree-maxdepth',
|
||||
confoverrides={'latex_toplevel_sectioning': None})
|
||||
@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()
|
||||
result = (app.outdir / 'Python.tex').text(encoding='utf8')
|
||||
@@ -754,8 +769,9 @@ def test_latex_toplevel_sectioning_is_None(app, status, warning):
|
||||
assert '\\chapter{Foo}' in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='toctree-maxdepth',
|
||||
confoverrides={'latex_toplevel_sectioning': 'part'})
|
||||
@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()
|
||||
result = (app.outdir / 'Python.tex').text(encoding='utf8')
|
||||
@@ -765,8 +781,9 @@ def test_latex_toplevel_sectioning_is_part(app, status, warning):
|
||||
assert '\\part{Foo}' in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='toctree-maxdepth',
|
||||
confoverrides={'latex_toplevel_sectioning': 'chapter'})
|
||||
@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()
|
||||
result = (app.outdir / 'Python.tex').text(encoding='utf8')
|
||||
@@ -776,8 +793,9 @@ def test_latex_toplevel_sectioning_is_chapter(app, status, warning):
|
||||
assert '\\chapter{Foo}' in result
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='toctree-maxdepth',
|
||||
confoverrides={'latex_toplevel_sectioning': 'section'})
|
||||
@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()
|
||||
result = (app.outdir / 'Python.tex').text(encoding='utf8')
|
||||
@@ -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,8 +26,9 @@ def test_defaults(app, status, warning):
|
||||
assert len(content.splitlines()) == 1
|
||||
|
||||
|
||||
@with_app('linkcheck', testroot='linkcheck', freshenv=True,
|
||||
confoverrides={'linkcheck_anchors_ignore': ["^!", "^top$"]})
|
||||
@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,14 +31,15 @@ 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',
|
||||
confoverrides={'language': 'en', 'locale_dirs': [locale_dir]})
|
||||
@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,9 +53,10 @@ def test_compile_all_catalogs(app, status, warning):
|
||||
assert actual == expect
|
||||
|
||||
|
||||
@with_setup(setup_test, teardown_test)
|
||||
@with_app(buildername='html', testroot='intl',
|
||||
confoverrides={'language': 'en', 'locale_dirs': [locale_dir]})
|
||||
@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,9 +69,10 @@ 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',
|
||||
confoverrides={'language': 'en', 'locale_dirs': [locale_dir]})
|
||||
@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,19 +10,19 @@
|
||||
: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
|
||||
|
||||
import sphinx
|
||||
from sphinx.config import Config
|
||||
from sphinx.errors import ExtensionError, ConfigError, VersionRequirementError
|
||||
|
||||
|
||||
@with_app(confoverrides={'master_doc': 'master', 'nonexisting_value': 'True',
|
||||
'latex_elements.docclass': 'scrartcl',
|
||||
'modindex_common_prefix': 'path1,path2'})
|
||||
@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):
|
||||
cfg = app.config
|
||||
|
||||
@@ -55,11 +55,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 +73,6 @@ def test_core_config(app, status, warning):
|
||||
assert cfg['project'] == cfg.project == 'Sphinx Tests'
|
||||
|
||||
|
||||
@with_app()
|
||||
def test_extension_values(app, status, warning):
|
||||
cfg = app.config
|
||||
|
||||
@@ -80,23 +82,26 @@ 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
|
||||
def test_errors_warnings(dir):
|
||||
def test_errors_warnings(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(lambda warning: 1/0)
|
||||
assert cfg.project == u'Jägermeister'
|
||||
|
||||
@@ -105,9 +110,9 @@ def test_errors_warnings(dir):
|
||||
# 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)
|
||||
warned = [False]
|
||||
|
||||
def warn(msg):
|
||||
@@ -117,62 +122,64 @@ def test_errors_warnings(dir):
|
||||
assert warned[0]
|
||||
|
||||
|
||||
@with_tempdir
|
||||
def test_errors_if_setup_is_not_callable(dir):
|
||||
def test_errors_if_setup_is_not_callable(tempdir, make_app):
|
||||
# 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:
|
||||
make_app(srcdir=tempdir)
|
||||
assert 'callable' in str(excinfo.value)
|
||||
|
||||
|
||||
@mock.patch.object(sphinx, '__display_version__', '1.3.4')
|
||||
def test_needs_sphinx():
|
||||
def test_needs_sphinx(make_app):
|
||||
# micro version
|
||||
app = TestApp(confoverrides={'needs_sphinx': '1.3.3'}) # OK: less
|
||||
app = make_app(confoverrides={'needs_sphinx': '1.3.3'}) # OK: less
|
||||
app.cleanup()
|
||||
app = TestApp(confoverrides={'needs_sphinx': '1.3.4'}) # OK: equals
|
||||
app = make_app(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):
|
||||
make_app(confoverrides={'needs_sphinx': '1.3.5'}) # NG: greater
|
||||
|
||||
# minor version
|
||||
app = TestApp(confoverrides={'needs_sphinx': '1.2'}) # OK: less
|
||||
app = make_app(confoverrides={'needs_sphinx': '1.2'}) # OK: less
|
||||
app.cleanup()
|
||||
app = TestApp(confoverrides={'needs_sphinx': '1.3'}) # OK: equals
|
||||
app = make_app(confoverrides={'needs_sphinx': '1.3'}) # OK: equals
|
||||
app.cleanup()
|
||||
raises(VersionRequirementError, TestApp,
|
||||
confoverrides={'needs_sphinx': '1.4'}) # NG: greater
|
||||
with pytest.raises(VersionRequirementError):
|
||||
make_app(confoverrides={'needs_sphinx': '1.4'}) # NG: greater
|
||||
|
||||
# major version
|
||||
app = TestApp(confoverrides={'needs_sphinx': '0'}) # OK: less
|
||||
app = make_app(confoverrides={'needs_sphinx': '0'}) # OK: less
|
||||
app.cleanup()
|
||||
app = TestApp(confoverrides={'needs_sphinx': '1'}) # OK: equals
|
||||
app = make_app(confoverrides={'needs_sphinx': '1'}) # OK: equals
|
||||
app.cleanup()
|
||||
raises(VersionRequirementError, TestApp,
|
||||
confoverrides={'needs_sphinx': '2'}) # NG: greater
|
||||
with pytest.raises(VersionRequirementError):
|
||||
make_app(confoverrides={'needs_sphinx': '2'}) # NG: greater
|
||||
|
||||
|
||||
@with_tempdir
|
||||
def test_config_eol(tmpdir):
|
||||
def test_config_eol(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(lambda warning: 1/0)
|
||||
assert cfg.project == u'spam'
|
||||
|
||||
|
||||
@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):
|
||||
warnings = warning.getvalue()
|
||||
assert_in('master_doc', warnings,
|
||||
'override on builtin "master_doc" should raise a type warning')
|
||||
assert_not_in('language', warnings, 'explicitly permitted '
|
||||
'override on builtin "language" should NOT raise a type warning')
|
||||
assert_not_in('primary_domain', warnings, 'override to None on builtin '
|
||||
'"primary_domain" should NOT raise a type warning')
|
||||
assert 'master_doc' in warnings, (
|
||||
'override on builtin "master_doc" should raise a type warning')
|
||||
assert 'language' not in warnings, (
|
||||
'explicitly permitted override on builtin "language" should NOT raise '
|
||||
'a type warning')
|
||||
assert 'primary_domain' not in warnings, (
|
||||
'override to None on builtin "primary_domain" should NOT raise a type '
|
||||
'warning')
|
||||
|
||||
|
||||
# See roots/test-config/conf.py.
|
||||
@@ -187,7 +194,7 @@ TYPECHECK_WARNINGS = {
|
||||
'value8': False,
|
||||
'value9': False,
|
||||
'value10': False,
|
||||
'value11': True,
|
||||
'value11': False if PY3 else True,
|
||||
'value12': False,
|
||||
'value13': False,
|
||||
'value14': False,
|
||||
@@ -196,25 +203,27 @@ TYPECHECK_WARNINGS = {
|
||||
}
|
||||
|
||||
|
||||
@gen_with_app(testroot='config')
|
||||
def test_gen_check_types(app, status, warning):
|
||||
if PY3:
|
||||
TYPECHECK_WARNINGS['value11'] = False
|
||||
|
||||
for key, should in iteritems(TYPECHECK_WARNINGS):
|
||||
yield assert_in if should else assert_not_in, key, warning.getvalue(), (
|
||||
'override on "%s" should%s raise a type warning' %
|
||||
(key, '' if should else ' NOT')
|
||||
@pytest.mark.parametrize("key,should", iteritems(TYPECHECK_WARNINGS))
|
||||
@pytest.mark.sphinx(testroot='config')
|
||||
def test_check_types(warning, key, should):
|
||||
warn = warning.getvalue()
|
||||
if should:
|
||||
assert key in warn, (
|
||||
'override on "%s" should raise a type warning' % key
|
||||
)
|
||||
else:
|
||||
assert key not in warn, (
|
||||
'override on "%s" should NOT raise a type warning' % key
|
||||
)
|
||||
|
||||
|
||||
@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()
|
||||
|
||||
@@ -8,42 +8,30 @@
|
||||
:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
import os
|
||||
|
||||
from util import TestApp
|
||||
import pytest
|
||||
|
||||
|
||||
def test_correct_year():
|
||||
try:
|
||||
# save current value of SOURCE_DATE_EPOCH
|
||||
sde = os.environ.pop('SOURCE_DATE_EPOCH', None)
|
||||
|
||||
@pytest.fixture(
|
||||
params=[
|
||||
# test with SOURCE_DATE_EPOCH unset: no modification
|
||||
app = TestApp(buildername='html', testroot='correct-year')
|
||||
app.builder.build_all()
|
||||
content = (app.outdir / 'contents.html').text()
|
||||
app.cleanup()
|
||||
assert '2006-2009' in content
|
||||
(None, '2006-2009'),
|
||||
# test with SOURCE_DATE_EPOCH set: copyright year should be updated
|
||||
('1293840000', '2006-2011'),
|
||||
('1293839999', '2006-2010'),
|
||||
],
|
||||
|
||||
# test with SOURCE_DATE_EPOCH set: copyright year should be
|
||||
# updated
|
||||
os.environ['SOURCE_DATE_EPOCH'] = "1293840000"
|
||||
app = TestApp(buildername='html', testroot='correct-year')
|
||||
app.builder.build_all()
|
||||
content = (app.outdir / 'contents.html').text()
|
||||
app.cleanup()
|
||||
assert '2006-2011' in content
|
||||
)
|
||||
def expect_date(request, monkeypatch):
|
||||
sde, expect = request.param
|
||||
if sde:
|
||||
monkeypatch.setenv('SOURCE_DATE_EPOCH', sde)
|
||||
else:
|
||||
monkeypatch.delenv('SOURCE_DATE_EPOCH', raising=False)
|
||||
yield expect
|
||||
|
||||
os.environ['SOURCE_DATE_EPOCH'] = "1293839999"
|
||||
app = TestApp(buildername='html', testroot='correct-year')
|
||||
app.builder.build_all()
|
||||
content = (app.outdir / 'contents.html').text()
|
||||
app.cleanup()
|
||||
assert '2006-2010' in content
|
||||
|
||||
finally:
|
||||
# Restores SOURCE_DATE_EPOCH
|
||||
if sde is None:
|
||||
os.environ.pop('SOURCE_DATE_EPOCH', None)
|
||||
else:
|
||||
os.environ['SOURCE_DATE_EPOCH'] = sde
|
||||
@pytest.mark.sphinx('html', testroot='correct-year')
|
||||
def test_correct_year(expect_date, app):
|
||||
app.build()
|
||||
content = (app.outdir / 'contents.html').text()
|
||||
assert expect_date in content
|
||||
|
||||
@@ -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,31 +46,31 @@ 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',
|
||||
docutilsconf='[general]\nsource_link=true\n')
|
||||
@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)
|
||||
mb_name = u'\u65e5\u672c\u8a9e'
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -9,9 +9,7 @@
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
from six import PY3
|
||||
|
||||
from util import TestApp, remove_unicode_literals, path
|
||||
from util import SphinxTestApp, path
|
||||
|
||||
from sphinx.builders.html import StandaloneHTMLBuilder
|
||||
from sphinx.builders.latex import LaTeXBuilder
|
||||
@@ -22,7 +20,7 @@ warnings = []
|
||||
|
||||
def setup_module():
|
||||
global app, env
|
||||
app = TestApp(srcdir='root-envtest')
|
||||
app = SphinxTestApp(srcdir='root-envtest')
|
||||
env = app.env
|
||||
env.set_warnfunc(lambda *args, **kwargs: warnings.append(args))
|
||||
|
||||
@@ -54,7 +52,6 @@ def test_images():
|
||||
'http://www.python.org/logo.png')
|
||||
|
||||
tree = env.get_doctree('images')
|
||||
app._warning.reset()
|
||||
htmlbuilder = StandaloneHTMLBuilder(app)
|
||||
htmlbuilder.imgpath = 'dummy'
|
||||
htmlbuilder.post_process_images(tree)
|
||||
@@ -64,7 +61,6 @@ def test_images():
|
||||
assert set(htmlbuilder.images.values()) == \
|
||||
set(['img.png', 'img1.png', 'simg.png', 'svgimg.svg', 'img.foo.png'])
|
||||
|
||||
app._warning.reset()
|
||||
latexbuilder = LaTeXBuilder(app)
|
||||
latexbuilder.post_process_images(tree)
|
||||
assert set(latexbuilder.images.keys()) == \
|
||||
|
||||
@@ -14,24 +14,15 @@ 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 assert_node
|
||||
|
||||
|
||||
@gen_with_app('xml', testroot='toctree')
|
||||
def test_basic(app, status, warning):
|
||||
@pytest.mark.sphinx('xml', testroot='toctree')
|
||||
@pytest.mark.test_params(shared_result='test_environment_toctree_basic')
|
||||
def test_process_doc(app):
|
||||
app.build()
|
||||
yield _test_process_doc, app
|
||||
yield _test_get_toc_for, app
|
||||
yield _test_get_toc_for_only, app
|
||||
yield _test_get_toc_for_tocdepth, app
|
||||
yield _test_get_toctree_for, app
|
||||
yield _test_get_toctree_for_collapse, app
|
||||
yield _test_get_toctree_for_maxdepth, app
|
||||
yield _test_get_toctree_for_includehidden, app
|
||||
|
||||
|
||||
def _test_process_doc(app):
|
||||
# tocs
|
||||
toctree = app.env.tocs['index']
|
||||
assert_node(toctree,
|
||||
@@ -97,8 +88,8 @@ def _test_process_doc(app):
|
||||
assert 'qux' not in app.env.toctree_includes
|
||||
|
||||
|
||||
@with_app('dummy', testroot='toctree-glob')
|
||||
def test_glob(app, status, warning):
|
||||
@pytest.mark.sphinx('dummy', testroot='toctree-glob')
|
||||
def test_glob(app):
|
||||
includefiles = ['foo', 'bar/index', 'bar/bar_1', 'bar/bar_2',
|
||||
'bar/bar_3', 'baz', 'qux/index']
|
||||
|
||||
@@ -143,7 +134,10 @@ def test_glob(app, status, warning):
|
||||
assert app.env.numbered_toctrees == set()
|
||||
|
||||
|
||||
def _test_get_toc_for(app):
|
||||
@pytest.mark.sphinx('xml', testroot='toctree')
|
||||
@pytest.mark.test_params(shared_result='test_environment_toctree_basic')
|
||||
def test_get_toc_for(app):
|
||||
app.build()
|
||||
toctree = app.env.get_toc_for('index', app.builder)
|
||||
|
||||
assert_node(toctree,
|
||||
@@ -166,7 +160,10 @@ def _test_get_toc_for(app):
|
||||
[compact_paragraph, reference, "Indices and tables"])
|
||||
|
||||
|
||||
def _test_get_toc_for_only(app):
|
||||
@pytest.mark.sphinx('xml', testroot='toctree')
|
||||
@pytest.mark.test_params(shared_result='test_environment_toctree_basic')
|
||||
def test_get_toc_for_only(app):
|
||||
app.build()
|
||||
builder = StandaloneHTMLBuilder(app)
|
||||
toctree = app.env.get_toc_for('index', builder)
|
||||
|
||||
@@ -193,7 +190,10 @@ def _test_get_toc_for_only(app):
|
||||
[compact_paragraph, reference, "Indices and tables"])
|
||||
|
||||
|
||||
def _test_get_toc_for_tocdepth(app):
|
||||
@pytest.mark.sphinx('xml', testroot='toctree')
|
||||
@pytest.mark.test_params(shared_result='test_environment_toctree_basic')
|
||||
def test_get_toc_for_tocdepth(app):
|
||||
app.build()
|
||||
toctree = app.env.get_toc_for('tocdepth', app.builder)
|
||||
|
||||
assert_node(toctree,
|
||||
@@ -205,7 +205,10 @@ def _test_get_toc_for_tocdepth(app):
|
||||
[bullet_list, list_item, compact_paragraph, reference, "level 2"])
|
||||
|
||||
|
||||
def _test_get_toctree_for(app):
|
||||
@pytest.mark.sphinx('xml', testroot='toctree')
|
||||
@pytest.mark.test_params(shared_result='test_environment_toctree_basic')
|
||||
def test_get_toctree_for(app):
|
||||
app.build()
|
||||
toctree = app.env.get_toctree_for('index', app.builder, collapse=False)
|
||||
assert_node(toctree,
|
||||
[compact_paragraph, ([caption, "Table of Contents"],
|
||||
@@ -239,7 +242,10 @@ def _test_get_toctree_for(app):
|
||||
assert_node(toctree[3][1][0][0], reference, refuri="http://python.org/")
|
||||
|
||||
|
||||
def _test_get_toctree_for_collapse(app):
|
||||
@pytest.mark.sphinx('xml', testroot='toctree')
|
||||
@pytest.mark.test_params(shared_result='test_environment_toctree_basic')
|
||||
def test_get_toctree_for_collapse(app):
|
||||
app.build()
|
||||
toctree = app.env.get_toctree_for('index', app.builder, collapse=True)
|
||||
assert_node(toctree,
|
||||
[compact_paragraph, ([caption, "Table of Contents"],
|
||||
@@ -264,7 +270,10 @@ def _test_get_toctree_for_collapse(app):
|
||||
assert_node(toctree[3][1][0][0], reference, refuri="http://python.org/")
|
||||
|
||||
|
||||
def _test_get_toctree_for_maxdepth(app):
|
||||
@pytest.mark.sphinx('xml', testroot='toctree')
|
||||
@pytest.mark.test_params(shared_result='test_environment_toctree_basic')
|
||||
def test_get_toctree_for_maxdepth(app):
|
||||
app.build()
|
||||
toctree = app.env.get_toctree_for('index', app.builder, collapse=False, maxdepth=3)
|
||||
assert_node(toctree,
|
||||
[compact_paragraph, ([caption, "Table of Contents"],
|
||||
@@ -303,7 +312,10 @@ def _test_get_toctree_for_maxdepth(app):
|
||||
assert_node(toctree[3][1][0][0], reference, refuri="http://python.org/")
|
||||
|
||||
|
||||
def _test_get_toctree_for_includehidden(app):
|
||||
@pytest.mark.sphinx('xml', testroot='toctree')
|
||||
@pytest.mark.test_params(shared_result='test_environment_toctree_basic')
|
||||
def test_get_toctree_for_includehidden(app):
|
||||
app.build()
|
||||
toctree = app.env.get_toctree_for('index', app.builder, collapse=False,
|
||||
includehidden=False)
|
||||
assert_node(toctree,
|
||||
|
||||
@@ -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()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user