From 5de84c9242643f786eff03726286578726d7d390 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 5 Jun 2024 18:20:59 +0200 Subject: Merging upstream version 7.3.7. Signed-off-by: Daniel Baumann --- tests/test_extensions/test_ext_math.py | 389 +++++++++++++++++++++++++++++++++ 1 file changed, 389 insertions(+) create mode 100644 tests/test_extensions/test_ext_math.py (limited to 'tests/test_extensions/test_ext_math.py') diff --git a/tests/test_extensions/test_ext_math.py b/tests/test_extensions/test_ext_math.py new file mode 100644 index 0000000..b673f83 --- /dev/null +++ b/tests/test_extensions/test_ext_math.py @@ -0,0 +1,389 @@ +"""Test math extensions.""" + +import re +import shutil +import subprocess +import warnings + +import pytest +from docutils import nodes + +from sphinx.ext.mathjax import MATHJAX_URL +from sphinx.testing.util import assert_node + + +def has_binary(binary): + try: + subprocess.check_output([binary]) + except FileNotFoundError: + return False + except OSError: + pass + return True + + +@pytest.mark.skipif(not has_binary('dvipng'), + reason='Requires dvipng" binary') +@pytest.mark.sphinx('html', testroot='ext-math-simple', + confoverrides={'extensions': ['sphinx.ext.imgmath']}) +def test_imgmath_png(app, status, warning): + app.build(force_all=True) + if "LaTeX command 'latex' cannot be run" in warning.getvalue(): + msg = 'LaTeX command "latex" is not available' + raise pytest.skip.Exception(msg) + if "dvipng command 'dvipng' cannot be run" in warning.getvalue(): + msg = 'dvipng command "dvipng" is not available' + raise pytest.skip.Exception(msg) + + content = (app.outdir / 'index.html').read_text(encoding='utf8') + shutil.rmtree(app.outdir) + html = (r'
\s*

\s*\s*

\s*
') + assert re.search(html, content, re.DOTALL) + + +@pytest.mark.skipif(not has_binary('dvisvgm'), + reason='Requires dvisvgm" binary') +@pytest.mark.sphinx('html', testroot='ext-math-simple', + confoverrides={'extensions': ['sphinx.ext.imgmath'], + 'imgmath_image_format': 'svg'}) +def test_imgmath_svg(app, status, warning): + app.build(force_all=True) + if "LaTeX command 'latex' cannot be run" in warning.getvalue(): + msg = 'LaTeX command "latex" is not available' + raise pytest.skip.Exception(msg) + if "dvisvgm command 'dvisvgm' cannot be run" in warning.getvalue(): + msg = 'dvisvgm command "dvisvgm" is not available' + raise pytest.skip.Exception(msg) + + content = (app.outdir / 'index.html').read_text(encoding='utf8') + shutil.rmtree(app.outdir) + html = (r'
\s*

\s*\s*

\s*
') + assert re.search(html, content, re.DOTALL) + + +@pytest.mark.skipif(not has_binary('dvisvgm'), + reason='Requires dvisvgm" binary') +@pytest.mark.sphinx('html', testroot='ext-math-simple', + confoverrides={'extensions': ['sphinx.ext.imgmath'], + 'imgmath_image_format': 'svg', + 'imgmath_embed': True}) +def test_imgmath_svg_embed(app, status, warning): + app.build(force_all=True) + if "LaTeX command 'latex' cannot be run" in warning.getvalue(): + msg = 'LaTeX command "latex" is not available' + raise pytest.skip.Exception(msg) + if "dvisvgm command 'dvisvgm' cannot be run" in warning.getvalue(): + msg = 'dvisvgm command "dvisvgm" is not available' + raise pytest.skip.Exception(msg) + + content = (app.outdir / 'index.html').read_text(encoding='utf8') + shutil.rmtree(app.outdir) + html = r'' + '' in content) + + +@pytest.mark.sphinx('html', testroot='ext-math', + confoverrides={'extensions': ['sphinx.ext.mathjax']}) +def test_mathjax_align(app, status, warning): + app.build(force_all=True) + + content = (app.outdir / 'index.html').read_text(encoding='utf8') + shutil.rmtree(app.outdir) + html = (r'
\s*' + r'\\\[ \\begin\{align\}\\begin\{aligned\}S \&= \\pi r\^2\\\\' + r'V \&= \\frac\{4\}\{3\} \\pi r\^3\\end\{aligned\}\\end\{align\} \\\]
') + assert re.search(html, content, re.DOTALL) + + +@pytest.mark.sphinx('html', testroot='ext-math', + confoverrides={'math_number_all': True, + 'extensions': ['sphinx.ext.mathjax']}) +def test_math_number_all_mathjax(app, status, warning): + app.build() + + content = (app.outdir / 'index.html').read_text(encoding='utf8') + html = (r'
\s*' + r'\(1\)\xb6\\\[a\^2\+b\^2=c\^2\\\]
') + assert re.search(html, content, re.DOTALL) + + +@pytest.mark.sphinx('latex', testroot='ext-math', + confoverrides={'extensions': ['sphinx.ext.mathjax']}) +def test_math_number_all_latex(app, status, warning): + app.build() + + content = (app.outdir / 'python.tex').read_text(encoding='utf8') + macro = (r'\\begin{equation\*}\s*' + r'\\begin{split}a\^2\+b\^2=c\^2\\end{split}\s*' + r'\\end{equation\*}') + assert re.search(macro, content, re.DOTALL) + + macro = r'Inline \\\(E=mc\^2\\\)' + assert re.search(macro, content, re.DOTALL) + + macro = (r'\\begin{equation\*}\s*' + r'\\begin{split}e\^{i\\pi}\+1=0\\end{split}\s+' + r'\\end{equation\*}') + assert re.search(macro, content, re.DOTALL) + + macro = (r'\\begin{align\*}\\!\\begin{aligned}\s*' + r'S &= \\pi r\^2\\\\\s*' + r'V &= \\frac\{4}\{3} \\pi r\^3\\\\\s*' + r'\\end{aligned}\\end{align\*}') + assert re.search(macro, content, re.DOTALL) + + macro = r'Referencing equation \\eqref{equation:math:foo}.' + assert re.search(macro, content, re.DOTALL) + + +@pytest.mark.sphinx('html', testroot='ext-math', + confoverrides={'extensions': ['sphinx.ext.mathjax'], + 'math_eqref_format': 'Eq.{number}'}) +def test_math_eqref_format_html(app, status, warning): + app.build(force_all=True) + + content = (app.outdir / 'math.html').read_text(encoding='utf8') + html = ('

Referencing equation Eq.1 and Eq.1.

') + assert html in content + + +@pytest.mark.sphinx('latex', testroot='ext-math', + confoverrides={'extensions': ['sphinx.ext.mathjax'], + 'math_eqref_format': 'Eq.{number}'}) +def test_math_eqref_format_latex(app, status, warning): + app.build(force_all=True) + + content = (app.outdir / 'python.tex').read_text(encoding='utf8') + macro = (r'Referencing equation Eq.\\ref{equation:math:foo} and ' + r'Eq.\\ref{equation:math:foo}.') + assert re.search(macro, content, re.DOTALL) + + +@pytest.mark.sphinx('html', testroot='ext-math', + confoverrides={'extensions': ['sphinx.ext.mathjax'], + 'numfig': True, + 'math_numfig': True}) +def test_mathjax_numfig_html(app, status, warning): + app.build(force_all=True) + + content = (app.outdir / 'math.html').read_text(encoding='utf8') + html = ('
\n' + '(1.2)') + assert html in content + html = ('

Referencing equation (1.1) and ' + '(1.1).

') + assert html in content + + +@pytest.mark.sphinx('html', testroot='ext-math', + confoverrides={'extensions': ['sphinx.ext.imgmath'], + 'numfig': True, + 'numfig_secnum_depth': 0, + 'math_numfig': True}) +def test_imgmath_numfig_html(app, status, warning): + app.build(force_all=True) + + content = (app.outdir / 'page.html').read_text(encoding='utf8') + html = '(3)Referencing equations (1) and ' + '(3).

') + assert html in content + + +@pytest.mark.sphinx('dummy', testroot='ext-math-compat') +def test_math_compat(app, status, warning): + with warnings.catch_warnings(record=True): + app.build(force_all=True) + doctree = app.env.get_and_resolve_doctree('index', app.builder) + + assert_node(doctree, + [nodes.document, nodes.section, (nodes.title, + [nodes.section, (nodes.title, + nodes.paragraph)], + nodes.section)]) + assert_node(doctree[0][1][1], + ('Inline: ', + [nodes.math, "E=mc^2"], + '\nInline my math: ', + [nodes.math, "E = mc^2"])) + assert_node(doctree[0][2], + ([nodes.title, "block"], + [nodes.math_block, "a^2+b^2=c^2\n\n"], + [nodes.paragraph, "Second math"], + [nodes.math_block, "e^{i\\pi}+1=0\n\n"], + [nodes.paragraph, "Multi math equations"], + [nodes.math_block, "E = mc^2"])) + + +@pytest.mark.sphinx('html', testroot='ext-math', + confoverrides={'extensions': ['sphinx.ext.mathjax'], + 'mathjax3_config': {'extensions': ['tex2jax.js']}}) +def test_mathjax3_config(app, status, warning): + app.build(force_all=True) + + content = (app.outdir / 'index.html').read_text(encoding='utf8') + assert MATHJAX_URL in content + assert ('' in content) + + +@pytest.mark.sphinx('html', testroot='ext-math', + confoverrides={'extensions': ['sphinx.ext.mathjax'], + 'mathjax2_config': {'extensions': ['tex2jax.js']}}) +def test_mathjax2_config(app, status, warning): + app.build(force_all=True) + + content = (app.outdir / 'index.html').read_text(encoding='utf8') + assert ('' in content) + + +@pytest.mark.sphinx('html', testroot='ext-math', + confoverrides={'extensions': ['sphinx.ext.mathjax'], + 'mathjax_options': {'async': 'async'}, + 'mathjax3_config': {'extensions': ['tex2jax.js']}}) +def test_mathjax_options_async_for_mathjax3(app, status, warning): + app.build(force_all=True) + + content = (app.outdir / 'index.html').read_text(encoding='utf8') + assert MATHJAX_URL in content + assert ('' in content + + +@pytest.mark.sphinx( + 'html', testroot='ext-math', + confoverrides={ + 'extensions': ['sphinx.ext.mathjax'], + 'mathjax_path': 'MathJax.js?config=scipy-mathjax', + }, +) +def test_mathjax_path_config(app): + app.build(force_all=True) + + content = (app.outdir / 'index.html').read_text(encoding='utf8') + assert '' in content + + +@pytest.mark.sphinx('html', testroot='ext-math', + confoverrides={'extensions': ['sphinx.ext.mathjax']}) +def test_mathjax_is_installed_only_if_document_having_math(app, status, warning): + app.build(force_all=True) + + content = (app.outdir / 'index.html').read_text(encoding='utf8') + assert MATHJAX_URL in content + + content = (app.outdir / 'nomath.html').read_text(encoding='utf8') + assert MATHJAX_URL not in content + + +@pytest.mark.sphinx('html', testroot='basic', + confoverrides={'extensions': ['sphinx.ext.mathjax']}) +def test_mathjax_is_not_installed_if_no_equations(app, status, warning): + app.build(force_all=True) + + content = (app.outdir / 'index.html').read_text(encoding='utf8') + assert 'MathJax.js' not in content + + +@pytest.mark.sphinx('html', testroot='ext-math', + confoverrides={'extensions': ['sphinx.ext.mathjax']}) +def test_mathjax_is_installed_if_no_equations_when_forced(app, status, warning): + app.set_html_assets_policy('always') + app.build(force_all=True) + + content = (app.outdir / 'index.html').read_text(encoding='utf8') + assert MATHJAX_URL in content + + content = (app.outdir / 'nomath.html').read_text(encoding='utf8') + assert MATHJAX_URL in content + + +@pytest.mark.sphinx('html', testroot='ext-math-include', + confoverrides={'extensions': ['sphinx.ext.mathjax']}) +def test_mathjax_is_installed_if_included_file_has_equations(app): + app.build(force_all=True) + + # no real equations at the rst level, but includes "included" + content = (app.outdir / 'index.html').read_text(encoding='utf8') + assert MATHJAX_URL in content + + # no real equations at the rst level, but includes "math.rst" + content = (app.outdir / 'included.html').read_text(encoding='utf8') + assert MATHJAX_URL in content + + content = (app.outdir / 'math.html').read_text(encoding='utf8') + assert MATHJAX_URL in content + + +@pytest.mark.sphinx('singlehtml', testroot='ext-math', + confoverrides={'extensions': ['sphinx.ext.mathjax']}) +def test_mathjax_is_installed_only_if_document_having_math_singlehtml(app): + app.build(force_all=True) + + content = (app.outdir / 'index.html').read_text(encoding='utf8') + assert MATHJAX_URL in content + + +@pytest.mark.sphinx('singlehtml', testroot='basic', + confoverrides={'extensions': ['sphinx.ext.mathjax']}) +def test_mathjax_is_not_installed_if_no_equations_singlehtml(app): + app.build(force_all=True) + + content = (app.outdir / 'index.html').read_text(encoding='utf8') + assert 'MathJax.js' not in content + + +@pytest.mark.sphinx('singlehtml', testroot='ext-math-include', + confoverrides={'extensions': ['sphinx.ext.mathjax']}) +def test_mathjax_is_installed_if_included_file_has_equations_singlehtml(app): + app.build(force_all=True) + + content = (app.outdir / 'index.html').read_text(encoding='utf8') + assert MATHJAX_URL in content -- cgit v1.2.3