import { jest } from '@jest/globals'; import { readFileSync } from 'node:fs'; jest.unstable_mockModule('../../src/appEngine', () => ({ appEngine: { interpreter: {} } })); describe('application educational Markdown integration', () => { test.each([ ['pt', 'Seção'], ['en', 'Section'], ['es', 'Sección'], ])('renders explicit heading anchors and localized references in %s', async (locale, section) => { const { Markdown } = await import('../../src/Markdown'); const container = document.createElement('div'); const diagnostics: unknown[] = []; const session = await Markdown.renderDocument('## 2.3 Logic {#logic}\n\n{@ref logic}\n\n## Notes {#notes}\n\n{@ref notes}', container, { locale, onDiagnostic: (diagnostic) => diagnostics.push(diagnostic), }); expect(diagnostics).toEqual([]); expect(container.querySelector('h2#logic')?.textContent).toBe('2.3 Logic'); expect(container.querySelector('[data-markdown-reference] a')?.textContent).toBe(`${section} 2.3`); expect(container.querySelector('[data-markdown-reference] a')?.getAttribute('href')).toBe('#logic'); expect(container.querySelectorAll('[data-markdown-reference] a')[1]?.textContent).toBe('Notes'); await session.dispose(); }); test('registers all educational syntax without importing optional renderer libraries', async () => { const { Markdown } = await import('../../src/Markdown'); const source = ':::: theorem Claim {#claim}\n\nText.\n\n::: solution\n\nAnswer.\n\n:::\n\n::::\n\n{@ref claim} [@source]\n\n' + ['wavedrom', 'geometry', 'tikz', 'circuitikz', 'bibtex', 'csl-json', 'bibliography', 'netlist', 'vcd'] .map((language) => '\x60\x60\x60' + language + '\n{}\n\x60\x60\x60') .join('\n\n'); const container = document.createElement('div'); container.innerHTML = Markdown.parse(source); expect(container.querySelector('[data-markdown-block="theorem"]')).not.toBeNull(); expect(container.querySelector('details[data-markdown-block="solution"]')).not.toBeNull(); expect(container.querySelector('[data-markdown-reference]')).not.toBeNull(); expect(container.querySelector('[data-markdown-citation]')).not.toBeNull(); for (const language of ['wavedrom', 'geometry', 'tikz', 'circuitikz', 'bibtex', 'csl-json', 'bibliography', 'netlist', 'vcd']) expect(container.querySelector('[data-markdown-language="' + language + '"]')).not.toBeNull(); }); test('highlights HDL source and diagnoses executable fences without an executor', async () => { const { Markdown } = await import('../../src/Markdown'); for (const [language, code] of [ ['vhdl', 'entity gate is end entity;'], ['verilog', 'module gate(input a, output y); assign y = a; endmodule'], ['systemverilog', 'module gate(input logic a, output logic y); assign y = a; endmodule'], ]) { const container = document.createElement('div'); container.innerHTML = Markdown.parse(`\x60\x60\x60${language}\n${code}\n\x60\x60\x60`); expect(container.querySelector('code .hljs-keyword')).not.toBeNull(); } const container = document.createElement('div'); const session = await Markdown.renderDocument('```vhdl-run\n{}\n```\n\n```verilog-live\n{}\n```', container); expect(container.querySelectorAll('[role="alert"]')).toHaveLength(2); expect(container.querySelector('[data-hdl-action]')).toBeNull(); await session.dispose(); }); test.each(['pt', 'en', 'es'])('renders the unchanged %s lesson with nested blocks and links', async (locale) => { const { Markdown } = await import('../../src/Markdown'); const source = readFileSync(new URL('../fixtures/markdown/educational/' + locale + '/blocos-didaticos.md', import.meta.url), 'utf8'); const container = document.createElement('div'); const diagnostics: unknown[] = []; const session = await Markdown.renderDocument(source, container, { locale, onDiagnostic: (diagnostic) => diagnostics.push(diagnostic) }); expect(diagnostics).toEqual([]); expect(container.querySelectorAll('[data-markdown-block]')).toHaveLength(5); expect(container.querySelectorAll('[data-markdown-reference] a')).toHaveLength(4); expect(container.querySelector('details')?.hasAttribute('open')).toBe(false); await session.dispose(); }); });