import pako from "pako" import { describe, expect, it } from "vitest" import { countCells, diffDiagrams, inflatePages, isEmptySummary, isSameDocument, } from "@/lib/diagram-diff" const doc = (cells: string) => `${cells}` const box = (id: string, value = id) => `` const edge = (id: string, source: string, target: string) => `` describe("diffDiagrams", () => { it("counts added shapes and connectors on an empty canvas", () => { const { summary, touchedIds } = diffDiagrams( "", doc(box("a") + box("b") + edge("e", "a", "b")), ) expect(summary.shapesAdded).toBe(2) expect(summary.edgesAdded).toBe(1) expect(touchedIds.sort()).toEqual(["a", "b", "e"]) }) it("separates added, changed and removed cells", () => { const before = doc(box("a") + box("b") + edge("e", "a", "b")) const after = doc(box("a", "renamed") + box("c") + edge("e", "a", "c")) const { summary, touchedIds } = diffDiagrams(before, after) expect(summary).toEqual({ shapesAdded: 1, shapesRemoved: 1, shapesChanged: 1, edgesAdded: 0, edgesRemoved: 0, edgesChanged: 1, }) expect(touchedIds.sort()).toEqual(["a", "c", "e"]) }) it("ignores how the same cell is written", () => { // As the model writes it, and as draw.io saves it const model = `` const saved = `` expect(isEmptySummary(diffDiagrams(model, saved).summary)).toBe(true) }) it("reports nothing for identical diagrams", () => { const xml = doc(box("a")) const { summary, touchedIds } = diffDiagrams(xml, xml) expect(isEmptySummary(summary)).toBe(true) expect(touchedIds).toEqual([]) }) it("reads the id from wrappers", () => { const wrapped = `` const { summary, touchedIds } = diffDiagrams(doc(""), doc(wrapped)) expect(summary.shapesAdded).toBe(1) expect(touchedIds).toEqual(["u1"]) }) it("only looks at the first page", () => { const twoPages = `${box("a")}${box("z")}` expect(countCells(twoPages)).toEqual({ shapes: 1, edges: 0 }) }) it("reads compressed pages", () => { const model = `${box("a")}${box("b")}` const compressed = btoa( String.fromCharCode(...pako.deflateRaw(encodeURIComponent(model))), ) const xml = `${compressed}` expect(countCells(xml)).toEqual({ shapes: 2, edges: 0 }) }) it("treats unparsable XML as empty", () => { expect(countCells("")).toEqual({ shapes: 0, edges: 0 }) }) }) const pageOf = (name: string, cells: string, attrs = "") => `${cells}` const file = (...pages: string[]) => `${pages.join("")}` const packedPage = (name: string, cells: string) => { const model = `${cells}` const packed = Buffer.from( pako.deflateRaw(encodeURIComponent(model)), ).toString("base64") return `${packed}` } describe("isSameDocument", () => { const a = file(pageOf("One", box("a")), pageOf("Two", box("b"))) it("is true for the same pages written differently", () => { const b = file( pageOf("One", box("a"), ' dx="300" dy="120" grid="1"'), packedPage("Two", box("b")), ) expect(isSameDocument(a, b)).toBe(true) }) it("sees a change on the second page", () => { const b = file(pageOf("One", box("a")), pageOf("Two", box("b", "x"))) expect(diffDiagrams(a, b).summary).toEqual(diffDiagrams(a, a).summary) expect(isSameDocument(a, b)).toBe(false) }) it("sees added pages, renamed pages and changed page settings", () => { expect(isSameDocument(a, file(pageOf("One", box("a"))))).toBe(false) expect( isSameDocument( a, file(pageOf("One", box("a")), pageOf("Renamed", box("b"))), ), ).toBe(false) expect( isSameDocument( file(pageOf("One", box("a"), ' background="#ffffff"')), file(pageOf("One", box("a"), ' background="#000000"')), ), ).toBe(false) }) }) describe("inflatePages", () => { it("inflates compressed pages in place", () => { const xml = file(pageOf("One", box("a")), packedPage("Two", box("b"))) const inflated = inflatePages(xml) expect(inflated).toContain(' { const xml = file(pageOf("One", box("a"))) expect(inflatePages(xml)).toBe(xml) expect(inflatePages("not xml <")).toBe("not xml <") }) })