import assert from "node:assert/strict"; import test from "node:test"; import type { DiagramIRV2 } from "../../model/diagram-ir.js"; import { relabelDiagram } from "./relabel.js"; const IR: DiagramIRV2 = { version: 2, title: "Original", pages: [{ id: "p", title: "Page", layout: { type: "manual" }, nodes: [ { id: "a", label: "A", style: "shape=hexagon;", geometry: { x: 10, y: 20, width: 100, height: 60 } }, { id: "b", label: "B", style: "shape=ellipse;", geometry: { x: 200, y: 20, width: 100, height: 60 } }, ], edges: [{ id: "flow", source: "a", target: "b", label: "old", style: "dashed=1;", waypoints: [{ x: 150, y: 50 }] }] }], }; test("complete relabel changes only labels while preserving IDs, topology, layout, and style", () => { const snapshot = structuredClone(IR); const result = relabelDiagram(IR, { mode: "complete", labels: { "p/a": "Alpha", "p/b": "Beta", "p/flow": "new" } }); assert.deepEqual(result.pages[0].nodes.map(({ id, label }) => ({ id, label })), [{ id: "a", label: "Alpha" }, { id: "b", label: "Beta" }]); assert.equal(result.pages[0].edges[0].label, "new"); const restored = structuredClone(result); restored.pages[0].nodes[0].label = "A"; restored.pages[0].nodes[1].label = "B"; restored.pages[0].edges[0].label = "old"; assert.deepEqual(restored, IR); assert.deepEqual(IR, snapshot); }); test("relabel requires a complete exact explicit map", () => { assert.throws(() => relabelDiagram(IR, { mode: "complete", labels: { "p/a": "Alpha" } }), /missing.*p\/b.*p\/flow/i); assert.throws(() => relabelDiagram(IR, { mode: "complete", labels: { "p/a": "Alpha", "p/b": "Beta", "p/flow": "new", extra: "no" } }), /unknown.*extra/i); assert.throws(() => relabelDiagram(IR, { mode: "complete", labels: { "p/a": "", "p/b": "Beta", "p/flow": "new" } }), /non-empty/i); });