Files
ycode/scripts/math-renderer-regression.tsx
T

47 lines
3.0 KiB
TypeScript

import assert from 'node:assert/strict'
import { renderToStaticMarkup } from 'react-dom/server'
import MarkdownContent from '../src/renderer/src/components/MarkdownContent'
import { loadMathModules, renderLatexFence } from '../src/renderer/src/workbuddy/markdown/math'
async function main(): Promise<void> {
assert.ok(await loadMathModules(), 'math renderer must load')
const render = (content: string, streaming = false): string => renderToStaticMarkup(<MarkdownContent content={content} streaming={streaming} />)
const inline = render('Inline $x^2$ equation.')
assert.match(inline, /class="cr-math-inline"/)
assert.match(inline, /class="katex"/)
assert.doesNotMatch(inline, /katex-error/)
const block = render('$$\nx^2 + y^2 = z^2\n$$')
assert.match(block, /cr-math-block__body/)
assert.match(block, /katex-display/)
assert.match(render('\\[ x^2 \\]'), /cr-math-block/)
assert.match(render('\\(x^2\\)'), /cr-math-inline/)
for (const macro of ['RR', 'NN', 'ZZ', 'QQ', 'CC']) {
const html = render(`$\\${macro}$`)
assert.match(html, /class="katex"/)
assert.doesNotMatch(html, /katex-error/)
}
assert.match(render('```latex\n\\frac{1}{2}\n```'), /cr-math-block/)
assert.doesNotMatch(render('```latex\n\\frac{1}{2}\n```'), /cr-code-like-box/)
assert.equal(renderLatexFence('\\documentclass{article}\n\\begin{document}hi\\end{document}'), null)
assert.equal(renderLatexFence('\\notARealCommand{'), null)
assert.match(render('```latex\n\\documentclass{article}\n```'), /cr-code-like-box/)
assert.match(render('```latex\n\\notARealCommand{\n```'), /cr-code-like-box/)
const unsafe = render('$\\href{javascript:alert(1)}{click}$')
assert.doesNotMatch(unsafe, /href="javascript:/)
assert.doesNotMatch(render('before<script>window.bad = true</script>after'), /<script|window\.bad/)
assert.match(render('Waiting $x +', true), /markdown-content__loading-char/)
const table = '| a | b |\n| - | - |\n| 1 | 2 |'
const tableWithAction = (streaming: boolean): string => renderToStaticMarkup(<MarkdownContent content={table} messageId="fixture-message" sourceId="fixture-message-text-0" streaming={streaming} onQuote={() => undefined} />)
assert.match(tableWithAction(true), /class="cr-message-quote-table-action" disabled=""[^>]*aria-label="添加到对话"/)
assert.match(tableWithAction(false), /class="cr-message-quote-table-action"[^>]*aria-label="添加到对话">/)
assert.doesNotMatch(tableWithAction(false), /class="cr-message-quote-table-action" disabled/)
assert.match(tableWithAction(false), /data-message-quote-source-id="fixture-message-text-0:table:table-0"/)
const opacity = render('abcdef', true)
assert.match(opacity, /style="opacity:0\.6/)
assert.match(opacity, /style="opacity:0\.1/)
const trailingFence = render('Previous paragraph.\n\n```js\nconst x = 1', true)
assert.doesNotMatch(trailingFence, /markdown-content__loading-char/)
console.log('math-renderer-regression: math, fallback, safety, table state and opacity checks passed')
}
void main().catch((error) => { console.error(error); process.exitCode = 1 })