23 lines
1.8 KiB
TypeScript
23 lines
1.8 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
import type { DiagramIRV2 } from "../../model/diagram-ir.js";
|
|
import { validateDiagramIR } from "../../model/diagram-ir.js";
|
|
import { createArchitectureTimelapse } from "./timelapse.js";
|
|
|
|
const one: DiagramIRV2 = { version: 2, title: "Arch", pages: [{ id: "p", title: "P", nodes: [{ id: "a", label: "A", provenance: { source: "model" } }, { id: "b", label: "B" }], edges: [{ id: "ab", source: "a", target: "b" }] }] };
|
|
const two: DiagramIRV2 = { version: 2, title: "Arch", pages: [{ id: "p", title: "P", nodes: [{ id: "a", label: "A2", provenance: { source: "model" } }, { id: "c", label: "C" }], edges: [{ id: "ac", source: "a", target: "c" }] }] };
|
|
|
|
test("timelapse emits valid immutable frames with stable change classifications", () => {
|
|
const input = [{ id: "v1", label: "Before", ir: one }, { id: "v2", label: "After", ir: two }]; const before = structuredClone(input);
|
|
const result = createArchitectureTimelapse(input); assert.deepEqual(result, createArchitectureTimelapse(input)); assert.deepEqual(input, before);
|
|
result.frames.forEach((frame) => assert.equal(validateDiagramIR(frame.ir), frame.ir));
|
|
assert.deepEqual(result.frames[1].changes.nodes, { added: ["p/c"], removed: ["p/b"], modified: ["p/a"], unchanged: [] });
|
|
assert.deepEqual(result.frames[1].changes.edges, { added: ["p/ac"], removed: ["p/ab"], modified: [], unchanged: [] });
|
|
assert.equal(result.frames[1].ir.pages[0].nodes[0].provenance?.source, "model");
|
|
});
|
|
|
|
test("timelapse rejects empty and invalid snapshots", () => {
|
|
assert.throws(() => createArchitectureTimelapse([]), /snapshot/i);
|
|
assert.throws(() => createArchitectureTimelapse([{ id: "bad", label: "Bad", ir: { version: 2, pages: [] } as DiagramIRV2 }]), /non-empty/i);
|
|
});
|