summaryrefslogtreecommitdiff
path: root/tests/test_intl.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_intl.py')
-rw-r--r--tests/test_intl.py859
1 files changed, 533 insertions, 326 deletions
diff --git a/tests/test_intl.py b/tests/test_intl.py
index 904fd7c5c..5fb3cea24 100644
--- a/tests/test_intl.py
+++ b/tests/test_intl.py
@@ -15,31 +15,22 @@ import os
import re
import pickle
from docutils import nodes
-from subprocess import Popen, PIPE
-from babel.messages import pofile
+from babel.messages import pofile, mofile
from six import string_types
import pytest
-from util import tempdir, rootdir, path, gen_with_app, SkipTest, \
- assert_re_search, assert_not_re_search, assert_in, assert_not_in, \
- assert_startswith, assert_node, etree_parse, strip_escseq, assert_equal
+from util import tempdir, rootdir, path, assert_re_search, \
+ assert_not_re_search, assert_startswith, assert_node, etree_parse
-root = tempdir / 'test-intl'
-
-
-def gen_with_intl_app(builder, confoverrides={}, *args, **kw):
- default_kw = {
- 'testroot': 'intl',
- 'confoverrides': {
- 'language': 'xx', 'locale_dirs': ['.'],
- 'gettext_compact': False,
- },
- }
- default_kw.update(kw)
- default_kw['confoverrides'].update(confoverrides)
- return gen_with_app(builder, *args, **default_kw)
+sphinx_intl = pytest.mark.sphinx(
+ testroot='intl',
+ confoverrides={
+ 'language': 'xx', 'locale_dirs': ['.'],
+ 'gettext_compact': False,
+ },
+)
def read_po(pathname):
@@ -47,32 +38,41 @@ def read_po(pathname):
return pofile.read_po(f)
-def setup_module():
- if not root.exists():
- (rootdir / 'roots' / 'test-intl').copytree(root)
- # Delete remnants left over after failed build
- # Compile all required catalogs into binary format (*.mo).
- for dirpath, dirs, files in os.walk(root):
- dirpath = path(dirpath)
- for f in [f for f in files if f.endswith('.po')]:
- po = dirpath / f
- mo = root / 'xx' / 'LC_MESSAGES' / (
- os.path.relpath(po[:-3], root) + '.mo')
- if not mo.parent.exists():
- mo.parent.makedirs()
- try:
- p = Popen(['msgfmt', po, '-o', mo],
- stdout=PIPE, stderr=PIPE)
- except OSError:
- raise SkipTest # most likely msgfmt was not found
- else:
- stdout, stderr = p.communicate()
- if p.returncode != 0:
- print(stdout)
- print(stderr)
- assert False, \
- 'msgfmt exited with return code %s' % p.returncode
- assert mo.isfile(), 'msgfmt failed'
+def write_mo(pathname, po):
+ with pathname.open('wb') as f:
+ return mofile.write_mo(f, po)
+
+
+@pytest.fixture
+def build_mo():
+ def builder(srcdir):
+ """
+ :param str srcdir: app.srcdir
+ """
+ srcdir = path(srcdir)
+ for dirpath, dirs, files in os.walk(srcdir):
+ dirpath = path(dirpath)
+ for f in [f for f in files if f.endswith('.po')]:
+ po = dirpath / f
+ mo = srcdir / 'xx' / 'LC_MESSAGES' / (
+ os.path.relpath(po[:-3], srcdir) + '.mo')
+ if not mo.parent.exists():
+ mo.parent.makedirs()
+
+ write_mo(mo, read_po(po))
+ return builder
+
+
+@pytest.fixture(autouse=True)
+def setup_intl(app_params, build_mo):
+ build_mo(app_params.kwargs['srcdir'])
+
+
+@pytest.fixture(autouse=True)
+def _info(app):
+ yield
+ print('# language:', app.config.language)
+ print('# locale_dirs:', app.config.locale_dirs)
def elem_gettexts(elem):
@@ -110,46 +110,72 @@ def assert_elem(elem, texts=None, refs=None, names=None):
def assert_count(expected_expr, result, count):
find_pair = (expected_expr, result)
- return assert_equal, len(re.findall(*find_pair)), count, find_pair
-
+ assert len(re.findall(*find_pair)) == count, find_pair
-@gen_with_intl_app('text', freshenv=True)
-def test_text_builder(app, status, warning):
- app.builder.build_all()
-
- # --- toctree
+@sphinx_intl
+@pytest.mark.sphinx('text')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_text_toctree(app):
+ app.build()
result = (app.outdir / 'contents.txt').text(encoding='utf-8')
- yield assert_startswith, result, u"CONTENTS\n********\n\nTABLE OF CONTENTS\n"
+ assert_startswith(result, u"CONTENTS\n********\n\nTABLE OF CONTENTS\n")
- # --- warnings in translation
+@sphinx_intl
+@pytest.mark.sphinx('text')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_text_emit_warnings(app, warning):
+ app.build()
+ # test warnings in translation
warnings = getwarning(warning)
warning_expr = u'.*/warnings.txt:4: ' \
u'WARNING: Inline literal start-string without end-string.\n'
- yield assert_re_search, warning_expr, warnings
+ assert_re_search(warning_expr, warnings)
+
+@sphinx_intl
+@pytest.mark.sphinx('text')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_text_warning_node(app):
+ app.build()
+ # test warnings in translation
result = (app.outdir / 'warnings.txt').text(encoding='utf-8')
expect = (u"I18N WITH REST WARNINGS"
u"\n***********************\n"
u"\nLINE OF >>``<<BROKEN LITERAL MARKUP.\n")
- yield assert_equal, result, expect
+ assert result == expect
- # --- simple translation; check title underlines
+@sphinx_intl
+@pytest.mark.sphinx('text')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_text_title_underline(app):
+ app.build()
+ # --- simple translation; check title underlines
result = (app.outdir / 'bom.txt').text(encoding='utf-8')
expect = (u"Datei mit UTF-8"
u"\n***************\n" # underline matches new translation
u"\nThis file has umlauts: äöü.\n")
- yield assert_equal, result, expect
+ assert result == expect
- # --- check translation in subdirs
+@sphinx_intl
+@pytest.mark.sphinx('text')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_text_subdirs(app):
+ app.build()
+ # --- check translation in subdirs
result = (app.outdir / 'subdir' / 'contents.txt').text(encoding='utf-8')
- yield assert_startswith, result, u"subdir contents\n***************\n"
+ assert_startswith(result, u"subdir contents\n***************\n")
- # --- check warnings for inconsistency in number of references
+@sphinx_intl
+@pytest.mark.sphinx('text')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_text_inconsistency_warnings(app, warning):
+ app.build()
+ # --- check warnings for inconsistency in number of references
result = (app.outdir / 'refs_inconsistency.txt').text(encoding='utf-8')
expect = (u"I18N WITH REFS INCONSISTENCY"
u"\n****************************\n"
@@ -159,7 +185,7 @@ def test_text_builder(app, status, warning):
u"\n[1] THIS IS A AUTO NUMBERED FOOTNOTE.\n"
u"\n[ref2] THIS IS A NAMED FOOTNOTE.\n"
u"\n[100] THIS IS A NUMBERED FOOTNOTE.\n")
- yield assert_equal, result, expect
+ assert result == expect
warnings = getwarning(warning)
warning_fmt = u'.*/refs_inconsistency.txt:\\d+: ' \
@@ -168,10 +194,15 @@ def test_text_builder(app, status, warning):
warning_fmt % 'footnote references' +
warning_fmt % 'references' +
warning_fmt % 'references')
- yield assert_re_search, expected_warning_expr, warnings
+ assert_re_search(expected_warning_expr, warnings)
- # --- check warning for literal block
+@sphinx_intl
+@pytest.mark.sphinx('text')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_text_literalblock_warnings(app, warning):
+ app.build()
+ # --- check warning for literal block
result = (app.outdir / 'literalblock.txt').text(encoding='utf-8')
expect = (u"I18N WITH LITERAL BLOCK"
u"\n***********************\n"
@@ -180,15 +211,20 @@ def test_text_builder(app, status, warning):
u"\n literal block\n"
u"\nMISSING LITERAL BLOCK:\n"
u"\n<SYSTEM MESSAGE:")
- yield assert_startswith, result, expect
+ assert_startswith(result, expect)
warnings = getwarning(warning)
expected_warning_expr = u'.*/literalblock.txt:\\d+: ' \
u'WARNING: Literal block expected; none found.'
- yield assert_re_search, expected_warning_expr, warnings
+ assert_re_search(expected_warning_expr, warnings)
- # --- definition terms: regression test for #975, #2198, #2205
+@sphinx_intl
+@pytest.mark.sphinx('text')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_text_definition_terms(app):
+ app.build()
+ # --- definition terms: regression test for #975, #2198, #2205
result = (app.outdir / 'definition_terms.txt').text(encoding='utf-8')
expect = (u"I18N WITH DEFINITION TERMS"
u"\n**************************\n"
@@ -201,10 +237,15 @@ def test_text_builder(app, status, warning):
u"\nSOME TERM WITH : CLASSIFIER[]"
u"\n THE CORRESPONDING DEFINITION\n"
)
- yield assert_equal, result, expect
+ assert result == expect
- # --- glossary terms: regression test for #1090
+@sphinx_intl
+@pytest.mark.sphinx('text')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_text_glossary_term(app, warning):
+ app.build()
+ # --- glossary terms: regression test for #1090
result = (app.outdir / 'glossary_terms.txt').text(encoding='utf-8')
expect = (u"I18N WITH GLOSSARY TERMS"
u"\n************************\n"
@@ -213,26 +254,36 @@ def test_text_builder(app, status, warning):
u"\nSOME OTHER NEW TERM"
u"\n THE CORRESPONDING GLOSSARY #2\n"
u"\nLINK TO *SOME NEW TERM*.\n")
- yield assert_equal, result, expect
+ assert result == expect
warnings = getwarning(warning)
- yield assert_not_in, 'term not in glossary', warnings
+ assert 'term not in glossary' not in warnings
- # --- glossary term inconsistencies: regression test for #1090
+@sphinx_intl
+@pytest.mark.sphinx('text')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_text_glossary_term_inconsistencies(app, warning):
+ app.build()
+ # --- glossary term inconsistencies: regression test for #1090
result = (app.outdir / 'glossary_terms_inconsistency.txt').text(encoding='utf-8')
expect = (u"I18N WITH GLOSSARY TERMS INCONSISTENCY"
u"\n**************************************\n"
u"\n1. LINK TO *SOME NEW TERM*.\n")
- yield assert_equal, result, expect
+ assert result == expect
warnings = getwarning(warning)
expected_warning_expr = (
u'.*/glossary_terms_inconsistency.txt:\\d+: '
u'WARNING: inconsistent term references in translated message\n')
- yield assert_re_search, expected_warning_expr, warnings
+ assert_re_search(expected_warning_expr, warnings)
- # --- seealso
+@sphinx_intl
+@pytest.mark.sphinx('text')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_text_seealso(app):
+ app.build()
+ # --- seealso
result = (app.outdir / 'seealso.txt').text(encoding='utf-8')
expect = (u"I18N WITH SEEALSO"
u"\n*****************\n"
@@ -240,10 +291,15 @@ def test_text_builder(app, status, warning):
u"\nSee also: LONG TEXT 1\n"
u"\nSee also: SHORT TEXT 2\n"
u"\n LONG TEXT 2\n")
- yield assert_equal, result, expect
+ assert result == expect
- # --- figure captions: regression test for #940
+@sphinx_intl
+@pytest.mark.sphinx('text')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_text_figure_captions(app):
+ app.build()
+ # --- figure captions: regression test for #940
result = (app.outdir / 'figure.txt').text(encoding='utf-8')
expect = (u"I18N WITH FIGURE CAPTION"
u"\n************************\n"
@@ -278,10 +334,15 @@ def test_text_builder(app, status, warning):
u"\n"
u" [image: img under note][image]\n"
)
- yield assert_equal, result, expect
+ assert result == expect
- # --- rubric: regression test for pull request #190
+@sphinx_intl
+@pytest.mark.sphinx('text')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_text_rubric(app):
+ app.build()
+ # --- rubric: regression test for pull request #190
result = (app.outdir / 'rubric.txt').text(encoding='utf-8')
expect = (u"I18N WITH RUBRIC"
u"\n****************\n"
@@ -291,10 +352,15 @@ def test_text_builder(app, status, warning):
u"\n===================\n"
u"\nBLOCK\n"
u"\n -[ RUBRIC TITLE ]-\n")
- yield assert_equal, result, expect
+ assert result == expect
- # --- docfields
+@sphinx_intl
+@pytest.mark.sphinx('text')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_text_docfields(app):
+ app.build()
+ # --- docfields
result = (app.outdir / 'docfields.txt').text(encoding='utf-8')
expect = (u"I18N WITH DOCFIELDS"
u"\n*******************\n"
@@ -315,103 +381,178 @@ def test_text_builder(app, status, warning):
u"\nclass Cls5\n"
u"\n Returns:"
u'\n A NEW "Cls3" INSTANCE\n')
- yield assert_equal, result, expect
+ assert result == expect
+
+@sphinx_intl
+@pytest.mark.sphinx('text')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_text_admonitions(app):
+ app.build()
# --- admonitions
# #1206: gettext did not translate admonition directive's title
# seealso: http://docutils.sourceforge.net/docs/ref/rst/directives.html#admonitions
-
result = (app.outdir / 'admonitions.txt').text(encoding='utf-8')
directives = (
"attention", "caution", "danger", "error", "hint",
"important", "note", "tip", "warning", "admonition")
for d in directives:
- yield assert_in, d.upper() + " TITLE", result
- yield assert_in, d.upper() + " BODY", result
+ assert d.upper() + " TITLE" in result
+ assert d.upper() + " BODY" in result
-@gen_with_intl_app('gettext', freshenv=True)
-def test_gettext_builder(app, status, warning):
- app.builder.build_all()
-
+@sphinx_intl
+@pytest.mark.sphinx('gettext')
+@pytest.mark.test_params(shared_result='test_intl_gettext')
+def test_gettext_toctree(app):
+ app.build()
# --- toctree
expect = read_po(app.srcdir / 'contents.po')
actual = read_po(app.outdir / 'contents.pot')
for expect_msg in [m for m in expect if m.id]:
- yield assert_in, expect_msg.id, [m.id for m in actual if m.id]
+ assert expect_msg.id in [m.id for m in actual if m.id]
+
+@sphinx_intl
+@pytest.mark.sphinx('gettext')
+@pytest.mark.test_params(shared_result='test_intl_gettext')
+def test_gettext_definition_terms(app):
+ app.build()
# --- definition terms: regression test for #2198, #2205
expect = read_po(app.srcdir / 'definition_terms.po')
actual = read_po(app.outdir / 'definition_terms.pot')
for expect_msg in [m for m in expect if m.id]:
- yield assert_in, expect_msg.id, [m.id for m in actual if m.id]
+ assert expect_msg.id in [m.id for m in actual if m.id]
+
+@sphinx_intl
+@pytest.mark.sphinx('gettext')
+@pytest.mark.test_params(shared_result='test_intl_gettext')
+def test_gettext_glossary_terms(app, warning):
+ app.build()
# --- glossary terms: regression test for #1090
expect = read_po(app.srcdir / 'glossary_terms.po')
actual = read_po(app.outdir / 'glossary_terms.pot')
for expect_msg in [m for m in expect if m.id]:
- yield assert_in, expect_msg.id, [m.id for m in actual if m.id]
+ assert expect_msg.id in [m.id for m in actual if m.id]
warnings = warning.getvalue().replace(os.sep, '/')
- yield assert_not_in, 'term not in glossary', warnings
+ assert 'term not in glossary' not in warnings
+
+@sphinx_intl
+@pytest.mark.sphinx('gettext')
+@pytest.mark.test_params(shared_result='test_intl_gettext')
+def test_gettext_glossary_term_inconsistencies(app):
+ app.build()
# --- glossary term inconsistencies: regression test for #1090
expect = read_po(app.srcdir / 'glossary_terms_inconsistency.po')
actual = read_po(app.outdir / 'glossary_terms_inconsistency.pot')
for expect_msg in [m for m in expect if m.id]:
- yield assert_in, expect_msg.id, [m.id for m in actual if m.id]
+ assert expect_msg.id in [m.id for m in actual if m.id]
+
+@sphinx_intl
+@pytest.mark.sphinx('gettext')
+@pytest.mark.test_params(shared_result='test_intl_gettext')
+def test_gettext_buildr_ignores_only_directive(app):
+ app.build()
# --- gettext builder always ignores ``only`` directive
expect = read_po(app.srcdir / 'only.po')
actual = read_po(app.outdir / 'only.pot')
for expect_msg in [m for m in expect if m.id]:
- yield assert_in, expect_msg.id, [m.id for m in actual if m.id]
+ assert expect_msg.id in [m.id for m in actual if m.id]
- # --- don't rebuild by .mo mtime
- app.builder.build_update()
- updated = app.env.update(app.config, app.srcdir, app.doctreedir, app)
- yield assert_equal, len(updated), 0
-
- (app.srcdir / 'xx' / 'LC_MESSAGES' / 'bom.mo').utime(None)
- updated = app.env.update(app.config, app.srcdir, app.doctreedir, app)
- yield assert_equal, len(updated), 0
-
-
-@gen_with_intl_app('html', freshenv=True)
-def test_html_builder(app, status, warning):
- app.builder.build_all()
+@sphinx_intl
+def test_gettext_dont_rebuild_mo(make_app, app_params, build_mo):
+ # --- don't rebuild by .mo mtime
+ def get_number_of_update_targets(app_):
+ updated = app_.env.update(app_.config, app_.srcdir, app_.doctreedir, app_)
+ return len(updated)
+
+ # setup new directory
+ args, kwargs = app_params
+ kwargs['srcdir'] = 'test_gettext_dont_rebuild_mo'
+
+ # phase1: build document with non-gettext builder and generate mo file in srcdir
+ app0 = make_app('dummy', *args, **kwargs)
+ build_mo(app0.srcdir)
+ app0.build()
+ assert (app0.srcdir / 'bom.mo')
+ # Since it is after the build, the number of documents to be updated is 0
+ assert get_number_of_update_targets(app0) == 0
+ # When rewriting the timestamp of mo file, the number of documents to be
+ # updated will be changed.
+ (app0.srcdir / 'xx' / 'LC_MESSAGES' / 'bom.mo').utime(None)
+ assert get_number_of_update_targets(app0) == 1
+
+ # Because doctree for gettext builder can not be shared with other builders,
+ # erase doctreedir before gettext build.
+ app0.doctreedir.rmtree()
+
+ # phase2: build document with gettext builder.
+ # The mo file in the srcdir directory is retained.
+ app = make_app('gettext', *args, **kwargs)
+ app.build()
+ # Since it is after the build, the number of documents to be updated is 0
+ assert get_number_of_update_targets(app) == 0
+ # Even if the timestamp of the mo file is updated, the number of documents
+ # to be updated is 0. gettext builder does not rebuild because of mo update.
+ (app0.srcdir / 'xx' / 'LC_MESSAGES' / 'bom.mo').utime(None)
+ assert get_number_of_update_targets(app) == 0
+
+
+@sphinx_intl
+@pytest.mark.sphinx('html')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_html_meta(app):
+ app.build()
# --- test for meta
-
result = (app.outdir / 'contents.html').text(encoding='utf-8')
expected_expr = '<meta content="TESTDATA FOR I18N" name="description" />'
- yield assert_in, expected_expr, result
+ assert expected_expr in result
expected_expr = '<meta content="I18N, SPHINX, MARKUP" name="keywords" />'
- yield assert_in, expected_expr, result
+ assert expected_expr in result
- # --- test for #955 cant-build-html-with-footnotes-when-using
+@sphinx_intl
+@pytest.mark.sphinx('html')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_html_footnotes(app):
+ app.build()
+ # --- test for #955 cant-build-html-with-footnotes-when-using
# expect no error by build
(app.outdir / 'footnote.html').text(encoding='utf-8')
- # --- links to undefined reference
+@sphinx_intl
+@pytest.mark.sphinx('html')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_html_undefined_refs(app):
+ app.build()
+ # --- links to undefined reference
result = (app.outdir / 'refs_inconsistency.html').text(encoding='utf-8')
expected_expr = ('<a class="reference external" '
'href="http://www.example.com">reference</a>')
- yield assert_equal, len(re.findall(expected_expr, result)), 2
+ assert len(re.findall(expected_expr, result)) == 2
expected_expr = ('<a class="reference internal" '
'href="#reference">reference</a>')
- yield assert_equal, len(re.findall(expected_expr, result)), 0
+ assert len(re.findall(expected_expr, result)) == 0
expected_expr = ('<a class="reference internal" '
'href="#i18n-with-refs-inconsistency">I18N WITH '
'REFS INCONSISTENCY</a>')
- yield assert_equal, len(re.findall(expected_expr, result)), 1
+ assert len(re.findall(expected_expr, result)) == 1
- # --- index entries: regression test for #976
+@sphinx_intl
+@pytest.mark.sphinx('html')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_html_index_entries(app):
+ app.build()
+ # --- index entries: regression test for #976
result = (app.outdir / 'genindex.html').text(encoding='utf-8')
def wrap(tag, keyword):
@@ -440,10 +581,15 @@ def test_html_builder(app, status, warning):
wrap('a', 'BUILTIN'),
]
for expr in expected_exprs:
- yield assert_re_search, expr, result, re.M
+ assert_re_search(expr, result, re.M)
- # --- versionchanges
+@sphinx_intl
+@pytest.mark.sphinx('html')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_html_versionchanges(app):
+ app.build()
+ # --- versionchanges
result = (app.outdir / 'versionchange.html').text(encoding='utf-8')
def get_content(result, name):
@@ -459,88 +605,108 @@ def test_html_builder(app, status, warning):
u"""THIS IS THE <em>FIRST</em> PARAGRAPH OF DEPRECATED.</p>\n"""
u"""<p>THIS IS THE <em>SECOND</em> PARAGRAPH OF DEPRECATED.</p>\n""")
matched_content = get_content(result, "deprecated")
- yield assert_equal, expect1, matched_content
+ assert expect1 == matched_content
expect2 = (
u"""<p><span class="versionmodified">New in version 1.0: </span>"""
u"""THIS IS THE <em>FIRST</em> PARAGRAPH OF VERSIONADDED.</p>\n""")
matched_content = get_content(result, "versionadded")
- yield assert_equal, expect2, matched_content
+ assert expect2 == matched_content
expect3 = (
u"""<p><span class="versionmodified">Changed in version 1.0: </span>"""
u"""THIS IS THE <em>FIRST</em> PARAGRAPH OF VERSIONCHANGED.</p>\n""")
matched_content = get_content(result, "versionchanged")
- yield assert_equal, expect3, matched_content
+ assert expect3 == matched_content
- # --- docfields
+@sphinx_intl
+@pytest.mark.sphinx('html')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_html_docfields(app):
+ app.build()
+ # --- docfields
# expect no error by build
(app.outdir / 'docfields.html').text(encoding='utf-8')
- # --- gettext template
+@sphinx_intl
+@pytest.mark.sphinx('html')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_html_template(app):
+ app.build()
+ # --- gettext template
result = (app.outdir / 'index.html').text(encoding='utf-8')
- yield assert_in, "WELCOME", result
- yield assert_in, "SPHINX 2013.120", result
+ assert "WELCOME" in result
+ assert "SPHINX 2013.120" in result
- # --- rebuild by .mo mtime
+@sphinx_intl
+@pytest.mark.sphinx('html')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_html_rebuild_mo(app):
+ app.build()
+ # --- rebuild by .mo mtime
app.builder.build_update()
updated = app.env.update(app.config, app.srcdir, app.doctreedir, app)
- yield assert_equal, len(updated), 0
+ assert len(updated) == 0
(app.srcdir / 'xx' / 'LC_MESSAGES' / 'bom.mo').utime(None)
updated = app.env.update(app.config, app.srcdir, app.doctreedir, app)
- yield assert_equal, len(updated), 1
-
+ assert len(updated) == 1
-@gen_with_intl_app('xml', freshenv=True)
-def test_xml_builder(app, status, warning):
- app.builder.build_all()
+@sphinx_intl
+@pytest.mark.sphinx('xml')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_xml_footnotes(app, warning):
+ app.build()
# --- footnotes: regression test for fix #955, #1176
-
et = etree_parse(app.outdir / 'footnote.xml')
secs = et.findall('section')
para0 = secs[0].findall('paragraph')
- yield (assert_elem,
- para0[0],
- ['I18N WITH FOOTNOTE', 'INCLUDE THIS CONTENTS',
- '2', '[ref]', '1', '100', '.'],
- ['i18n-with-footnote', 'ref'])
+ assert_elem(
+ para0[0],
+ ['I18N WITH FOOTNOTE', 'INCLUDE THIS CONTENTS',
+ '2', '[ref]', '1', '100', '.'],
+ ['i18n-with-footnote', 'ref'])
footnote0 = secs[0].findall('footnote')
- yield (assert_elem,
- footnote0[0],
- ['1', 'THIS IS A AUTO NUMBERED FOOTNOTE.'],
- None,
- ['1'])
- yield (assert_elem,
- footnote0[1],
- ['100', 'THIS IS A NUMBERED FOOTNOTE.'],
- None,
- ['100'])
- yield (assert_elem,
- footnote0[2],
- ['2', 'THIS IS A AUTO NUMBERED NAMED FOOTNOTE.'],
- None,
- ['named'])
+ assert_elem(
+ footnote0[0],
+ ['1', 'THIS IS A AUTO NUMBERED FOOTNOTE.'],
+ None,
+ ['1'])
+ assert_elem(
+ footnote0[1],
+ ['100', 'THIS IS A NUMBERED FOOTNOTE.'],
+ None,
+ ['100'])
+ assert_elem(
+ footnote0[2],
+ ['2', 'THIS IS A AUTO NUMBERED NAMED FOOTNOTE.'],
+ None,
+ ['named'])
citation0 = secs[0].findall('citation')
- yield (assert_elem,
- citation0[0],
- ['ref', 'THIS IS A NAMED FOOTNOTE.'],
- None,
- ['ref'])
+ assert_elem(
+ citation0[0],
+ ['ref', 'THIS IS A NAMED FOOTNOTE.'],
+ None,
+ ['ref'])
warnings = getwarning(warning)
warning_expr = u'.*/footnote.xml:\\d*: SEVERE: Duplicate ID: ".*".\n'
- yield assert_not_re_search, warning_expr, warnings
+ assert_not_re_search(warning_expr, warnings)
- # --- footnote backlinks: i18n test for #1058
+@sphinx_intl
+@pytest.mark.sphinx('xml')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_xml_footnote_backlinks(app):
+ app.build()
+ # --- footnote backlinks: i18n test for #1058
et = etree_parse(app.outdir / 'footnote.xml')
secs = et.findall('section')
@@ -553,207 +719,234 @@ def test_xml_builder(app, status, warning):
for footnote in footnote0:
ids = footnote.attrib.get('ids')
backrefs = footnote.attrib.get('backrefs')
- yield assert_equal, refid2id[ids], backrefs
+ assert refid2id[ids] == backrefs
- # --- refs in the Python domain
+@sphinx_intl
+@pytest.mark.sphinx('xml')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_xml_refs_in_python_domain(app):
+ app.build()
+ # --- refs in the Python domain
et = etree_parse(app.outdir / 'refs_python_domain.xml')
secs = et.findall('section')
# regression test for fix #1363
para0 = secs[0].findall('paragraph')
- yield (assert_elem,
- para0[0],
- ['SEE THIS DECORATOR:', 'sensitive_variables()', '.'],
- ['sensitive.sensitive_variables'])
+ assert_elem(
+ para0[0],
+ ['SEE THIS DECORATOR:', 'sensitive_variables()', '.'],
+ ['sensitive.sensitive_variables'])
- # --- keep external links: regression test for #1044
+@sphinx_intl
+@pytest.mark.sphinx('xml')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_xml_keep_external_links(app):
+ app.build()
+ # --- keep external links: regression test for #1044
et = etree_parse(app.outdir / 'external_links.xml')
secs = et.findall('section')
para0 = secs[0].findall('paragraph')
# external link check
- yield (assert_elem,
- para0[0],
- ['EXTERNAL LINK TO', 'Python', '.'],
- ['http://python.org/index.html'])
+ assert_elem(
+ para0[0],
+ ['EXTERNAL LINK TO', 'Python', '.'],
+ ['http://python.org/index.html'])
# internal link check
- yield (assert_elem,
- para0[1],
- ['EXTERNAL LINKS', 'IS INTERNAL LINK.'],
- ['i18n-with-external-links'])
+ assert_elem(
+ para0[1],
+ ['EXTERNAL LINKS', 'IS INTERNAL LINK.'],
+ ['i18n-with-external-links'])
# inline link check
- yield (assert_elem,
- para0[2],
- ['INLINE LINK BY', 'THE SPHINX SITE', '.'],
- ['http://sphinx-doc.org'])
+ assert_elem(
+ para0[2],
+ ['INLINE LINK BY', 'THE SPHINX SITE', '.'],
+ ['http://sphinx-doc.org'])
# unnamed link check
- yield (assert_elem,
- para0[3],
- ['UNNAMED', 'LINK', '.'],
- ['http://google.com'])
+ assert_elem(
+ para0[3],
+ ['UNNAMED', 'LINK', '.'],
+ ['http://google.com'])
# link target swapped translation
para1 = secs[1].findall('paragraph')
- yield (assert_elem,
- para1[0],
- ['LINK TO', 'external2', 'AND', 'external1', '.'],
- ['http://example.com/external2',
- 'http://example.com/external1'])
- yield (assert_elem,
+ assert_elem(
+ para1[0],
+ ['LINK TO', 'external2', 'AND', 'external1', '.'],
+ ['http://example.com/external2',
+ 'http://example.com/external1'])
+ assert_elem(
para1[1],
['LINK TO', 'THE PYTHON SITE', 'AND', 'THE SPHINX SITE', '.'],
['http://python.org', 'http://sphinx-doc.org'])
# multiple references in the same line
para2 = secs[2].findall('paragraph')
- yield (assert_elem,
- para2[0],
- ['LINK TO', 'EXTERNAL LINKS', ',', 'Python', ',',
- 'THE SPHINX SITE', ',', 'UNNAMED', 'AND',
- 'THE PYTHON SITE', '.'],
- ['i18n-with-external-links', 'http://python.org/index.html',
- 'http://sphinx-doc.org', 'http://google.com',
- 'http://python.org'])
-
+ assert_elem(
+ para2[0],
+ ['LINK TO', 'EXTERNAL LINKS', ',', 'Python', ',',
+ 'THE SPHINX SITE', ',', 'UNNAMED', 'AND',
+ 'THE PYTHON SITE', '.'],
+ ['i18n-with-external-links', 'http://python.org/index.html',
+ 'http://sphinx-doc.org', 'http://google.com',
+ 'http://python.org'])
+
+
+@sphinx_intl
+@pytest.mark.sphinx('xml')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_xml_role_xref(app):
+ app.build()
# --- role xref: regression test for #1090, #1193
-
et = etree_parse(app.outdir / 'role_xref.xml')
sec1, sec2 = et.findall('section')
para1, = sec1.findall('paragraph')
- yield (assert_elem,
- para1,
- ['LINK TO', "I18N ROCK'N ROLE XREF", ',', 'CONTENTS', ',',
- 'SOME NEW TERM', '.'],
- ['i18n-role-xref', 'contents',
- 'glossary_terms#term-some-term'])
+ assert_elem(
+ para1,
+ ['LINK TO', "I18N ROCK'N ROLE XREF", ',', 'CONTENTS', ',',
+ 'SOME NEW TERM', '.'],
+ ['i18n-role-xref', 'contents',
+ 'glossary_terms#term-some-term'])
para2 = sec2.findall('paragraph')
- yield (assert_elem,
- para2[0],
- ['LINK TO', 'SOME OTHER NEW TERM', 'AND', 'SOME NEW TERM', '.'],
- ['glossary_terms#term-some-other-term',
- 'glossary_terms#term-some-term'])
- yield(assert_elem,
- para2[1],
- ['LINK TO', 'SAME TYPE LINKS', 'AND',
- "I18N ROCK'N ROLE XREF", '.'],
- ['same-type-links', 'i18n-role-xref'])
- yield (assert_elem,
- para2[2],
- ['LINK TO', 'I18N WITH GLOSSARY TERMS', 'AND', 'CONTENTS', '.'],
- ['glossary_terms', 'contents'])
- yield (assert_elem,
- para2[3],
- ['LINK TO', '--module', 'AND', '-m', '.'],
- ['cmdoption-module', 'cmdoption-m'])
- yield (assert_elem,
- para2[4],
- ['LINK TO', 'env2', 'AND', 'env1', '.'],
- ['envvar-env2', 'envvar-env1'])
- yield (assert_elem,
- para2[5],
- ['LINK TO', 'token2', 'AND', 'token1', '.'],
- []) # TODO: how do I link token role to productionlist?
- yield (assert_elem,
- para2[6],
- ['LINK TO', 'same-type-links', 'AND', "i18n-role-xref", '.'],
- ['same-type-links', 'i18n-role-xref'])
-
+ assert_elem(
+ para2[0],
+ ['LINK TO', 'SOME OTHER NEW TERM', 'AND', 'SOME NEW TERM', '.'],
+ ['glossary_terms#term-some-other-term',
+ 'glossary_terms#term-some-term'])
+ assert_elem(
+ para2[1],
+ ['LINK TO', 'SAME TYPE LINKS', 'AND',
+ "I18N ROCK'N ROLE XREF", '.'],
+ ['same-type-links', 'i18n-role-xref'])
+ assert_elem(
+ para2[2],
+ ['LINK TO', 'I18N WITH GLOSSARY TERMS', 'AND', 'CONTENTS', '.'],
+ ['glossary_terms', 'contents'])
+ assert_elem(
+ para2[3],
+ ['LINK TO', '--module', 'AND', '-m', '.'],
+ ['cmdoption-module', 'cmdoption-m'])
+ assert_elem(
+ para2[4],
+ ['LINK TO', 'env2', 'AND', 'env1', '.'],
+ ['envvar-env2', 'envvar-env1'])
+ assert_elem(
+ para2[5],
+ ['LINK TO', 'token2', 'AND', 'token1', '.'],
+ []) # TODO: how do I link token role to productionlist?
+ assert_elem(
+ para2[6],
+ ['LINK TO', 'same-type-links', 'AND', "i18n-role-xref", '.'],
+ ['same-type-links', 'i18n-role-xref'])
+
+
+@sphinx_intl
+@pytest.mark.sphinx('xml')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_xml_warnings(app, warning):
+ app.build()
# warnings
warnings = getwarning(warning)
- yield assert_not_in, 'term not in glossary', warnings
- yield assert_not_in, 'undefined label', warnings
- yield assert_not_in, 'unknown document', warnings
+ assert 'term not in glossary' not in warnings
+ assert 'undefined label' not in warnings
+ assert 'unknown document' not in warnings
- # --- label targets: regression test for #1193, #1265
+@sphinx_intl
+@pytest.mark.sphinx('xml')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_xml_label_targets(app):
+ app.build()
+ # --- label targets: regression test for #1193, #1265
et = etree_parse(app.outdir / 'label_target.xml')
secs = et.findall('section')
para0 = secs[0].findall('paragraph')
- yield (assert_elem,
- para0[0],
- ['X SECTION AND LABEL', 'POINT TO', 'implicit-target', 'AND',
- 'X SECTION AND LABEL', 'POINT TO', 'section-and-label', '.'],
- ['implicit-target', 'section-and-label'])
+ assert_elem(
+ para0[0],
+ ['X SECTION AND LABEL', 'POINT TO', 'implicit-target', 'AND',
+ 'X SECTION AND LABEL', 'POINT TO', 'section-and-label', '.'],
+ ['implicit-target', 'section-and-label'])
para1 = secs[1].findall('paragraph')
- yield (assert_elem,
- para1[0],
- ['X EXPLICIT-TARGET', 'POINT TO', 'explicit-target', 'AND',
- 'X EXPLICIT-TARGET', 'POINT TO DUPLICATED ID LIKE', 'id1',
- '.'],
- ['explicit-target', 'id1'])
+ assert_elem(
+ para1[0],
+ ['X EXPLICIT-TARGET', 'POINT TO', 'explicit-target', 'AND',
+ 'X EXPLICIT-TARGET', 'POINT TO DUPLICATED ID LIKE', 'id1',
+ '.'],
+ ['explicit-target', 'id1'])
para2 = secs[2].findall('paragraph')
- yield (assert_elem,
- para2[0],
- ['X IMPLICIT SECTION NAME', 'POINT TO',
- 'implicit-section-name', '.'],
- ['implicit-section-name'])
+ assert_elem(
+ para2[0],
+ ['X IMPLICIT SECTION NAME', 'POINT TO',
+ 'implicit-section-name', '.'],
+ ['implicit-section-name'])
sec2 = secs[2].findall('section')
para2_0 = sec2[0].findall('paragraph')
- yield (assert_elem,
- para2_0[0],
- ['`X DUPLICATED SUB SECTION`_', 'IS BROKEN LINK.'],
- [])
+ assert_elem(
+ para2_0[0],
+ ['`X DUPLICATED SUB SECTION`_', 'IS BROKEN LINK.'],
+ [])
para3 = secs[3].findall('paragraph')
- yield (assert_elem,
- para3[0],
- ['X', 'bridge label',
- 'IS NOT TRANSLATABLE BUT LINKED TO TRANSLATED ' +
- 'SECTION TITLE.'],
- ['label-bridged-target-section'])
- yield (assert_elem,
- para3[1],
- ['X', 'bridge label', 'POINT TO',
- 'LABEL BRIDGED TARGET SECTION', 'AND', 'bridge label2',
- 'POINT TO', 'SECTION AND LABEL', '. THE SECOND APPEARED',
- 'bridge label2', 'POINT TO CORRECT TARGET.'],
- ['label-bridged-target-section',
- 'section-and-label',
- 'section-and-label'])
-
-
-@gen_with_intl_app('html', freshenv=True)
-def test_additional_targets_should_not_be_translated(app, status, warning):
- app.builder.build_all()
-
+ assert_elem(
+ para3[0],
+ ['X', 'bridge label',
+ 'IS NOT TRANSLATABLE BUT LINKED TO TRANSLATED ' +
+ 'SECTION TITLE.'],
+ ['label-bridged-target-section'])
+ assert_elem(
+ para3[1],
+ ['X', 'bridge label', 'POINT TO',
+ 'LABEL BRIDGED TARGET SECTION', 'AND', 'bridge label2',
+ 'POINT TO', 'SECTION AND LABEL', '. THE SECOND APPEARED',
+ 'bridge label2', 'POINT TO CORRECT TARGET.'],
+ ['label-bridged-target-section',
+ 'section-and-label',
+ 'section-and-label'])
+
+
+@sphinx_intl
+@pytest.mark.sphinx('html')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_additional_targets_should_not_be_translated(app):
+ app.build()
# [literalblock.txt]
result = (app.outdir / 'literalblock.html').text(encoding='utf-8')
# title should be translated
expected_expr = 'CODE-BLOCKS'
- yield assert_count(expected_expr, result, 2)
+ assert_count(expected_expr, result, 2)
# ruby code block should not be translated but be highlighted
expected_expr = """<span class="s1">&#39;result&#39;</span>"""
- yield assert_count(expected_expr, result, 1)
+ assert_count(expected_expr, result, 1)
# C code block without lang should not be translated and *ruby* highlighted
expected_expr = """<span class="c1">#include &lt;stdlib.h&gt;</span>"""
- yield assert_count(expected_expr, result, 1)
+ assert_count(expected_expr, result, 1)
# C code block with lang should not be translated but be *C* highlighted
expected_expr = ("""<span class="cp">#include</span> """
"""<span class="cpf">&lt;stdio.h&gt;</span>""")
- yield assert_count(expected_expr, result, 1)
+ assert_count(expected_expr, result, 1)
# doctest block should not be translated but be highlighted
expected_expr = (
"""<span class="gp">&gt;&gt;&gt; </span>"""
"""<span class="kn">import</span> <span class="nn">sys</span> """
"""<span class="c1"># sys importing</span>""")
- yield assert_count(expected_expr, result, 1)
+ assert_count(expected_expr, result, 1)
# [raw.txt]
@@ -761,7 +954,7 @@ def test_additional_targets_should_not_be_translated(app, status, warning):
# raw block should not be translated
expected_expr = """<iframe src="http://sphinx-doc.org"></iframe></div>"""
- yield assert_count(expected_expr, result, 1)
+ assert_count(expected_expr, result, 1)
# [figure.txt]
@@ -769,52 +962,57 @@ def test_additional_targets_should_not_be_translated(app, status, warning):
# alt and src for image block should not be translated
expected_expr = """<img alt="i18n" src="_images/i18n.png" />"""
- yield assert_count(expected_expr, result, 1)
+ assert_count(expected_expr, result, 1)
# alt and src for figure block should not be translated
expected_expr = """<img alt="img" src="_images/img.png" />"""
- yield assert_count(expected_expr, result, 1)
-
-
-@gen_with_intl_app('html', freshenv=True,
- confoverrides={
- 'gettext_additional_targets': [
- 'index',
- 'literal-block',
- 'doctest-block',
- 'raw',
- 'image',
- ],
- })
-def test_additional_targets_should_be_translated(app, status, warning):
- app.builder.build_all()
-
+ assert_count(expected_expr, result, 1)
+
+
+@sphinx_intl
+@pytest.mark.sphinx(
+ 'html',
+ srcdir='test_additional_targets_should_be_translated',
+ confoverrides={
+ 'language': 'xx', 'locale_dirs': ['.'],
+ 'gettext_compact': False,
+ 'gettext_additional_targets': [
+ 'index',
+ 'literal-block',
+ 'doctest-block',
+ 'raw',
+ 'image',
+ ],
+ }
+)
+def test_additional_targets_should_be_translated(app):
+ app.build()
# [literalblock.txt]
result = (app.outdir / 'literalblock.html').text(encoding='utf-8')
# title should be translated
expected_expr = 'CODE-BLOCKS'
- yield assert_count(expected_expr, result, 2)
+ assert_count(expected_expr, result, 2)
# ruby code block should be translated and be highlighted
expected_expr = """<span class="s1">&#39;RESULT&#39;</span>"""
- yield assert_count(expected_expr, result, 1)
+ assert_count(expected_expr, result, 1)
# C code block without lang should be translated and *ruby* highlighted
expected_expr = """<span class="c1">#include &lt;STDLIB.H&gt;</span>"""
- yield assert_count(expected_expr, result, 1)
+ assert_count(expected_expr, result, 1)
# C code block with lang should be translated and be *C* highlighted
expected_expr = ("""<span class="cp">#include</span> """
"""<span class="cpf">&lt;STDIO.H&gt;</span>""")
- yield assert_count(expected_expr, result, 1)
+ assert_count(expected_expr, result, 1)
# doctest block should not be translated but be highlighted
expected_expr = (
"""<span class="gp">&gt;&gt;&gt; </span>"""
"""<span class="kn">import</span> <span class="nn">sys</span> """
"""<span class="c1"># SYS IMPORTING</span>""")
- yield assert_count(expected_expr, result, 1)
+ assert_count(expected_expr, result, 1)
# [raw.txt]
@@ -822,7 +1020,7 @@ def test_additional_targets_should_be_translated(app, status, warning):
# raw block should be translated
expected_expr = """<iframe src="HTTP://SPHINX-DOC.ORG"></iframe></div>"""
- yield assert_count(expected_expr, result, 1)
+ assert_count(expected_expr, result, 1)
# [figure.txt]
@@ -830,26 +1028,31 @@ def test_additional_targets_should_be_translated(app, status, warning):
# alt and src for image block should be translated
expected_expr = """<img alt="I18N -&gt; IMG" src="_images/img.png" />"""
- yield assert_count(expected_expr, result, 1)
+ assert_count(expected_expr, result, 1)
# alt and src for figure block should be translated
expected_expr = """<img alt="IMG -&gt; I18N" src="_images/i18n.png" />"""
- yield assert_count(expected_expr, result, 1)
+ assert_count(expected_expr, result, 1)
-@gen_with_intl_app('text', freshenv=True)
-def test_references(app, status, warning):
+@sphinx_intl
+@pytest.mark.sphinx('text')
+@pytest.mark.test_params(shared_result='test_intl_basic')
+def test_text_references(app, warning):
app.builder.build_specific([app.srcdir / 'refs.txt'])
warnings = warning.getvalue().replace(os.sep, '/')
warning_expr = u'refs.txt:\\d+: ERROR: Unknown target name:'
- yield assert_count(warning_expr, warnings, 0)
-
+ assert_count(warning_expr, warnings, 0)
-@pytest.mark.sphinx('dummy', testroot='image-glob', confoverrides={'language': 'xx'})
-def test_image_glob_intl(app, status, warning):
- app.builder.build_all()
+@pytest.mark.sphinx(
+ 'dummy', testroot='image-glob',
+ srcdir='test_intl_image_glob',
+ confoverrides={'language': 'xx'}
+)
+def test_image_glob_intl(app):
+ app.build()
# index.rst
doctree = pickle.loads((app.doctreedir / 'index.doctree').bytes())
@@ -887,12 +1090,16 @@ def test_image_glob_intl(app, status, warning):
'image/svg+xml': 'subdir/svgimg.xx.svg'})
-@pytest.mark.sphinx('dummy', testroot='image-glob',
- confoverrides={'language': 'xx',
- 'figure_language_filename': u'{root}{ext}.{language}'})
-def test_image_glob_intl_using_figure_language_filename(app, status, warning):
- app.builder.build_all()
-
+@pytest.mark.sphinx(
+ 'dummy', testroot='image-glob',
+ srcdir='test_intl_image_glob',
+ confoverrides={
+ 'language': 'xx',
+ 'figure_language_filename': u'{root}{ext}.{language}',
+ }
+)
+def test_image_glob_intl_using_figure_language_filename(app):
+ app.build()
# index.rst
doctree = pickle.loads((app.doctreedir / 'index.doctree').bytes())