返回 DeepSeek-Reasonix
turn-verification-commands.test.tsx
根目录 / desktop / frontend / src / __tests__ / turn-verification-commands.test.tsx
1 import assert from "node:assert/strict";
2 import React, { act } from "react";
3 import { createRoot } from "react-dom/client";
4 import { JSDOM } from "jsdom";
5 import { useTurnVerificationCommands } from "../app-runtime/useTurnVerificationCommands";
6 import type { WireCompletionSummary } from "../lib/types";
7
8 const dom = new JSDOM("<div id='root'></div>");
9 Object.assign(globalThis, { window: dom.window, document: dom.window.document, IS_REACT_ACT_ENVIRONMENT: true });
10 const root = createRoot(document.getElementById("root")!);
11
12 function summary(mutations: number): WireCompletionSummary {
13 return {
14 preset: "balanced",
15 verdict: "partial",
16 mutations,
17 checks_passed: 2,
18 checks_failed: 1,
19 checks_suppressed: 0,
20 review: "passed",
21 gap_kinds: [],
22 constraint_degraded: false,
23 };
24 }
25
26 const dockCalls: string[] = [];
27 let states!: ReturnType<typeof useTurnVerificationCommands>;
28 function Probe(props: { activeTabId?: string; turnStartAt?: number; completionSummary?: WireCompletionSummary }) {
29 states = useTurnVerificationCommands({
30 activeTabId: props.activeTabId,
31 turnStartAt: props.turnStartAt ?? 0,
32 completionSummary: props.completionSummary,
33 openChangedDock: () => { dockCalls.push("changed"); },
34 });
35 return null;
36 }
37 const paint = (props?: { activeTabId?: string; turnStartAt?: number; completionSummary?: WireCompletionSummary }) =>
38 act(async () => root.render(<Probe activeTabId="A" turnStartAt={100} completionSummary={summary(1)} {...props} />));
39
40 try {
41 await paint();
42 assert.equal(states.verificationRevealRequest, null, "no reveal request exists before the first open");
43
44 const historical = summary(7);
45 await act(async () => { states.openTurnVerification(historical); });
46 assert.deepEqual(dockCalls, ["changed"], "opening verification reveals the changed-files dock");
47 assert.deepEqual(states.verificationRevealRequest, {
48 id: 1, summary: historical, tabId: "A", turnStartAt: 100, currentSummary: summary(1), sessionPath: undefined, view: "checks",
49 }, "the reveal request binds the clicked summary to the tab and turn that published it");
50
51 const second = summary(9);
52 await act(async () => { states.openTurnVerification(second); });
53 assert.equal(states.verificationRevealRequest?.id, 2, "reveal request ids increase monotonically");
54 assert.equal(states.verificationRevealRequest?.summary, second, "the newest open replaces the pending request");
55 assert.equal(dockCalls.length, 2, "every open re-reveals the dock");
56
57 await paint({ turnStartAt: 200 });
58 assert.equal(states.verificationRevealRequest, null, "a new turn clears the historical reveal");
59
60 await act(async () => { states.openTurnVerification(summary(3)); });
61 assert.equal(states.verificationRevealRequest?.id, 3, "the reveal sequence survives resets");
62 await paint({ activeTabId: "B" });
63 assert.equal(states.verificationRevealRequest, null, "switching tabs clears the historical reveal");
64
65 await act(async () => { states.openTurnVerification(summary(4)); });
66 await paint({ activeTabId: "B", completionSummary: summary(2) });
67 assert.equal(states.verificationRevealRequest?.summary.mutations, 4, "a summary refresh preserves the historical reveal");
68 await act(async () => { states.openTurnChanges(historical); });
69 assert.equal(states.verificationRevealRequest?.view, "changes");
70 await act(async () => { states.closeTurnResult(); });
71 assert.equal(states.verificationRevealRequest, null);
72
73 await paint({ activeTabId: undefined });
74 await act(async () => { states.openTurnVerification(summary(5)); });
75 assert.equal(states.verificationRevealRequest?.tabId, "", "opening without an active tab records an empty tab binding");
76
77 console.log("turn verification commands: dock reveal, sequenced requests and reset lifecycle passed");
78 } finally { dom.window.close(); }
79
79 lines Plain Text