34 lines
2.5 KiB
TypeScript
34 lines
2.5 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
import type { DiagramPage } from "../../model/diagram-ir.js";
|
|
import { validateDiagramIR } from "../../model/diagram-ir.js";
|
|
import { createBuildup } from "./buildup.js";
|
|
|
|
const PAGE: DiagramPage = { id: "deploy", title: "Deploy", nodes: [{ id: "db", label: "DB", provenance: { source: "infra" } }, { id: "api", label: "API" }, { id: "web", label: "Web" }], edges: [{ id: "db-api", source: "db", target: "api" }, { id: "api-web", source: "api", target: "web" }] };
|
|
|
|
test("buildup uses deterministic topological order and valid cumulative IR frames", () => {
|
|
const before = structuredClone(PAGE); const result = createBuildup(PAGE);
|
|
assert.deepEqual(result, createBuildup(PAGE)); assert.deepEqual(PAGE, before); assert.deepEqual(result.order, ["db", "api", "web"]); assert.deepEqual(result.cycleFallback, []);
|
|
result.frames.forEach((frame) => assert.equal(validateDiagramIR(frame), frame));
|
|
assert.deepEqual(result.frames.map((frame) => frame.pages[0].nodes.map((node) => node.id)), [["db"], ["db", "api"], ["db", "api", "web"]]);
|
|
assert.equal(result.frames[0].pages[0].nodes[0].provenance?.source, "infra");
|
|
});
|
|
|
|
test("buildup explicitly falls back to stable ID order for cycles", () => {
|
|
const cyclic: DiagramPage = { id: "cycle", title: "Cycle", nodes: [{ id: "b", label: "B" }, { id: "a", label: "A" }], edges: [{ id: "ab", source: "a", target: "b" }, { id: "ba", source: "b", target: "a" }] };
|
|
const result = createBuildup(cyclic); assert.deepEqual(result.order, ["a", "b"]); assert.deepEqual(result.cycleFallback, ["a", "b"]);
|
|
result.frames.forEach((frame) => assert.equal(validateDiagramIR(frame), frame));
|
|
});
|
|
|
|
test("buildup cycle fallback keeps containers before children so every frame remains valid", () => {
|
|
const cyclic: DiagramPage = { id: "nested", title: "Nested", nodes: [{ id: "a-child", label: "Child", parentId: "z-parent" }, { id: "z-parent", label: "Parent", kind: "container" }], edges: [{ id: "reverse", source: "a-child", target: "z-parent" }] };
|
|
const result = createBuildup(cyclic);
|
|
assert.deepEqual(result.order, ["z-parent", "a-child"]);
|
|
result.frames.forEach((frame) => assert.equal(validateDiagramIR(frame), frame));
|
|
});
|
|
|
|
test("buildup rejects empty and invalid input", () => {
|
|
assert.throws(() => createBuildup({ id: "empty", title: "Empty", nodes: [], edges: [] }), /non-empty/i);
|
|
assert.throws(() => createBuildup({ id: "bad", title: "Bad", nodes: [{ id: "a", label: "A" }], edges: [{ id: "e", source: "x", target: "a" }] }), /unknown source/i);
|
|
});
|