File size: 10,647 Bytes
f0743f4 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 | import { preprocessLaTeX } from './latex';
describe('preprocessLaTeX', () => {
test('returns the same string if no LaTeX patterns are found', () => {
const content = 'This is a test string without LaTeX or dollar signs';
expect(preprocessLaTeX(content)).toBe(content);
});
test('returns the same string if no dollar signs are present', () => {
const content = 'This has LaTeX \\(x^2\\) and \\[y^2\\] but no dollars';
expect(preprocessLaTeX(content)).toBe(content);
});
test('preserves valid inline LaTeX delimiters \\(...\\)', () => {
const content = 'This is inline LaTeX: \\(x^2 + y^2 = z^2\\)';
expect(preprocessLaTeX(content)).toBe(content);
});
test('preserves valid block LaTeX delimiters \\[...\\]', () => {
const content = 'This is block LaTeX: \\[E = mc^2\\]';
expect(preprocessLaTeX(content)).toBe(content);
});
test('preserves valid double dollar delimiters', () => {
const content = 'This is valid: $$x^2 + y^2 = z^2$$';
expect(preprocessLaTeX(content)).toBe(content);
});
test('converts single dollar delimiters to double dollars', () => {
const content = 'Inline math: $x^2 + y^2 = z^2$';
const expected = 'Inline math: $$x^2 + y^2 = z^2$$';
expect(preprocessLaTeX(content)).toBe(expected);
});
test('converts multiple single dollar expressions', () => {
const content = 'First $a + b = c$ and second $x^2 + y^2 = z^2$';
const expected = 'First $$a + b = c$$ and second $$x^2 + y^2 = z^2$$';
expect(preprocessLaTeX(content)).toBe(expected);
});
test('escapes currency dollar signs', () => {
const content = 'Price is $50 and $100';
const expected = 'Price is \\$50 and \\$100';
expect(preprocessLaTeX(content)).toBe(expected);
});
test('escapes currency with spaces', () => {
const content = '$50 is $20 + $30';
const expected = '\\$50 is \\$20 + \\$30';
expect(preprocessLaTeX(content)).toBe(expected);
});
test('escapes currency with commas', () => {
const content = 'The price is $1,000,000 for this item.';
const expected = 'The price is \\$1,000,000 for this item.';
expect(preprocessLaTeX(content)).toBe(expected);
});
test('escapes currency with decimals', () => {
const content = 'Total: $29.50 plus tax';
const expected = 'Total: \\$29.50 plus tax';
expect(preprocessLaTeX(content)).toBe(expected);
});
test('converts LaTeX expressions while escaping currency', () => {
const content = 'LaTeX $x^2$ and price $50';
const expected = 'LaTeX $$x^2$$ and price \\$50';
expect(preprocessLaTeX(content)).toBe(expected);
});
test('handles Goldbach Conjecture example', () => {
const content = '- **Goldbach Conjecture**: $2n = p + q$ (every even integer > 2)';
const expected = '- **Goldbach Conjecture**: $$2n = p + q$$ (every even integer > 2)';
expect(preprocessLaTeX(content)).toBe(expected);
});
test('does not escape already escaped dollar signs', () => {
const content = 'Already escaped \\$50 and \\$100';
expect(preprocessLaTeX(content)).toBe(content);
});
test('does not convert already escaped single dollars', () => {
const content = 'Escaped \\$x^2\\$ should not change';
expect(preprocessLaTeX(content)).toBe(content);
});
test('escapes mhchem commands', () => {
const content = '$\\ce{H2O}$ and $\\pu{123 J}$';
const expected = '$$\\\\ce{H2O}$$ and $$\\\\pu{123 J}$$';
expect(preprocessLaTeX(content)).toBe(expected);
});
test('handles empty string', () => {
expect(preprocessLaTeX('')).toBe('');
});
test('handles complex mixed content', () => {
const content = `Valid double $$y^2$$
Currency $100 and $200
Single dollar math $x^2 + y^2$
Chemical $\\ce{H2O}$
Valid brackets \\[z^2\\]`;
const expected = `Valid double $$y^2$$
Currency \\$100 and \\$200
Single dollar math $$x^2 + y^2$$
Chemical $$\\\\ce{H2O}$$
Valid brackets \\[z^2\\]`;
expect(preprocessLaTeX(content)).toBe(expected);
});
test('handles multiple equations with currency', () => {
const content = `- **Euler's Totient Function**: $\\phi(n) = n \\prod_{p|n} \\left(1 - \\frac{1}{p}\\right)$
- **Total Savings**: $500 + $200 + $150 = $850`;
const expected = `- **Euler's Totient Function**: $$\\phi(n) = n \\prod_{p|n} \\left(1 - \\frac{1}{p}\\right)$$
- **Total Savings**: \\$500 + \\$200 + \\$150 = \\$850`;
expect(preprocessLaTeX(content)).toBe(expected);
});
test('handles inline code blocks', () => {
const content = 'Outside $x^2$ and inside code: `$100`';
const expected = 'Outside $$x^2$$ and inside code: `$100`';
expect(preprocessLaTeX(content)).toBe(expected);
});
test('handles multiline code blocks', () => {
const content = '```\n$100\n$variable\n```\nOutside $x^2$';
const expected = '```\n$100\n$variable\n```\nOutside $$x^2$$';
expect(preprocessLaTeX(content)).toBe(expected);
});
test('preserves LaTeX expressions with special characters', () => {
const content = 'The set is defined as $\\{x | x > 0\\}$.';
const expected = 'The set is defined as $$\\{x | x > 0\\}$$.';
expect(preprocessLaTeX(content)).toBe(expected);
});
test('handles complex physics equations', () => {
const content = `- **Schrödinger Equation**: $i\\hbar\\frac{\\partial}{\\partial t}|\\psi\\rangle = \\hat{H}|\\psi\\rangle$
- **Einstein Field Equations**: $G_{\\mu\\nu} = \\frac{8\\pi G}{c^4} T_{\\mu\\nu}$`;
const expected = `- **Schrödinger Equation**: $$i\\hbar\\frac{\\partial}{\\partial t}|\\psi\\rangle = \\hat{H}|\\psi\\rangle$$
- **Einstein Field Equations**: $$G_{\\mu\\nu} = \\frac{8\\pi G}{c^4} T_{\\mu\\nu}$$`;
expect(preprocessLaTeX(content)).toBe(expected);
});
test('handles financial calculations with currency', () => {
const content = `- **Simple Interest**: $A = P + Prt = $1,000 + ($1,000)(0.05)(2) = $1,100$
- **ROI**: $\\text{ROI} = \\frac{$1,200 - $1,000}{$1,000} \\times 100\\% = 20\\%$`;
const expected = `- **Simple Interest**: $$A = P + Prt = \\$1,000 + (\\$1,000)(0.05)(2) = \\$1,100$$
- **ROI**: $$\\text{ROI} = \\frac{\\$1,200 - \\$1,000}{\\$1,000} \\times 100\\% = 20\\%$$`;
expect(preprocessLaTeX(content)).toBe(expected);
});
test('does not convert partial or malformed expressions', () => {
const content = 'A single $ sign should not be converted';
const expected = 'A single $ sign should not be converted';
expect(preprocessLaTeX(content)).toBe(expected);
});
test('handles nested parentheses in LaTeX', () => {
const content =
'Matrix determinant: $\\det(A) = \\sum_{\\sigma \\in S_n} \\text{sgn}(\\sigma) \\prod_{i=1}^n a_{i,\\sigma(i)}$';
const expected =
'Matrix determinant: $$\\det(A) = \\sum_{\\sigma \\in S_n} \\text{sgn}(\\sigma) \\prod_{i=1}^n a_{i,\\sigma(i)}$$';
expect(preprocessLaTeX(content)).toBe(expected);
});
test('preserves spacing in equations', () => {
const content = 'Equation: $f(x) = 2x + 3$ where x is a variable.';
const expected = 'Equation: $$f(x) = 2x + 3$$ where x is a variable.';
expect(preprocessLaTeX(content)).toBe(expected);
});
test('handles LaTeX with newlines inside should not be converted', () => {
const content = `This has $x
y$ which spans lines`;
const expected = `This has $x
y$ which spans lines`;
expect(preprocessLaTeX(content)).toBe(expected);
});
test('handles multiple dollar signs in text', () => {
const content = 'Price $100 then equation $x + y = z$ then another price $50';
const expected = 'Price \\$100 then equation $$x + y = z$$ then another price \\$50';
expect(preprocessLaTeX(content)).toBe(expected);
});
test('handles complex LaTeX with currency in same expression', () => {
const content = 'Calculate $\\text{Total} = \\$500 + \\$200$';
const expected = 'Calculate $$\\text{Total} = \\$500 + \\$200$$';
expect(preprocessLaTeX(content)).toBe(expected);
});
test('preserves already escaped dollars in LaTeX', () => {
const content = 'The formula $f(x) = \\$2x$ represents cost';
const expected = 'The formula $$f(x) = \\$2x$$ represents cost';
expect(preprocessLaTeX(content)).toBe(expected);
});
test('handles adjacent LaTeX and currency', () => {
const content = 'Formula $x^2$ costs $25';
const expected = 'Formula $$x^2$$ costs \\$25';
expect(preprocessLaTeX(content)).toBe(expected);
});
test('handles LaTeX with special characters and currency', () => {
const content = 'Set $\\{x | x > \\$0\\}$ for positive prices';
const expected = 'Set $$\\{x | x > \\$0\\}$$ for positive prices';
expect(preprocessLaTeX(content)).toBe(expected);
});
test('does not convert when closing dollar is preceded by backtick', () => {
const content = 'The error "invalid $lookup namespace" occurs when using `$lookup` operator';
const expected = 'The error "invalid $lookup namespace" occurs when using `$lookup` operator';
expect(preprocessLaTeX(content)).toBe(expected);
});
test('handles mixed backtick and non-backtick cases', () => {
const content = 'Use $x + y$ in math but `$lookup` in code';
const expected = 'Use $$x + y$$ in math but `$lookup` in code';
expect(preprocessLaTeX(content)).toBe(expected);
});
test('escapes currency amounts without commas', () => {
const content =
'The total amount invested is $1157.90 (existing amount) + $500 (new investment) = $1657.90.';
const expected =
'The total amount invested is \\$1157.90 (existing amount) + \\$500 (new investment) = \\$1657.90.';
expect(preprocessLaTeX(content)).toBe(expected);
});
test('handles large currency amounts', () => {
const content = 'You can win $1000000 or even $9999999.99!';
const expected = 'You can win \\$1000000 or even \\$9999999.99!';
expect(preprocessLaTeX(content)).toBe(expected);
});
test('escapes currency with many decimal places', () => {
const content = 'Bitcoin: $0.00001234, Gas: $3.999, Rate: $1.234567890';
const expected = 'Bitcoin: \\$0.00001234, Gas: \\$3.999, Rate: \\$1.234567890';
expect(preprocessLaTeX(content)).toBe(expected);
});
test('escapes abbreviated currency notation', () => {
const content = '$250k is 25% of $1M';
const expected = '\\$250k is 25% of \\$1M';
expect(preprocessLaTeX(content)).toBe(expected);
});
test('handles various abbreviated currency formats', () => {
const content = 'Revenue: $5M to $10M, funding: $1.5B, price: $5K';
const expected = 'Revenue: \\$5M to \\$10M, funding: \\$1.5B, price: \\$5K';
expect(preprocessLaTeX(content)).toBe(expected);
});
});
|