import { describe, it, expect } from "vitest"; import { createLinearGraph, createDiamondGraph, createOperationGraph, createCallGraph, } from "@test/graph-factory.js"; import { createTestReactiveRoot, assertStatus, assertPreconditions, assertBlockedByFailure, } from "@test/reactive.js"; import { CompatibleInputSchema, CompatibleOutputSchema, NarrowOutputSchema, WideInputSchema, IncompatibleNumberOutputSchema, IncompatibleStringInputSchema, compatiblePairs, incompatiblePairs, unknownSchemas, } from "@test/schemas.js"; describe("test helpers smoke tests", () => { describe("graph-factory", () => { it("creates a linear graph", () => { const graph = createLinearGraph(["A", "B", "C"]); expect(graph.nodes()).toEqual(["A", "B", "C"]); expect(graph.edges()).toEqual(["A->B", "B->C"]); }); it("creates a diamond graph", () => { const graph = createDiamondGraph("top", "left", "right", "bottom"); expect(graph.nodes()).toEqual(["top", "left", "right", "bottom"]); expect(graph.edges()).toEqual([ "top->left", "top->right", "left->bottom", "right->bottom", ]); }); it("creates an operation graph", () => { const graph = createOperationGraph( [ { name: "classify", namespace: "task" }, { name: "enrich", namespace: "task" }, ], [{ source: "task.classify", target: "task.enrich" }], ); expect(graph.nodes()).toEqual(["task.classify", "task.enrich"]); expect(graph.edges()).toEqual(["task.classify->task.enrich"]); }); it("creates a call graph", () => { const graph = createCallGraph([ { requestId: "req1", operationId: "op1", status: "completed" }, { requestId: "req2", operationId: "op2", status: "running", parentRequestId: "req1", }, ]); expect(graph.nodes()).toEqual(["req1", "req2"]); expect(graph.edges()).toEqual(["req1->req2"]); }); }); describe("reactive", () => { it("creates reactive root with setup-transition-assert-dispose", () => { const graph = createDiamondGraph("A", "B", "C", "D"); const root = createTestReactiveRoot(graph); try { assertStatus(root, "A", "idle"); assertStatus(root, "B", "idle"); assertPreconditions(root, "A", true); assertPreconditions(root, "D", false); root.statusMap.get("A")!.value = "completed"; assertPreconditions(root, "B", true); assertPreconditions(root, "C", true); assertPreconditions(root, "D", false); root.statusMap.get("B")!.value = "completed"; root.statusMap.get("C")!.value = "completed"; assertPreconditions(root, "D", true); } finally { root.dispose(); } }); it("propagates failure to blockedByFailure", () => { const graph = createLinearGraph(["A", "B"]); const root = createTestReactiveRoot(graph); try { assertBlockedByFailure(root, "B", false); root.statusMap.get("A")!.value = "failed"; assertBlockedByFailure(root, "B", true); } finally { root.dispose(); } }); it("auto-aborts idle nodes when blockedByFailure fires", () => { const graph = createLinearGraph(["A", "B"]); const root = createTestReactiveRoot(graph); try { assertStatus(root, "B", "idle"); assertBlockedByFailure(root, "B", false); root.statusMap.get("A")!.value = "failed"; assertBlockedByFailure(root, "B", true); assertStatus(root, "B", "aborted"); } finally { root.dispose(); } }); it("skipped satisfies preconditions", () => { const graph = createLinearGraph(["A", "B"]); const root = createTestReactiveRoot(graph); try { root.statusMap.get("A")!.value = "skipped"; assertPreconditions(root, "B", true); } finally { root.dispose(); } }); }); describe("schemas", () => { it("provides compatible pairs", () => { expect(compatiblePairs.length).toBeGreaterThan(0); for (const pair of compatiblePairs) { expect(pair.name).toBeTruthy(); expect(pair.output).toBeDefined(); expect(pair.input).toBeDefined(); } }); it("provides incompatible pairs", () => { expect(incompatiblePairs.length).toBeGreaterThan(0); for (const pair of incompatiblePairs) { expect(pair.name).toBeTruthy(); expect(pair.output).toBeDefined(); expect(pair.input).toBeDefined(); } }); it("provides unknown schemas", () => { expect(unknownSchemas.length).toBeGreaterThan(0); for (const item of unknownSchemas) { expect(item.name).toBeTruthy(); expect(item.schema).toBeDefined(); } }); it("CompatibleInputSchema and CompatibleOutputSchema have same structure", () => { expect(CompatibleInputSchema).toBeDefined(); expect(CompatibleOutputSchema).toBeDefined(); }); }); });