返回 DeepSeek-Reasonix
desktop-event-recovery.test.ts
根目录 / desktop / frontend / src / __tests__ / desktop-event-recovery.test.ts
1 import assert from "node:assert/strict";
2 import { startDesktopEventRecovery } from "../lib/desktopEventRecovery";
3
4 const tick = () => new Promise(resolve => setImmediate(resolve));
5 let signal!: () => void;
6 let selected = "task-a", generation = 1;
7 const pending: Array<(value: string) => void> = [];
8 const applied: string[] = [];
9 const timers = new Map<number, () => void>();
10 let timerID = 0;
11 const stop = startDesktopEventRecovery({
12 subscribe: callback => { signal = callback; return () => {}; },
13 capture: () => ({ selected, generation }),
14 isCurrent: scope => scope.selected === selected && scope.generation === generation,
15 read: () => new Promise<string>(resolve => pending.push(resolve)),
16 apply: (snapshot, scope) => applied.push(`${scope.selected}:${scope.generation}:${snapshot}`),
17 timer: callback => { const id = ++timerID; timers.set(id, callback); return id; },
18 clearTimer: id => { timers.delete(id as number); },
19 });
20 signal(); signal();
21 assert.equal(pending.length, 1, "gaps share one in-flight snapshot read");
22 pending.shift()!("obsolete"); await tick();
23 assert.deepEqual(applied, [], "a new recovery signal fences the previous snapshot");
24 assert.equal(pending.length, 1);
25 selected = "task-b";
26 pending.shift()!("old-selection"); await tick();
27 assert.deepEqual(applied, [], "switching tasks prevents late snapshot application");
28 assert.equal(timers.size, 1, "a superseded selection queues fresh recovery");
29 [...timers.values()][0]();
30 generation++;
31 signal();
32 pending.shift()!("old-service"); await tick();
33 pending.shift()!("current"); await tick();
34 assert.deepEqual(applied, ["task-b:2:current"]);
35 signal(); stop(); pending.shift()!("disposed"); await tick();
36 assert.equal(applied.length, 1);
37 assert.equal(timers.size, 0);
38 console.log("desktop event recovery: coalescing, generation/session fencing, retry and disposal passed");
39
39 lines TYPESCRIPT