import { test } from 'node:test'; import assert from 'node:assert/strict'; import { Descendant } from 'slate'; import { toMatrixCustomHTML } from './output'; import { BlockType } from './types'; // Loose Slate node builders for the test. const txt = (text: string, marks: Record = {}) => ({ text, ...marks }) as unknown as Descendant; const el = (type: BlockType, children: unknown[]) => ({ type, children }) as unknown as Descendant; const OPTS = { allowTextFormatting: true, allowInlineMarkdown: false, allowBlockMarkdown: false, allowMath: true, }; test('inline $…$ → data-mx-maths span, surrounding prose preserved', () => { assert.equal( toMatrixCustomHTML(txt('a $x^2$ b'), OPTS), 'a x^2 b', ); }); test('single-line block $$…$$ → data-mx-maths div', () => { assert.equal( toMatrixCustomHTML(txt('$$E=mc^2$$'), OPTS), '
E=mc^2
', ); }); test('LaTeX special chars are escaped in attribute + fallback', () => { assert.equal( toMatrixCustomHTML(txt('$aa<b', ); }); test('math bypasses markdown — underscores are not italicised', () => { // Without pre-markdown extraction, `_` would become . assert.equal( toMatrixCustomHTML(txt('$a_b$'), { ...OPTS, allowInlineMarkdown: true }), 'a_b', ); }); test('currency ($5 and $10) stays literal', () => { assert.equal(toMatrixCustomHTML(txt('$5 and $10'), OPTS), '$5 and $10'); }); test('no math conversion inside an inline code mark', () => { const out = toMatrixCustomHTML(txt('$x$', { code: true }), OPTS); assert.ok(!out.includes('data-mx-maths')); assert.ok(out.includes('$x$')); }); test('no math conversion inside a code block', () => { const block = el(BlockType.CodeBlock, [el(BlockType.CodeLine, [txt('$x$')])]); const out = toMatrixCustomHTML(block, OPTS); assert.ok(!out.includes('data-mx-maths')); assert.ok(out.includes('$x$')); }); test('a message with no math is unchanged', () => { assert.equal(toMatrixCustomHTML(txt('just hello'), OPTS), 'just hello'); });