import { describe, expect, it } from "vitest" import { expandCompactCells, foldCells, } from "@/packages/mcp-server/src/compact-cells.ts" import { editDiagram } from "@/packages/mcp-server/src/edit-diagram.ts" import { prepareNewDiagram } from "@/packages/mcp-server/src/new-diagram.ts" import { normalizeToMxfile, wrapCellsInModel, } from "@/packages/mcp-server/src/pages.ts" const shape = '' const shapeLong = '' const edge = '' const edgeLong = '' /** Cells compared by what they mean, not by attribute order */ function canonical(xml: string): string { const doc = new DOMParser().parseFromString( `${xml}`, "text/xml", ) const describe = (el: Element): string => { const attrs = Array.from(el.attributes) .map((a) => `${a.name}=${a.value}`) .sort() .join(" ") const children = Array.from(el.children).map(describe).join("") return `<${el.tagName} ${attrs}>${children}` } return Array.from(doc.documentElement.children).map(describe).join("\n") } describe("expandCompactCells", () => { it("gives a compact shape its flags, parent and geometry", () => { expect(expandCompactCells(shape)).toBe(shapeLong) }) it("gives a compact edge its flags, parent and relative geometry", () => { expect(expandCompactCells(edge)).toBe(edgeLong) }) it("keeps an explicit parent and accepts width/height as names", () => { const inLane = '' expect(expandCompactCells(inLane)).toBe( '', ) }) it("fills in a default position and size when some are missing", () => { expect(expandCompactCells('')).toBe( '', ) }) it("lets an explicit geometry win over compact attributes", () => { const both = '' expect(expandCompactCells(both)).toBe( shapeLong.replace(' value="Start" style="rounded=1;"', ""), ) }) it("adds the relative geometry to a long-form edge that has none", () => { const noGeometry = '' expect(expandCompactCells(noGeometry)).toBe(edgeLong) }) it("leaves root cells, long-form cells and edge labels alone", () => { const roots = '' const label = '' expect(expandCompactCells(roots + shapeLong + edgeLong + label)).toBe( roots + shapeLong + edgeLong + label, ) }) it("works on a cell inside a UserObject wrapper", () => { const wrapped = '' expect(expandCompactCells(wrapped)).toBe( '', ) }) }) describe("foldCells", () => { it("writes plain shapes and edges compactly", () => { expect(foldCells(shapeLong)).toBe(shape) expect(foldCells(edgeLong)).toBe(edge) }) it("keeps a parent other than 1 and leaves special cells as written", () => { const inLane = '' expect(foldCells(inLane)).toBe( '', ) const waypoints = '' const label = '' const sourcePoint = '' const roots = '' const wrongAs = '' for (const xml of [waypoints, label, sourcePoint, roots, wrongAs]) { expect(foldCells(xml)).toBe(xml) } }) it("round-trips through expandCompactCells", () => { const page = `${shapeLong}${edgeLong}` const folded = foldCells(page) expect(folded).not.toContain("vertex=") expect(canonical(expandCompactCells(folded))).toBe(canonical(page)) }) }) describe("compact cells through the pipeline", () => { const geometryOf = (xml: string, id: string) => xml.match( new RegExp(`]*>(]*/>)`), )?.[1] it("prepareNewDiagram expands them and still adds the defaults", () => { const prepared = prepareNewDiagram(`${shape}\n${edge}`) expect(prepared.ok).toBe(true) if (!prepared.ok) return expect(prepared.xml).toContain( 'style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1"', ) expect(geometryOf(prepared.xml, "2")).toBe( '', ) expect(prepared.xml).toContain( '', ) }) it("editDiagram accepts a compact cell in new_xml", () => { const file = normalizeToMxfile(wrapCellsInModel(shapeLong), { pageId: "p1", pageName: "Page-1", }) ?? "" const outcome = editDiagram( file, [ { operation: "add", cell_id: "3", new_xml: '', }, { operation: "update", cell_id: "2", new_xml: '', }, ], {}, ) expect(outcome.ok).toBe(true) if (!outcome.ok) return expect(outcome.xml).toContain('value="Next"') expect(outcome.xml).toContain('value="Begin"') expect(geometryOf(outcome.xml, "3")).toBe( '', ) }) }) describe("a compact cell with a slip", () => { it("repairs a missing closing quote before the slash", () => { const prepared = prepareNewDiagram( '', ) }) })