import { describe, expect, it } from "vitest"; import { extractMarkdownImageSources, MarkdownDocumentParseError, renderMarkdown } from "../src/render-markdown.js"; describe("renderMarkdown", () => { it("渲染常用 Markdown 扩展并识别能力", () => { const result = renderMarkdown(` # 示例文档 | 名称 | 状态 | | --- | --- | | PDF | 可用 | - [x] 已完成 - [ ] 待处理 \`\`\`ts const answer = 42; \`\`\` 脚注引用[^note]。 [^note]: 脚注正文。 `); expect(result.articleHtml).toContain('id="write"'); expect(result.bodyHtml).toContain("
| 左对齐 | '); expect(result.bodyHtml).toContain('居中 | '); expect(result.bodyHtml).toContain('右对齐 | '); expect(result.bodyHtml).toContain('A | '); expect(result.bodyHtml).toContain('B | '); expect(result.bodyHtml).toContain('C | '); }); it("读取并规范化 Front Matter 元数据", () => { const result = renderMarkdown(`--- title: 项目报告 author: 张三 subject: 技术方案 keywords: - Markdown - PDF lang: zh-CN --- # 不作为标题 `); expect(result.metadata).toEqual({ title: "项目报告", author: "张三", subject: "技术方案", keywords: ["Markdown", "PDF"], language: "zh-CN" }); }); it("使用稳定错误类型报告无效 Front Matter", () => { expect(() => renderMarkdown(`--- title: [未闭合 --- # 文档 `) ).toThrow(MarkdownDocumentParseError); }); it("服务端渲染公式并保留 Mermaid 安全占位", () => { const result = renderMarkdown(` 内联公式 $E=mc^2$。 \`\`\`mermaid flowchart LR A[开始] --> B[结束] \`\`\` `); expect(result.bodyHtml).toContain("katex"); expect(result.bodyHtml).toContain('class="mermaid"'); expect(result.bodyHtml).toContain("data-mermaid-pending"); expect(result.features).toEqual( expect.arrayContaining(["katex", "mermaid"]) ); }); it("完整保留 Mermaid 区块内的 config frontmatter", () => { const result = renderMarkdown(` \`\`\`mermaid --- title: Frontmatter 示例 config: layout: elk theme: forest look: handDrawn fontFamily: Microsoft YaHei themeVariables: primaryColor: "#dbeafe" flowchart: curve: basis --- flowchart LR classDef important fill:#fee2e2,stroke:#dc2626 A[开始] --> B[结束] style A fill:#dcfce7,stroke:#16a34a class B important \`\`\` `); expect(result.bodyHtml).toContain("title: Frontmatter 示例"); expect(result.bodyHtml).toContain("layout: elk"); expect(result.bodyHtml).toContain("theme: forest"); expect(result.bodyHtml).toContain("look: handDrawn"); expect(result.bodyHtml).toContain("fontFamily: Microsoft YaHei"); expect(result.bodyHtml).toContain("primaryColor:"); expect(result.bodyHtml).toContain("curve: basis"); expect(result.bodyHtml).toContain("flowchart LR"); expect(result.bodyHtml).toContain("classDef important"); expect(result.bodyHtml).toContain("style A fill:"); expect(result.bodyHtml).toContain("class B important"); }); it("将 ECharts YAML 围栏转换为安全占位并识别能力", () => { const result = renderMarkdown(` \`\`\`echarts version: 1 height: 80mm caption: 年度收入 option: xAxis: type: category data: [2023, 2024] yAxis: type: value series: - type: bar data: [120, 180] \`\`\` `); expect(result.bodyHtml).toContain('class="md-echarts"'); expect(result.bodyHtml).toContain( 'data-echarts-pending="true"' ); expect(result.bodyHtml).toContain( 'data-echarts-protocol="1"' ); expect(result.bodyHtml).toContain( 'class="md-echarts-definition" hidden="hidden"' ); expect(result.bodyHtml).toContain( "
|---|