Skip to content

Commit 8deaf88

Browse files
authored
Merge pull request #1111 from mathjax/tests/tex_error_coverage
Towards completion of TexError tests
2 parents 80f1978 + 55cb5e4 commit 8deaf88

File tree

8 files changed

+573
-8
lines changed

8 files changed

+573
-8
lines changed

testsuite/scripts/test-diff.el

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
;;;
2+
;;; Tools for working with Jest tests in Emacs.
3+
;;;
4+
;;;
5+
;;; Copyright (c) 2024 The MathJax Consortium
6+
7+
(require 'ediff)
8+
9+
;;; Jest Tests
10+
;;; ==========
11+
;;;
12+
;;; Run by piping stdout and stderr into a file. Then use the output file form
13+
;;; the stderr pipe to replace expected for actual
14+
;;;
15+
;;; If piping stderr only the output file will contain noise for tty
16+
;;; colorization.
17+
;;;
18+
19+
(defun jest-find-expected ()
20+
(block find-fail-block
21+
(let ((expected (condition-case nil
22+
(search-forward "Expected value")
23+
(error nil))))
24+
(if (null expected)
25+
(let ((expected (condition-case nil
26+
(search-forward "Expected:")
27+
(error nil))))
28+
expected)
29+
expected))))
30+
31+
(defun jest-find-fail ()
32+
;; Returns start end for actual and expected and position of fail o/w nil.
33+
(interactive)
34+
(block find-fail-block
35+
(let ((pos (condition-case nil
36+
(search-forward "" nil t)
37+
(error nil))))
38+
(when (null pos)
39+
(return-from find-fail-block nil))
40+
(let ((expected (jest-find-expected))
41+
(actual (condition-case nil
42+
(search-forward "Received:")
43+
(error nil)))
44+
)
45+
(when (or (null actual) (null expected))
46+
(return-from find-fail-block nil))
47+
(let* ((beg1 (progn
48+
(goto-char actual)
49+
(search-forward "\"")
50+
(backward-char)
51+
(point)))
52+
(dummy1 (forward-sexp))
53+
(end1 (1- (point)))
54+
(fail1 (buffer-substring beg1 end1))
55+
(beg2 (progn
56+
(goto-char expected)
57+
(search-forward "\"")
58+
(backward-char)
59+
(point)))
60+
(dummy2 (forward-sexp))
61+
(end2 (1- (point)))
62+
(fail2 (buffer-substring beg2 end2)))
63+
(list (cons beg1 end1) (cons beg2 end2) pos (cons fail1 fail2))
64+
)))))
65+
66+
67+
;; Automatic region ediff for failed test.
68+
(defun jest-diff-fail ()
69+
(interactive)
70+
;; (do* ((fail (find-fail)))
71+
;; ((null fail))
72+
(let ((fail (jest-find-fail)))
73+
(when (null fail) nil)
74+
(ediff-regions-internal
75+
(get-buffer (buffer-name)) (caar fail) (cdar fail)
76+
(get-buffer (buffer-name)) (caadr fail) (cdadr fail)
77+
nil 'ediff-regions-wordwise 'word-mode nil)))
78+
79+
(global-set-key [?\C-c ?\C-d] 'jest-diff-fail)
80+
81+
;; Separates expected and received values for all failed tests
82+
;; into two separate buffers/files for ease of comparison.
83+
;; Then simply run an ediff-buffers.
84+
(defun jest-separate-fails (bufferA bufferB)
85+
(interactive
86+
(list (read-buffer "Buffer for Expected: ")
87+
(read-buffer "Buffer for Received: ")))
88+
(condition-case nil
89+
(search-forward "Summary of all failing tests")
90+
(error (beginning-of-buffer)))
91+
(do ((fail (jest-find-fail) (jest-find-fail)))
92+
((null fail) nil)
93+
(print fail)
94+
(append-to-buffer bufferA (caadr fail) (cdadr fail))
95+
(with-current-buffer bufferA (insert "\n\n"))
96+
(append-to-buffer bufferB (caar fail) (cdar fail))
97+
(with-current-buffer bufferB (insert "\n\n"))
98+
))
99+
100+
;;; Replace expected for actual
101+
;;; Make sure that the test output is in the other window.
102+
;;; Go to position where you want the next test inserted.
103+
(defun jest-replace-expected-for-actual ()
104+
(interactive)
105+
(block expected-block
106+
(other-window 1)
107+
(let* ((fail (jest-find-fail))
108+
(actual (car (fourth fail)))
109+
(str (subseq actual 1))
110+
)
111+
(other-window 1)
112+
(insert str)
113+
)))

testsuite/tests/input/tex/Ams.test.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2509,3 +2509,87 @@ describe('Ams Complex', () => {
25092509
</math>`
25102510
));
25112511
});
2512+
2513+
describe('Ams SideSet', () => {
2514+
it('Sideset Empty', () =>
2515+
toXmlMatch(
2516+
tex2mml('\\sideset{}{}{}'),
2517+
`<math xmlns=\"http://www.w3.org/1998/Math/MathML\" data-latex=\"\\sideset{}{}{}\" display=\"block\">
2518+
<mrow data-mjx-texclass=\"OP\" data-latex=\"\\sideset{}{}{}\"></mrow>
2519+
</math>`
2520+
));
2521+
it('Sideset Simple', () =>
2522+
toXmlMatch(
2523+
tex2mml('\\sideset{}{}{a}'),
2524+
`<math xmlns=\"http://www.w3.org/1998/Math/MathML\" data-latex=\"\\sideset{}{}{a}\" display=\"block\">
2525+
<mrow data-mjx-texclass=\"OP\" data-latex=\"\\sideset{}{}{a}\">
2526+
<mi data-latex=\"a\">a</mi>
2527+
</mrow>
2528+
</math>`
2529+
));
2530+
it('Sideset Simple Right', () =>
2531+
toXmlMatch(
2532+
tex2mml('\\sideset{}{\'}{a}'),
2533+
`<math xmlns=\"http://www.w3.org/1998/Math/MathML\" data-latex=\"\\sideset{}{'}{a}\" display=\"block\">
2534+
<mrow data-mjx-texclass=\"OP\" data-latex=\"\\sideset{}{'}{a}\">
2535+
<msup data-latex=\"'\">
2536+
<mi data-latex=\"a\">a</mi>
2537+
<mo data-mjx-alternate=\"1\" data-latex=\"'\">&#x2032;</mo>
2538+
</msup>
2539+
</mrow>
2540+
</math>`
2541+
));
2542+
it('Sideset Simple Left', () =>
2543+
toXmlMatch(
2544+
tex2mml('\\sideset{\'}{}{a}'),
2545+
`<math xmlns=\"http://www.w3.org/1998/Math/MathML\" data-latex=\"\\sideset{'}{}{a}\" display=\"block\">
2546+
<mrow data-mjx-texclass=\"OP\" data-latex=\"\\sideset{'}{}{a}\">
2547+
<mmultiscripts data-mjx-script-align=\"left\">
2548+
<mi data-latex=\"a\">a</mi>
2549+
<mprescripts></mprescripts>
2550+
<mo data-mjx-alternate=\"1\" data-latex=\"'\">&#x2032;</mo>
2551+
<none></none>
2552+
</mmultiscripts>
2553+
</mrow>
2554+
</math>`
2555+
));
2556+
it('Sideset Simple Left Right', () =>
2557+
toXmlMatch(
2558+
tex2mml('\\sideset{\'}{\'}{a}'),
2559+
`<math xmlns=\"http://www.w3.org/1998/Math/MathML\" data-latex=\"\\sideset{'}{'}{a}\" display=\"block\">
2560+
<mrow data-mjx-texclass=\"OP\" data-latex=\"\\sideset{'}{'}{a}\">
2561+
<mmultiscripts data-mjx-script-align=\"left\">
2562+
<mi data-latex=\"a\">a</mi>
2563+
<mo data-mjx-alternate=\"1\" data-latex=\"'\">&#x2032;</mo>
2564+
<none></none>
2565+
<mprescripts></mprescripts>
2566+
<mo data-mjx-alternate=\"1\" data-latex=\"'\">&#x2032;</mo>
2567+
<none></none>
2568+
</mmultiscripts>
2569+
</mrow>
2570+
</math>`
2571+
));
2572+
it('Sideset Simple Sum', () =>
2573+
toXmlMatch(
2574+
tex2mml('\\sideset{}{\'}\\sum_{n=0}^{k}n'),
2575+
`<math xmlns=\"http://www.w3.org/1998/Math/MathML\" data-latex=\"\\sideset{}{'}\\sum_{n=0}^{k}n\" display=\"block\">
2576+
<munderover data-latex=\"\\sideset{}{'}\\sum_{n=0}^{k}\">
2577+
<mrow data-mjx-texclass=\"OP\" data-latex=\"\\sideset{}{'}\\sum\">
2578+
<msup data-latex=\"'\">
2579+
<mo data-latex=\"\\sum\">&#x2211;</mo>
2580+
<mo data-mjx-alternate=\"1\" data-latex=\"'\">&#x2032;</mo>
2581+
</msup>
2582+
</mrow>
2583+
<mrow data-mjx-texclass=\"ORD\" data-latex=\"{n=0}\">
2584+
<mi data-latex=\"n\">n</mi>
2585+
<mo data-latex=\"=\">=</mo>
2586+
<mn data-latex=\"0\">0</mn>
2587+
</mrow>
2588+
<mrow data-mjx-texclass=\"ORD\" data-latex=\"{k}\">
2589+
<mi data-latex=\"k\">k</mi>
2590+
</mrow>
2591+
</munderover>
2592+
<mi data-latex=\"n\">n</mi>
2593+
</math>`
2594+
));
2595+
});

testsuite/tests/input/tex/Base.test.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1687,10 +1687,10 @@ describe('Error', () => {
16871687
));
16881688
it('EnvMissingEnd Array', () =>
16891689
toXmlMatch(
1690-
tex2mml('\\begin{array}a'),
1691-
`<math xmlns="http://www.w3.org/1998/Math/MathML" data-latex="\\begin{array}a" display="block">
1692-
<merror data-mjx-error="Illegal pream-token (a)">
1693-
<mtext>Illegal pream-token (a)</mtext>
1690+
tex2mml('\\begin{array}{c}a'),
1691+
`<math xmlns="http://www.w3.org/1998/Math/MathML" data-latex="\\begin{array}{c}a" display="block">
1692+
<merror data-mjx-error="Missing \\end{array}">
1693+
<mtext>Missing \\end{array}</mtext>
16941694
</merror>
16951695
</math>`
16961696
));
@@ -2752,10 +2752,10 @@ describe('InternalMath', () => {
27522752
toXmlMatch(
27532753
tex2mml('a\\mbox{$}} c'),
27542754
`<math xmlns="http://www.w3.org/1998/Math/MathML" data-latex="a\\mbox{$}} c" display="block">
2755-
<merror data-mjx-error="Math not terminated in text box">
2756-
<mtext>Math not terminated in text box</mtext>
2757-
</merror>
2758-
</math>`
2755+
<merror data-mjx-error="Math mode is not properly terminated">
2756+
<mtext>Math mode is not properly terminated</mtext>
2757+
</merror>
2758+
</math>`
27592759
));
27602760
it('Mbox Internal Display', () =>
27612761
toXmlMatch(
@@ -4415,3 +4415,16 @@ describe('Base Complex', () => {
44154415
</math>`
44164416
));
44174417
});
4418+
4419+
4420+
describe('Column Parser', () => {
4421+
it('BadPreamToken', () =>
4422+
toXmlMatch(
4423+
tex2mml('\\begin{array}a'),
4424+
`<math xmlns="http://www.w3.org/1998/Math/MathML" data-latex="\\begin{array}a" display="block">
4425+
<merror data-mjx-error="Illegal pream-token (a)">
4426+
<mtext>Illegal pream-token (a)</mtext>
4427+
</merror>
4428+
</math>`
4429+
));
4430+
});

testsuite/tests/input/tex/Braket.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,4 +504,13 @@ describe('Braket', () => {
504504
</mrow>
505505
</math>`
506506
));
507+
it('Braket-error', () =>
508+
toXmlMatch(
509+
tex2mml('\\braket'),
510+
`<math xmlns="http://www.w3.org/1998/Math/MathML" data-latex="\\braket" display="block">
511+
<merror data-mjx-error="Missing argument for \\braket">
512+
<mtext>Missing argument for \\braket</mtext>
513+
</merror>
514+
</math>`
515+
));
507516
});
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import { beforeEach, describe, it } from '@jest/globals';
2+
import { toXmlMatch, setupTex, tex2mml } from '#helpers';
3+
4+
beforeEach(() => {});
5+
6+
function runMacroTests(
7+
macros: {[key: string]: any},
8+
expected: string,
9+
control: string,
10+
macro: string) {
11+
setupTex(['base', 'configmacros'], macros);
12+
toXmlMatch(tex2mml(control), expected.replace('PH', control));
13+
toXmlMatch(tex2mml(macro), expected.replace('PH', macro));
14+
}
15+
16+
describe('Config Macros Active', () => {
17+
it('Macros Simple', () =>
18+
runMacroTests(
19+
{active: {"@": "~"}},
20+
`<math xmlns=\"http://www.w3.org/1998/Math/MathML\" data-latex=\"PH\" display=\"block\">
21+
<mi data-latex=\"A\">A</mi>
22+
<mtext data-latex=\"~\">&#xA0;</mtext>
23+
<mi data-latex=\"a\">a</mi>
24+
</math>`,
25+
'A~a',
26+
'A@a'
27+
));
28+
});
29+
30+
describe('Config Macros Commands', () => {
31+
it('Commands Simple', () =>
32+
runMacroTests(
33+
{macros: {"RR": "{\\bf R}"}},
34+
`<math xmlns=\"http://www.w3.org/1998/Math/MathML\" data-latex=\"PH\" display=\"block\">
35+
<mrow data-mjx-texclass=\"ORD\" data-latex=\"{\\bf R}\">
36+
<mi mathvariant=\"bold\" data-latex=\"R\">R</mi>
37+
</mrow>
38+
</math>`,
39+
'{\\bf R}',
40+
'\\RR'));
41+
it('Commands Argument', () =>
42+
runMacroTests(
43+
{macros: {"bold": ["{\\bf #1}", 1]}},
44+
`<math xmlns=\"http://www.w3.org/1998/Math/MathML\" data-latex=\"PH\" display=\"block\">
45+
<mrow data-mjx-texclass=\"ORD\" data-latex=\"{\\bf bold}\">
46+
<mi mathvariant=\"bold\" data-latex=\"b\">b</mi>
47+
<mi mathvariant=\"bold\" data-latex=\"o\">o</mi>
48+
<mi mathvariant=\"bold\" data-latex=\"l\">l</mi>
49+
<mi mathvariant=\"bold\" data-latex=\"d\">d</mi>
50+
</mrow>
51+
</math>`,
52+
'{\\bf bold}',
53+
'\\bold{bold}'));
54+
it('Commands Aux Argument', () =>
55+
runMacroTests(
56+
{macros: {"foo": ["\\mbox{first } #1 \\mbox{ second } #2", 2, ["[", "]"]]}},
57+
`<math xmlns=\"http://www.w3.org/1998/Math/MathML\" data-latex=\"PH\" display=\"block\">
58+
<mstyle displaystyle=\"false\" scriptlevel=\"0\" data-latex=\"\\mbox{first }\">
59+
<mtext>first&#xA0;</mtext>
60+
</mstyle>
61+
<mi data-latex=\"h\">h</mi>
62+
<mi data-latex=\"i\">i</mi>
63+
<mstyle displaystyle=\"false\" scriptlevel=\"0\" data-latex=\"\\mbox{ second }\">
64+
<mtext>&#xA0;second&#xA0;</mtext>
65+
</mstyle>
66+
<mi data-latex=\"t\">t</mi>
67+
<mi data-latex=\"h\">h</mi>
68+
<mi data-latex=\"e\">e</mi>
69+
<mi data-latex=\"r\">r</mi>
70+
<mi data-latex=\"e\">e</mi>
71+
</math>`,
72+
'\\mbox{first } hi \\mbox{ second } there',
73+
'\\foo[hi]{there}'));
74+
});
75+
76+
describe('Config Macros Environment', () => {
77+
it('Environment Simple', () =>
78+
runMacroTests(
79+
{environments: {"myHeartEnv": ["\\heartsuit", "\\spadesuit"]}},
80+
`<math xmlns=\"http://www.w3.org/1998/Math/MathML\" data-latex=\"\\begin{myHeartEnv}a\\end{myHeartEnv}\" display=\"block\">
81+
<mi mathvariant=\"normal\" data-latex=\"\\heartsuit\">&#x2661;</mi>
82+
<mi data-latex=\"a\">a</mi>
83+
<mi mathvariant=\"normal\" data-latex=\"\\spadesuit\">&#x2660;</mi>
84+
</math>`,
85+
'\\begin{myHeartEnv}a\\end{myHeartEnv}',
86+
'\\begin{myHeartEnv}a\\end{myHeartEnv}'
87+
));
88+
});

0 commit comments

Comments
 (0)