import pako from "pako" import { describe, expect, it } from "vitest" import { cn, extractCompleteMxCells, extractDiagramXML, isMxCellXmlComplete, isRealDiagram, replaceNodes, } from "@/lib/utils" import { BLANK_MXFILE } from "@/packages/mcp-server/src/pages.ts" describe("isRealDiagram", () => { it("counts a small diagram with one shape", () => { // 234 characters: valid, shown, and saved with its chat const xml = '' expect(xml.length).toBeLessThan(300) expect(isRealDiagram(xml)).toBe(true) }) it("does not count a blank page or nothing", () => { expect(isRealDiagram(BLANK_MXFILE)).toBe(false) expect(isRealDiagram("")).toBe(false) expect(isRealDiagram(null)).toBe(false) }) it("still counts a longer document of empty named pages", () => { // Pages and page settings are worth keeping, as before const pages = Array.from( { length: 3 }, (_, i) => ``, ).join("") expect(isRealDiagram(`${pages}`)).toBe(true) }) }) describe("isMxCellXmlComplete", () => { it("returns false for empty/null input", () => { expect(isMxCellXmlComplete("")).toBe(false) expect(isMxCellXmlComplete(null)).toBe(false) expect(isMxCellXmlComplete(undefined)).toBe(false) }) it("returns true for self-closing mxCell", () => { const xml = '' expect(isMxCellXmlComplete(xml)).toBe(true) // A raw "<" in a value (escaped later by the auto-fix) expect( isMxCellXmlComplete( '', ), ).toBe(true) }) it("returns true for mxCell with closing tag", () => { const xml = ` ` expect(isMxCellXmlComplete(xml)).toBe(true) }) it("returns false for truncated mxCell", () => { const xml = ' { const xml = ` { const xml = ` ` expect(isMxCellXmlComplete(xml)).toBe(false) }) it("returns false when output stops after of an open mxCell", () => { const xml = ` ` expect(isMxCellXmlComplete(xml)).toBe(false) }) it("returns true for a self-closing last mxCell with > in its value", () => { const xml = ` ` expect(isMxCellXmlComplete(xml)).toBe(true) }) it("returns true for multiple complete mxCells", () => { const xml = ` ` expect(isMxCellXmlComplete(xml)).toBe(true) }) }) describe("cn (class name utility)", () => { it("merges class names", () => { expect(cn("foo", "bar")).toBe("foo bar") }) it("handles conditional classes", () => { expect(cn("foo", false && "bar", "baz")).toBe("foo baz") }) it("merges tailwind classes correctly", () => { expect(cn("px-2", "px-4")).toBe("px-4") expect(cn("text-red-500", "text-blue-500")).toBe("text-blue-500") }) }) describe("extractCompleteMxCells", () => { it("keeps the cell right after self-closing root cells", () => { const xml = `` const ids = [ ...extractCompleteMxCells(xml).matchAll(/ m[1]) expect(ids).toEqual(["0", "1", "2", "3"]) }) it("drops an incomplete trailing cell", () => { const xml = `` expect(extractCompleteMxCells(xml)).toBe( '', ) }) }) const pageBox = (id: string) => `` const pageModel = (cells: string) => `${cells}` const pageOf = (id: string, cells: string) => `${pageModel(cells)}` /** Ids of the shapes on a page (not the root cells) */ const shapesOn = (xml: string, pageId: string) => Array.from( new DOMParser() .parseFromString(xml, "text/xml") .querySelectorAll(`diagram[id="${pageId}"] mxCell`), ) .map((cell) => cell.getAttribute("id")) .filter((id) => id !== "0" && id !== "1") describe("replaceNodes", () => { const two = `${pageOf("a", pageBox("A"))}${pageOf("b", pageBox("B"))}` it("replaces the first page's cells by default", () => { const out = replaceNodes(two, pageBox("N")) expect(shapesOn(out, "a")).toEqual(["N"]) expect(shapesOn(out, "b")).toEqual(["B"]) }) it("replaces the given page's cells and keeps the others", () => { const out = replaceNodes(two, pageBox("N"), "b") expect(shapesOn(out, "a")).toEqual(["A"]) expect(shapesOn(out, "b")).toEqual(["N"]) }) it("uses the first page when the given page is not there", () => { const out = replaceNodes(two, pageBox("N"), "zzz") expect(shapesOn(out, "a")).toEqual(["N"]) expect(shapesOn(out, "b")).toEqual(["B"]) }) }) describe("extractDiagramXML", () => { const packed = (model: string) => Buffer.from(pako.deflateRaw(encodeURIComponent(model))).toString( "base64", ) const file = `${packed(pageModel(pageBox("A")))}${packed(pageModel(pageBox("B")))}` const escapeAttr = (s: string) => s .replace(/&/g, "&") .replace(/"/g, """) .replace(//g, ">") const svg = `` const dataUrl = `data:image/svg+xml;base64,${Buffer.from(svg).toString("base64")}` it("returns the first page by default and a page by its id", () => { expect(extractDiagramXML(dataUrl)).toContain('id="A"') expect(extractDiagramXML(dataUrl, "b")).toContain('id="B"') expect(extractDiagramXML(dataUrl, "b")).not.toContain('id="A"') expect(extractDiagramXML(dataUrl, "zzz")).toContain('id="A"') }) })