返回 DeepSeek-Reasonix
transcriptRaceClock.ts
根目录 / desktop / frontend / src / __tests__ / helpers / transcriptRaceClock.ts
1 import { act } from "react";
2
3 export function installTranscriptRaceClock(targetWindow: Window) {
4 let clockNow = 10_000;
5 let nextTimer = 1;
6 const timers = new Map<number, { dueAt: number; run: () => void }>();
7 const originalDateNow = Date.now;
8 const originalSetTimeout = targetWindow.setTimeout;
9 const originalClearTimeout = targetWindow.clearTimeout;
10 Date.now = () => clockNow;
11 targetWindow.setTimeout = ((handler: TimerHandler, timeout = 0, ...args: unknown[]) => {
12 const id = nextTimer++;
13 const run = typeof handler === "function"
14 ? () => handler(...args)
15 : () => { throw new Error("string timer handlers are unsupported in this test"); };
16 timers.set(id, { dueAt: clockNow + Math.max(0, timeout), run });
17 return id;
18 }) as typeof targetWindow.setTimeout;
19 targetWindow.clearTimeout = ((id: number | undefined) => {
20 if (id !== undefined) timers.delete(id);
21 }) as typeof targetWindow.clearTimeout;
22
23 const advanceClock = async (milliseconds: number) => {
24 await act(async () => {
25 const target = clockNow + milliseconds;
26 while (true) {
27 const next = [...timers.entries()]
28 .filter(([, timer]) => timer.dueAt <= target)
29 .sort(([leftID, left], [rightID, right]) => left.dueAt - right.dueAt || leftID - rightID)[0];
30 if (!next) break;
31 const [id, timer] = next;
32 timers.delete(id);
33 clockNow = timer.dueAt;
34 timer.run();
35 }
36 clockNow = target;
37 });
38 };
39 const restore = () => {
40 Date.now = originalDateNow;
41 targetWindow.setTimeout = originalSetTimeout;
42 targetWindow.clearTimeout = originalClearTimeout;
43 };
44 return { advanceClock, restore };
45 }
46
46 lines TYPESCRIPT