/** * Unit tests for the diagram pre-pass: fence extraction, info-string parsing, * slot substitution, diagnostic blocks, image inlining policy, and the * byte-level image dimension prober. No browse daemon required — the tab * factory returns null so downscale paths are exercised as no-ops. */ import { afterAll, describe, expect, test } from "bun:test"; import * as fs from "node:fs"; import * as os from "node:os"; import * as path from "node:path"; import zlib from "node:zlib"; import { StrictModeError, buildDiagnosticBlock, buildDiagramFigure, contentWidthInches, dimToInches, extractDiagramFences, inlineLocalImages, parseInfoString, substituteSlots, decodeFigureSource, } from "../src/diagram-prepass"; import { imageDims } from "../src/image-size"; // ─── fence extraction ───────────────────────────────────────────────── describe("extractDiagramFences", () => { test("extracts a mermaid fence and replaces it with a token paragraph", () => { const md = "# T\n\n```mermaid\ngraph LR\n A --> B\n```\n\ntail"; const { markdown, fences } = extractDiagramFences(md); expect(fences).toHaveLength(1); expect(fences[0].lang).toBe("mermaid"); expect(fences[0].source).toBe("graph LR\n A --> B"); expect(markdown).toContain(fences[0].token); expect(markdown).not.toContain("```mermaid"); }); test("extracts excalidraw fences", () => { const md = '```excalidraw\n{"type":"excalidraw","elements":[]}\n```'; const { fences } = extractDiagramFences(md); expect(fences).toHaveLength(1); expect(fences[0].lang).toBe("excalidraw"); }); test("render=false keeps the fence as code and strips the flag", () => { const md = "```mermaid render=false\ngraph LR\n X --> Y\n```"; const { markdown, fences } = extractDiagramFences(md); expect(fences).toHaveLength(0); expect(markdown).toContain("```mermaid\ngraph LR"); expect(markdown).not.toContain("render=false"); }); test("title is captured from the info string", () => { const md = '```mermaid title="Auth flow"\ngraph LR\n A --> B\n```'; const { fences } = extractDiagramFences(md); expect(fences[0].title).toBe("Auth flow"); }); test("non-diagram fences pass through untouched", () => { const md = "```js\nconst a = 1;\n```"; const { markdown, fences } = extractDiagramFences(md); expect(fences).toHaveLength(0); expect(markdown).toBe(md); }); test("a mermaid example inside a plain fence is never extracted", () => { const md = "````\n```mermaid\ngraph LR\n```\n````"; const { markdown, fences } = extractDiagramFences(md); expect(fences).toHaveLength(0); expect(markdown).toBe(md); }); test("tilde fences work", () => { const md = "~~~mermaid\ngraph TD\n A --> B\n~~~"; const { fences } = extractDiagramFences(md); expect(fences).toHaveLength(1); }); test("unclosed fence at EOF replays verbatim", () => { const md = "```mermaid\ngraph LR\n A --> B"; const { markdown, fences } = extractDiagramFences(md); expect(fences).toHaveLength(0); expect(markdown).toBe(md); }); test("multiple fences get distinct ordinals and tokens", () => { const md = "```mermaid\nA\n```\n\nmiddle\n\n```mermaid\nB\n```"; const { fences } = extractDiagramFences(md); expect(fences).toHaveLength(2); expect(fences[0].ordinal).toBe(1); expect(fences[1].ordinal).toBe(2); expect(fences[0].token).not.toBe(fences[1].token); }); }); describe("parseInfoString", () => { test("plain language", () => { expect(parseInfoString("mermaid")).toEqual({ lang: "mermaid", render: true, title: undefined }); }); test("render=false", () => { expect(parseInfoString("mermaid render=false").render).toBe(false); }); test("single-quoted title", () => { expect(parseInfoString("mermaid title='Hi there'").title).toBe("Hi there"); }); }); // ─── slots ──────────────────────────────────────────────────────────── describe("substituteSlots", () => { test("replaces the

-wrapped token with slot HTML", () => { const slots = new Map([["gstack-diagram-slot-ab-1", "

X
"]]); const html = "

T

\n

gstack-diagram-slot-ab-1

\n

tail

"; const out = substituteSlots(html, slots); expect(out).toContain("
X
"); expect(out).not.toContain("gstack-diagram-slot"); expect(out).not.toContain("

"); }); }); describe("diagnostic + figure blocks", () => { const fence = { lang: "mermaid", source: "graph LR\n A --> B", render: true, token: "t", ordinal: 3, title: undefined, }; test("diagnostic block escapes error content and names the lang", () => { const block = buildDiagnosticBlock(fence, 'Parse "quoted"'); expect(block).toContain("diagram-error"); expect(block).toContain("Diagram failed to render (mermaid)"); expect(block).toContain("Parse <error>"); expect(block).not.toContain(""); }); test("figure carries role=img and ordinal-based aria-label fallback", () => { const fig = buildDiagramFigure(fence, ""); expect(fig).toContain('role="img"'); expect(fig).toContain('aria-label="diagram 3"'); expect(fig).toContain(""); }); test("figure strips scripts from SVG (sanitizer second layer)", () => { const fig = buildDiagramFigure(fence, ""); expect(fig).not.toContain("