| 1 | from pathlib import Path |
| 2 | import shutil |
| 3 | import subprocess |
| 4 | |
| 5 | import pytest |
| 6 | |
| 7 | |
| 8 | PROJECT_ROOT = Path(__file__).resolve().parents[1] |
| 9 | MESSAGES_JS = PROJECT_ROOT / "webui" / "js" / "messages.js" |
| 10 | |
| 11 | |
| 12 | def test_standard_latex_delimiters_survive_markdown_preprocessing(): |
| 13 | if not shutil.which("node"): |
| 14 | pytest.skip("Node.js is required to execute the LaTeX delimiter regression.") |
| 15 | |
| 16 | source = MESSAGES_JS.read_text(encoding="utf-8") |
| 17 | converter_start = source.index("function convertLatexDelimiters(") |
| 18 | converter_end = source.index("\nfunction renderLatexElements", converter_start) |
| 19 | function_source = source[converter_start:converter_end] |
| 20 | |
| 21 | script = rf""" |
| 22 | {function_source} |
| 23 | |
| 24 | function assertEqual(actual, expected) {{ |
| 25 | if (actual !== expected) {{ |
| 26 | throw new Error(`Expected ${{JSON.stringify(expected)}}, got ${{JSON.stringify(actual)}}`); |
| 27 | }} |
| 28 | }} |
| 29 | |
| 30 | const encode = (value) => |
| 31 | Array.from(value, (char) => `&#${{char.codePointAt(0)}};`).join(''); |
| 32 | |
| 33 | assertEqual( |
| 34 | convertLatexDelimiters(String.raw`\[x^2 < y & z > 0\]`), |
| 35 | `<latex data-display="true">${{encode('x^2 < y & z > 0')}}</latex>`, |
| 36 | ); |
| 37 | assertEqual( |
| 38 | convertLatexDelimiters(String.raw`Before \(x+y\) after`), |
| 39 | `Before <latex>${{encode('x+y')}}</latex> after`, |
| 40 | ); |
| 41 | assertEqual( |
| 42 | convertLatexDelimiters(String.raw`$$\sum_n a_n$$`), |
| 43 | `<latex data-display="true">${{encode(String.raw`\sum_n a_n`)}}</latex>`, |
| 44 | ); |
| 45 | const protectedCode = |
| 46 | 'Inline `' + String.raw`\(not_math\)` + '` and:\n' + |
| 47 | '```tex\n' + String.raw`\[also_not_math\]` + '\n```'; |
| 48 | assertEqual(convertLatexDelimiters(protectedCode), protectedCode); |
| 49 | """ |
| 50 | subprocess.run(["node", "--input-type=module", "-e", script], check=True) |
| 51 | |
| 52 | |
| 53 | def test_katex_renderer_uses_text_content_and_display_metadata(): |
| 54 | source = MESSAGES_JS.read_text(encoding="utf-8") |
| 55 | |
| 56 | assert "if (latex) processedContent = convertLatexDelimiters(processedContent)" in source |
| 57 | assert "renderLatexElements(contentDiv)" in source |
| 58 | assert "globalThis.katex.render(element.textContent, element" in source |
| 59 | assert 'displayMode: element.dataset.display === "true"' in source |
| 60 | assert "drawKvpsIncremental(stepDetailScroll, kvps)" in source |
| 61 | assert "drawKvpsIncremental(stepDetailScroll, kvps, latex)" not in source |
| 62 | assert "if (result.kvpsTable) renderLatexText(result.kvpsTable)" in source |
| 63 | assert "globalThis.renderMathInElement(container" in source |