import { describe, expect, it } from "vitest" import { applyDiagramOperations, autoFixXml, cn, extractCompleteMxCells, isMxCellXmlComplete, validateAndFixXml, validateMxCellStructure, wrapWithMxFile, } from "@/lib/utils" 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) }) 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("wrapWithMxFile", () => { it("wraps empty string with default structure", () => { const result = wrapWithMxFile("") expect(result).toContain("") expect(result).toContain("") expect(result).toContain('') expect(result).toContain('') }) it("wraps raw mxCell content", () => { const xml = '' const result = wrapWithMxFile(xml) expect(result).toContain("") expect(result).toContain(xml) expect(result).toContain("") }) it("returns full mxfile unchanged", () => { const fullXml = '' const result = wrapWithMxFile(fullXml) expect(result).toBe(fullXml) }) it("handles whitespace in input", () => { const result = wrapWithMxFile(" ") expect(result).toContain("") }) }) 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 page = (id: string, cells: string) => `${cells}` describe("duplicate ids in multi-page documents", () => { const shape = (id: string, value = "Box") => `` it("accepts the same ids on different pages", () => { const xml = `${page("p1", shape("2"))}${page("p2", shape("2"))}` expect(validateMxCellStructure(xml)).toBeNull() }) it("still reports duplicate ids within one page", () => { const xml = `${page("p1", shape("2") + shape("2"))}${page("p2", "")}` expect(validateMxCellStructure(xml)).toContain("duplicate ID") }) it("does not rename the root cells of other pages when fixing", () => { const xml = `${page("p1", shape("2", "R&D"))}${page("p2", shape("3"))}` const result = validateAndFixXml(xml) expect(result.valid).toBe(true) expect(result.fixed).not.toContain("_dup") expect(result.fixed).toContain("R&D") }) it("renames a duplicate id within a page", () => { const xml = `${page("p1", shape("d") + shape("d"))}` const { fixed } = autoFixXml(xml) expect(fixed).toContain(' { it("does not insert a space at the start of style values", () => { const xml = `` const { fixed } = autoFixXml(xml) expect(fixed).toContain('style="rounded=1;whiteSpace=wrap;"') }) it("adds a missing space between attributes", () => { const xml = `` expect(autoFixXml(xml).fixed).toContain('vertex="1" parent="1"') }) it("keeps " inside rich text labels", () => { const label = "<font color="#ff0000">Hello</font>" const xml = `` const result = validateAndFixXml(xml) expect(result.valid).toBe(true) expect(result.fixed).toContain(`value="${label}"`) }) it("fixes an attribute delimited by "", () => { const xml = `` expect(autoFixXml(xml).fixed).toContain('dashPattern="1 1;"') }) it("keeps cells written on one line next to multi-line cells", () => { const xml = ` ` const result = validateAndFixXml(xml) expect(result.valid).toBe(true) for (const id of ["2", "e1", "3"]) { expect(result.fixed).toContain(` { const xml = `` const result = validateAndFixXml(xml) expect(result.valid).toBe(true) expect(result.fixed).toContain(' { const xml = `` it("deletes a wrapped cell and its edges", () => { const { result, errors } = applyDiagramOperations(xml, [ { operation: "delete", cell_id: "5" }, { operation: "delete", cell_id: "e1" }, ]) expect(errors).toEqual([]) expect(result).not.toContain("UserObject") expect(result).not.toContain('id="e1"') expect(result).toContain('id="6"') }) it("rejects adding a cell with the id of a wrapped cell", () => { const { errors } = applyDiagramOperations(xml, [ { operation: "add", cell_id: "5", new_xml: '', }, ]) expect(errors[0]?.message).toContain("already exists") }) it("updates a wrapped cell", () => { const { result, errors } = applyDiagramOperations(xml, [ { operation: "update", cell_id: "5", new_xml: '', }, ]) expect(errors).toEqual([]) expect(result).toContain('label="New"') expect(result).not.toContain('label="Docs"') }) it("reports deleting a cell that does not exist", () => { const { errors } = applyDiagramOperations(xml, [ { operation: "delete", cell_id: "missing" }, ]) expect(errors[0]?.message).toContain("not found") }) })