diff options
Diffstat (limited to 'tests/test_intl.py')
-rw-r--r-- | tests/test_intl.py | 859 |
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">'result'</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 <stdlib.h></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"><stdio.h></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">>>> </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">'RESULT'</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 <STDLIB.H></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"><STDIO.H></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">>>> </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 -> 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 -> 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()) |