summaryrefslogtreecommitdiff
path: root/tests/test_build_html.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_build_html.py')
-rw-r--r--tests/test_build_html.py191
1 files changed, 141 insertions, 50 deletions
diff --git a/tests/test_build_html.py b/tests/test_build_html.py
index 3ee89b72b..b1181fbeb 100644
--- a/tests/test_build_html.py
+++ b/tests/test_build_html.py
@@ -5,7 +5,7 @@
Test the HTML builder and check output against XPath.
- :copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS.
+ :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@@ -16,7 +16,7 @@ from six import PY3, iteritems
from six.moves import html_entities
from sphinx import __display_version__
-from util import remove_unicode_literals, gen_with_app
+from util import remove_unicode_literals, gen_with_app, with_app
from etree13 import ElementTree as ET
@@ -31,18 +31,16 @@ http://www.python.org/logo.png
reading included file u'.*?wrongenc.inc' seems to be wrong, try giving an \
:encoding: option\\n?
%(root)s/includes.txt:4: WARNING: download file not readable: .*?nonexisting.png
-(%(root)s/markup.txt:\\d+: WARNING: Malformed :option: u'&option', does \
-not contain option marker - or -- or / or \\+
-%(root)s/undecodable.txt:3: WARNING: undecodable source characters, replacing \
+(%(root)s/markup.txt:359: WARNING: invalid single index entry u'')?
+(%(root)s/undecodable.txt:3: WARNING: undecodable source characters, replacing \
with "\\?": b?'here: >>>(\\\\|/)xbb<<<'
)?"""
HTML_WARNINGS = ENV_WARNINGS + """\
%(root)s/images.txt:20: WARNING: no matching candidate for image URI u'foo.\\*'
-None:\\d+: WARNING: citation not found: missing
-%(root)s/markup.txt:: WARNING: invalid single index entry u''
-%(root)s/markup.txt:: WARNING: invalid pair index entry u''
-%(root)s/markup.txt:: WARNING: invalid pair index entry u'keyword; '
+%(root)s/markup.txt:271: WARNING: Could not lex literal_block as "c". Highlighting skipped.
+%(root)s/footnote.txt:60: WARNING: citation not found: missing
+%(root)s/markup.txt:160: WARNING: unknown option: &option
"""
if PY3:
@@ -83,9 +81,9 @@ HTML_XPATH = {
(".//pre", u'Max Strauß'),
(".//a[@href='_downloads/img.png']", ''),
(".//a[@href='_downloads/img1.png']", ''),
- (".//pre", u'"quotes"'),
- (".//pre", u"'included'"),
- (".//pre/span[@class='s']", u'üöä'),
+ (".//pre/span", u'"quotes"'),
+ (".//pre/span", u"'included'"),
+ (".//pre/span[@class='s2']", u'üöä'),
(".//div[@class='inc-pyobj1 highlight-text']//pre",
r'^class Foo:\n pass\n\s*$'),
(".//div[@class='inc-pyobj2 highlight-text']//pre",
@@ -154,7 +152,7 @@ HTML_XPATH = {
(".//a[@href='#grammar-token-try_stmt']"
"[@class='reference internal']/code/span", '^statement$'),
(".//a[@href='subdir/includes.html']"
- "[@class='reference internal']/em", 'Including in subdir'),
+ "[@class='reference internal']/span", 'Including in subdir'),
(".//a[@href='objects.html#cmdoption-python-c']"
"[@class='reference internal']/code/span[@class='pre']", '-c'),
# abbreviations
@@ -234,6 +232,23 @@ HTML_XPATH = {
(".//td[@class='field-body']/ul/li/strong", '^hour$'),
(".//td[@class='field-body']/ul/li/em", '^DuplicateType$'),
(".//td[@class='field-body']/ul/li/em", tail_check(r'.* Some parameter')),
+ # others
+ (".//a[@class='reference internal'][@href='#cmdoption-perl-arg-+p']/code/span",
+ 'perl'),
+ (".//a[@class='reference internal'][@href='#cmdoption-perl-arg-+p']/code/span",
+ '\+p'),
+ (".//a[@class='reference internal'][@href='#cmdoption-perl-arg-arg']/code/span",
+ 'arg'),
+ (".//a[@class='reference internal'][@href='#cmdoption-hg-arg-commit']/code/span",
+ 'hg'),
+ (".//a[@class='reference internal'][@href='#cmdoption-hg-arg-commit']/code/span",
+ 'commit'),
+ (".//a[@class='reference internal'][@href='#cmdoption-git-commit-p']/code/span",
+ 'git'),
+ (".//a[@class='reference internal'][@href='#cmdoption-git-commit-p']/code/span",
+ 'commit'),
+ (".//a[@class='reference internal'][@href='#cmdoption-git-commit-p']/code/span",
+ '-p'),
],
'contents.html': [
(".//meta[@name='hc'][@content='hcval']", ''),
@@ -280,14 +295,18 @@ HTML_XPATH = {
(".//dt/a", "double"),
],
'footnote.html': [
- (".//a[@class='footnote-reference'][@href='#id5'][@id='id1']", r"\[1\]"),
- (".//a[@class='footnote-reference'][@href='#id6'][@id='id2']", r"\[2\]"),
+ (".//a[@class='footnote-reference'][@href='#id7'][@id='id1']", r"\[1\]"),
+ (".//a[@class='footnote-reference'][@href='#id8'][@id='id2']", r"\[2\]"),
(".//a[@class='footnote-reference'][@href='#foo'][@id='id3']", r"\[3\]"),
(".//a[@class='reference internal'][@href='#bar'][@id='id4']", r"\[bar\]"),
+ (".//a[@class='footnote-reference'][@href='#id9'][@id='id5']", r"\[4\]"),
+ (".//a[@class='footnote-reference'][@href='#id10'][@id='id6']", r"\[5\]"),
(".//a[@class='fn-backref'][@href='#id1']", r"\[1\]"),
(".//a[@class='fn-backref'][@href='#id2']", r"\[2\]"),
(".//a[@class='fn-backref'][@href='#id3']", r"\[3\]"),
(".//a[@class='fn-backref'][@href='#id4']", r"\[bar\]"),
+ (".//a[@class='fn-backref'][@href='#id5']", r"\[4\]"),
+ (".//a[@class='fn-backref'][@href='#id6']", r"\[5\]"),
],
'otherext.html': [
(".//h1", "Generated section"),
@@ -325,12 +344,23 @@ def check_xpath(etree, fname, path, check, be_found=True):
# only check for node presence
pass
else:
+ def get_text(node):
+ if node.text is not None:
+ return node.text
+ else:
+ # Since pygments-2.1.1, empty <span> tag is inserted at top of
+ # highlighting block
+ if len(node) == 1 and node[0].tag == 'span' and node[0].text is None:
+ return node[0].tail
+ else:
+ return ''
+
rex = re.compile(check)
if be_found:
- if any(node.text and rex.search(node.text) for node in nodes):
+ if any(rex.search(get_text(node)) for node in nodes):
return
else:
- if all(node.text and not rex.search(node.text) for node in nodes):
+ if all(not rex.search(get_text(node)) for node in nodes):
return
assert False, ('%r not found in any node matching '
@@ -356,7 +386,7 @@ def check_extra_entries(outdir):
assert (outdir / 'robots.txt').isfile()
-@gen_with_app(buildername='html',
+@gen_with_app(buildername='html', freshenv=True, # use freshenv to check warnings
confoverrides={'html_context.hckey_co': 'hcval_co'},
tags=['testtag'])
def test_html_output(app, status, warning):
@@ -372,11 +402,8 @@ def test_html_output(app, status, warning):
for fname, paths in iteritems(HTML_XPATH):
parser = NslessParser()
parser.entity.update(html_entities.entitydefs)
- fp = open(os.path.join(app.outdir, fname), 'rb')
- try:
+ with (app.outdir / fname).open('rb') as fp:
etree = ET.parse(fp, parser)
- finally:
- fp.close()
for path, check in paths:
yield check_xpath, etree, fname, path, check
@@ -425,11 +452,8 @@ def test_tocdepth(app, status, warning):
for fname, paths in iteritems(expects):
parser = NslessParser()
parser.entity.update(html_entities.entitydefs)
- fp = open(os.path.join(app.outdir, fname), 'rb')
- try:
+ with (app.outdir / fname).open('rb') as fp:
etree = ET.parse(fp, parser)
- finally:
- fp.close()
for xpath, check, be_found in paths:
yield check_xpath, etree, fname, xpath, check, be_found
@@ -470,11 +494,8 @@ def test_tocdepth_singlehtml(app, status, warning):
for fname, paths in iteritems(expects):
parser = NslessParser()
parser.entity.update(html_entities.entitydefs)
- fp = open(os.path.join(app.outdir, fname), 'rb')
- try:
+ with (app.outdir / fname).open('rb') as fp:
etree = ET.parse(fp, parser)
- finally:
- fp.close()
for xpath, check, be_found in paths:
yield check_xpath, etree, fname, xpath, check, be_found
@@ -484,6 +505,11 @@ def test_tocdepth_singlehtml(app, status, warning):
def test_numfig_disabled(app, status, warning):
app.builder.build_all()
+ assert ('index.rst:45: WARNING: numfig is disabled. :numref: is ignored.'
+ in warning.getvalue())
+ assert 'index.rst:51: WARNING: invalid numfig_format: invalid' not in warning.getvalue()
+ assert 'index.rst:52: WARNING: invalid numfig_format: Fig %s %s' not in warning.getvalue()
+
expects = {
'index.html': [
(".//div[@class='figure']/p[@class='caption']/"
@@ -524,11 +550,8 @@ def test_numfig_disabled(app, status, warning):
for fname, paths in iteritems(expects):
parser = NslessParser()
parser.entity.update(html_entities.entitydefs)
- fp = open(os.path.join(app.outdir, fname), 'rb')
- try:
+ with (app.outdir / fname).open('rb') as fp:
etree = ET.parse(fp, parser)
- finally:
- fp.close()
for xpath, check, be_found in paths:
yield check_xpath, etree, fname, xpath, check, be_found
@@ -543,6 +566,11 @@ def test_numfig_without_numbered_toctree(app, status, warning):
(app.srcdir / 'index.rst').write_text(index, encoding='utf-8')
app.builder.build_all()
+ assert ('index.rst:45: WARNING: numfig is disabled. :numref: is ignored.'
+ not in warning.getvalue())
+ assert 'index.rst:51: WARNING: invalid numfig_format: invalid' in warning.getvalue()
+ assert 'index.rst:52: WARNING: invalid numfig_format: Fig %s %s' in warning.getvalue()
+
expects = {
'index.html': [
(".//div[@class='figure']/p[@class='caption']/"
@@ -623,11 +651,8 @@ def test_numfig_without_numbered_toctree(app, status, warning):
for fname, paths in iteritems(expects):
parser = NslessParser()
parser.entity.update(html_entities.entitydefs)
- fp = open(os.path.join(app.outdir, fname), 'rb')
- try:
+ with (app.outdir / fname).open('rb') as fp:
etree = ET.parse(fp, parser)
- finally:
- fp.close()
for xpath, check, be_found in paths:
yield check_xpath, etree, fname, xpath, check, be_found
@@ -638,6 +663,11 @@ def test_numfig_without_numbered_toctree(app, status, warning):
def test_numfig_with_numbered_toctree(app, status, warning):
app.builder.build_all()
+ assert ('index.rst:45: WARNING: numfig is disabled. :numref: is ignored.'
+ not in warning.getvalue())
+ assert 'index.rst:51: WARNING: invalid numfig_format: invalid' in warning.getvalue()
+ assert 'index.rst:52: WARNING: invalid numfig_format: Fig %s %s' in warning.getvalue()
+
expects = {
'index.html': [
(".//div[@class='figure']/p[@class='caption']/"
@@ -718,11 +748,8 @@ def test_numfig_with_numbered_toctree(app, status, warning):
for fname, paths in iteritems(expects):
parser = NslessParser()
parser.entity.update(html_entities.entitydefs)
- fp = open(os.path.join(app.outdir, fname), 'rb')
- try:
+ with (app.outdir / fname).open('rb') as fp:
etree = ET.parse(fp, parser)
- finally:
- fp.close()
for xpath, check, be_found in paths:
yield check_xpath, etree, fname, xpath, check, be_found
@@ -736,6 +763,11 @@ def test_numfig_with_numbered_toctree(app, status, warning):
def test_numfig_with_prefix(app, status, warning):
app.builder.build_all()
+ assert ('index.rst:45: WARNING: numfig is disabled. :numref: is ignored.'
+ not in warning.getvalue())
+ assert 'index.rst:51: WARNING: invalid numfig_format: invalid' in warning.getvalue()
+ assert 'index.rst:52: WARNING: invalid numfig_format: Fig %s %s' in warning.getvalue()
+
expects = {
'index.html': [
(".//div[@class='figure']/p[@class='caption']/"
@@ -816,11 +848,8 @@ def test_numfig_with_prefix(app, status, warning):
for fname, paths in iteritems(expects):
parser = NslessParser()
parser.entity.update(html_entities.entitydefs)
- fp = open(os.path.join(app.outdir, fname), 'rb')
- try:
+ with (app.outdir / fname).open('rb') as fp:
etree = ET.parse(fp, parser)
- finally:
- fp.close()
for xpath, check, be_found in paths:
yield check_xpath, etree, fname, xpath, check, be_found
@@ -831,6 +860,11 @@ def test_numfig_with_prefix(app, status, warning):
def test_numfig_with_secnum_depth(app, status, warning):
app.builder.build_all()
+ assert ('index.rst:45: WARNING: numfig is disabled. :numref: is ignored.'
+ not in warning.getvalue())
+ assert 'index.rst:51: WARNING: invalid numfig_format: invalid' in warning.getvalue()
+ assert 'index.rst:52: WARNING: invalid numfig_format: Fig %s %s' in warning.getvalue()
+
expects = {
'index.html': [
(".//div[@class='figure']/p[@class='caption']/"
@@ -911,11 +945,68 @@ def test_numfig_with_secnum_depth(app, status, warning):
for fname, paths in iteritems(expects):
parser = NslessParser()
parser.entity.update(html_entities.entitydefs)
- fp = open(os.path.join(app.outdir, fname), 'rb')
- try:
+ with (app.outdir / fname).open('rb') as fp:
+ etree = ET.parse(fp, parser)
+
+ for xpath, check, be_found in paths:
+ yield check_xpath, etree, fname, xpath, check, be_found
+
+
+@gen_with_app(buildername='html', testroot='add_enumerable_node')
+def test_enumerable_node(app, status, warning):
+ app.builder.build_all()
+
+ expects = {
+ 'index.html': [
+ (".//div[@class='figure']/p[@class='caption']/span[@class='caption-number']",
+ "Fig. 1", True),
+ (".//div[@class='figure']/p[@class='caption']/span[@class='caption-number']",
+ "Fig. 2", True),
+ (".//div[@class='figure']/p[@class='caption']/span[@class='caption-number']",
+ "Fig. 3", True),
+ (".//div//span[@class='caption-number']", "No.1 ", True),
+ (".//div//span[@class='caption-number']", "No.2 ", True),
+ (".//li/a/span", 'Fig. 1', True),
+ (".//li/a/span", 'Fig. 2', True),
+ (".//li/a/span", 'Fig. 3', True),
+ (".//li/a/span", 'No.1', True),
+ (".//li/a/span", 'No.2', True),
+ ],
+ }
+
+ for fname, paths in iteritems(expects):
+ parser = NslessParser()
+ parser.entity.update(html_entities.entitydefs)
+ with (app.outdir / fname).open('rb') as fp:
etree = ET.parse(fp, parser)
- finally:
- fp.close()
for xpath, check, be_found in paths:
yield check_xpath, etree, fname, xpath, check, be_found
+
+
+@with_app(buildername='html')
+def test_jsmath(app, status, warning):
+ app.builder.build_all()
+ content = (app.outdir / 'math.html').text()
+
+ assert '<div class="math">\na^2 + b^2 = c^2</div>' in content
+ assert '<div class="math">\n\\begin{split}a + 1 &lt; b\\end{split}</div>' in content
+ assert ('<span class="eqno">(1)</span><div class="math" id="equation-foo">\n'
+ 'e^{i\\pi} = 1</div>' in content)
+ assert ('<span class="eqno">(2)</span><div class="math">\n'
+ 'e^{ix} = \\cos x + i\\sin x</div>' in content)
+ assert '<div class="math">\nn \\in \\mathbb N</div>' in content
+ assert '<div class="math">\na + 1 &lt; b</div>' in content
+
+
+@with_app(buildername='html', testroot='html_extra_path')
+def test_html_extra_path(app, status, warning):
+ app.builder.build_all()
+
+ assert (app.outdir / '.htaccess').exists()
+ assert not (app.outdir / '.htpasswd').exists()
+ assert (app.outdir / 'API.html_t').exists()
+ assert (app.outdir / 'css/style.css').exists()
+ assert (app.outdir / 'rimg.png').exists()
+ assert not (app.outdir / '_build/index.html').exists()
+ assert (app.outdir / 'background.png').exists()