47 lines
2.4 KiB
TypeScript
47 lines
2.4 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { ExecutionProgressState } from "./execution-progress-state";
|
|
|
|
const T0 = "2026-08-03T00:00:00.000Z";
|
|
const T1 = "2026-08-03T00:00:18.000Z";
|
|
|
|
describe("ExecutionProgressState", () => {
|
|
it("starts a turn with no invented operation steps", () => {
|
|
const state = new ExecutionProgressState();
|
|
expect(state.begin("exec_001", T0)).toEqual(expect.objectContaining({ id: "exec_001", status: "running", steps: [] }));
|
|
});
|
|
|
|
it("only accepts bounded, canonical execution steps for the matching turn", () => {
|
|
const state = new ExecutionProgressState();
|
|
state.begin("exec_001", T0);
|
|
expect(state.applyTrace("exec_other", "completed", [], T1)).toBeUndefined();
|
|
const summary = state.applyTrace("exec_001", "completed", [{ id: "step_01", title: "检查 qmtbridge health", status: "completed" }], T1);
|
|
expect(summary).toEqual(expect.objectContaining({ status: "completed", steps: [{ id: "step_01", title: "检查 qmtbridge health", status: "completed" }] }));
|
|
});
|
|
|
|
it("updates a real running step in place before the turn ends", () => {
|
|
const state = new ExecutionProgressState();
|
|
state.begin("exec_001", T0);
|
|
expect(state.applyTrace("exec_001", "running", [{ id: "step_01", title: "查询公开资料", status: "running" }], T1))
|
|
.toEqual(expect.objectContaining({ status: "running", finished_at: undefined, steps: [{ id: "step_01", title: "查询公开资料", status: "running" }] }));
|
|
expect(state.applyTrace("exec_001", "completed", [{ id: "step_01", title: "查询公开资料", status: "completed" }], T1))
|
|
.toEqual(expect.objectContaining({ status: "completed", finished_at: T1 }));
|
|
});
|
|
|
|
it("finishes without a trace without fabricating a fixed lifecycle", () => {
|
|
const state = new ExecutionProgressState();
|
|
state.begin("exec_001", T0);
|
|
expect(state.finishActive("completed", T1)).toEqual(expect.objectContaining({ steps: [] }));
|
|
});
|
|
|
|
it("keeps overlapping execution ids independent and finishes only the matching turn", () => {
|
|
const state = new ExecutionProgressState();
|
|
state.begin("exec_001", T0);
|
|
state.begin("exec_002", T1);
|
|
state.finish("exec_002", "completed", T1);
|
|
expect(state.snapshot()).toEqual([
|
|
expect.objectContaining({ id: "exec_001", status: "running" }),
|
|
expect.objectContaining({ id: "exec_002", status: "completed" }),
|
|
]);
|
|
});
|
|
});
|