import { describe, expect, it } from "vitest"
import {
applyDiagramOperations,
cn,
extractCompleteMxCells,
isMxCellXmlComplete,
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(
'',
)
})
})
describe("applyDiagramOperations with wrapped cells", () => {
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")
})
})