返回 DeepSeek-Reasonix
turn-timing-race.test.ts
根目录 / desktop / frontend / src / __tests__ / turn-timing-race.test.ts
1 // Run: tsx src/__tests__/turn-timing-race.test.ts
2
3 import { initialState, promptEventClock, reducer } from "../lib/useController";
4
5 let passed = 0;
6 let failed = 0;
7
8 function eq(actual: unknown, expected: unknown, label: string) {
9 if (actual === expected) {
10 process.stdout.write(` PASS ${label}\n`);
11 passed += 1;
12 } else {
13 process.stdout.write(` FAIL ${label}: expected ${JSON.stringify(expected)}, got ${JSON.stringify(actual)}\n`);
14 failed += 1;
15 }
16 }
17
18 process.stdout.write("turn timing snapshot ordering\n");
19
20 const originalNow = Date.now;
21 let now = 2_000;
22 Date.now = () => now;
23 try {
24 let state = reducer(initialState, {
25 type: "event",
26 e: { kind: "turn_started", submissionId: "turn-a", turnStartedAt: 2_000 },
27 });
28 const staleSnapshotAt = promptEventClock();
29 state = reducer(state, { type: "event", e: { kind: "turn_done", submissionId: "turn-a" } });
30
31 const staleAfterDone = reducer(state, {
32 type: "backend_status",
33 running: true,
34 cancellable: true,
35 turnStartedAt: 2_000,
36 snapshotAt: staleSnapshotAt,
37 });
38 eq(staleAfterDone.running, false, "a stale running snapshot cannot resurrect a completed turn");
39
40 now = 4_000;
41 state = reducer(state, {
42 type: "event",
43 e: { kind: "turn_started", submissionId: "turn-b", turnStartedAt: 4_000 },
44 });
45
46 const staleRunning = reducer(state, {
47 type: "backend_status",
48 running: true,
49 cancellable: true,
50 turnStartedAt: 2_000,
51 snapshotAt: staleSnapshotAt,
52 });
53 eq(staleRunning.turnStartAt, 4_000, "a stale running snapshot cannot rewind a newer turn clock");
54
55 const unorderedRunning = reducer(state, {
56 type: "backend_status",
57 running: true,
58 cancellable: true,
59 turnStartedAt: 2_000,
60 });
61 eq(unorderedRunning.turnStartAt, 4_000, "an unordered status keeps a surviving newer local clock");
62
63 const staleIdle = reducer(state, {
64 type: "backend_status",
65 running: false,
66 cancellable: false,
67 snapshotAt: staleSnapshotAt,
68 });
69 eq(staleIdle.running, true, "a stale idle snapshot cannot stop a newer live turn");
70
71 now = 5_000;
72 const correctedFallback = reducer({ ...state, turnStartAt: 3_900 }, {
73 type: "backend_status",
74 running: true,
75 cancellable: true,
76 turnStartedAt: 4_000,
77 });
78 eq(correctedFallback.turnStartAt, 4_000, "a newer backend start still corrects an earlier local fallback");
79 } finally {
80 Date.now = originalNow;
81 }
82
83 if (failed > 0) {
84 process.stderr.write(`\n${failed} check(s) failed\n`);
85 process.exitCode = 1;
86 } else {
87 process.stdout.write(`\n${passed} passed, ${failed} failed\n`);
88 }
89
89 lines TYPESCRIPT