Files
next-tjwater-frontend/src/features/agent/execution-plan.test.ts
T

30 lines
1.9 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { executionPlanStages, parseExecutionPlan, readExecutionPlanHistory } from "./execution-plan";
const snapshot = {
schema_version: "execution-plan@1", session_id: "s1", revision: 1, updated_at: "2026-09-23T01:00:00.000Z",
title: "调查", reason: "开始",
nodes: [{ id: "a", title: '水质"] --> injected["<script>', status: "waiting", owner: "human", detail: "等待采样", evidence: [] }], edges: []
};
describe("execution plan projection", () => {
it("groups independent checks before their shared downstream decision", () => {
const plan = parseExecutionPlan({ ...snapshot,
nodes: ["a", "b", "c", "d"].map((id) => ({ ...snapshot.nodes[0], id })),
edges: [{ from: "a", to: "b", label: "" }, { from: "a", to: "c", label: "" }, { from: "b", to: "d", label: "" }, { from: "c", to: "d", label: "" }]
}, "s1")!;
expect(executionPlanStages(plan).map((stage) => stage.map((node) => node.id))).toEqual([["a"], ["b", "c"], ["d"]]);
});
it("rejects other sessions and dangling dependencies", () => {
expect(parseExecutionPlan(snapshot, "s2")).toBeNull();
expect(parseExecutionPlan({ ...snapshot, edges: [{ from: "a", to: "b", label: "" }] }, "s1")).toBeNull();
});
it("restores and deduplicates UI and active-run snapshots without completing waiting work", () => {
const history = readExecutionPlanHistory([{ parts: [{ type: "data-execution_plan", data: snapshot }] }, { executionPlans: [snapshot] }], "s1");
expect(history).toHaveLength(1);
expect(history[0].nodes[0].status).toBe("waiting");
});
it("rejects cyclic dependencies rather than guessing their order", () => {
expect(parseExecutionPlan({ ...snapshot, nodes: [snapshot.nodes[0], { ...snapshot.nodes[0], id: "b" }], edges: [{ from: "a", to: "b", label: "" }, { from: "b", to: "a", label: "" }] }, "s1")).toBeNull();
});
});