返回 DeepSeek-Reasonix
task-monitor-navigation.test.ts
根目录 / desktop / frontend / src / __tests__ / task-monitor-navigation.test.ts
1 import assert from "node:assert/strict";
2 import type { ControlResult, SessionMeta } from "../lib/types";
3 import { resolveTaskMonitorSession } from "../lib/taskMonitorNavigation";
4
5 function deferred<T>() {
6 let resolve!: (value: T) => void;
7 const promise = new Promise<T>((res) => {
8 resolve = res;
9 });
10 return { promise, resolve };
11 }
12
13 const openResult: ControlResult = {
14 schema_version: 1,
15 command: "open_session",
16 task_id: "session-a--task-1",
17 session_id: "session-a",
18 accepted: true,
19 idempotent: false,
20 };
21 const session: SessionMeta = {
22 path: "/project-a/session-a.jsonl",
23 preview: "project A",
24 turns: 1,
25 createdAt: 1,
26 lastActivityAt: 1,
27 modTime: 1,
28 current: false,
29 open: false,
30 };
31 const sessionIDFromPath = (path: string) => path.split("/").pop()?.replace(/\.jsonl$/, "") ?? "";
32
33 async function testLateOpenCompletionIsDiscarded() {
34 const open = deferred<ControlResult>();
35 let currentIntent = 1;
36 let listCalls = 0;
37 const pending = resolveTaskMonitorSession({
38 tabID: "tab-a",
39 taskID: openResult.task_id,
40 intentSeq: 1,
41 isIntentCurrent: (seq) => seq === currentIntent,
42 openTaskSessionForTab: () => open.promise,
43 listSessionsForTab: async () => {
44 listCalls += 1;
45 return [session];
46 },
47 sessionIDFromPath,
48 });
49
50 currentIntent = 2;
51 open.resolve(openResult);
52 assert.equal(await pending, null);
53 assert.equal(listCalls, 0);
54 }
55
56 async function testLateSessionListIsDiscarded() {
57 const list = deferred<SessionMeta[]>();
58 let currentIntent = 1;
59 const pending = resolveTaskMonitorSession({
60 tabID: "tab-a",
61 taskID: openResult.task_id,
62 intentSeq: 1,
63 isIntentCurrent: (seq) => seq === currentIntent,
64 openTaskSessionForTab: async () => openResult,
65 listSessionsForTab: () => list.promise,
66 sessionIDFromPath,
67 });
68
69 await Promise.resolve();
70 currentIntent = 2;
71 list.resolve([session]);
72 assert.equal(await pending, null);
73 }
74
75 async function testSourceTabAndSessionStayBound() {
76 const calls: string[][] = [];
77 const resolved = await resolveTaskMonitorSession({
78 tabID: "tab-a",
79 taskID: openResult.task_id,
80 intentSeq: 7,
81 isIntentCurrent: (seq) => seq === 7,
82 openTaskSessionForTab: async (...args) => {
83 calls.push(args);
84 return openResult;
85 },
86 listSessionsForTab: async (tabID) => {
87 calls.push([tabID]);
88 return [session];
89 },
90 sessionIDFromPath,
91 });
92
93 assert.equal(resolved?.path, session.path);
94 assert.deepEqual(calls, [["tab-a", openResult.task_id], ["tab-a"]]);
95 }
96
97 await testLateOpenCompletionIsDiscarded();
98 await testLateSessionListIsDiscarded();
99 await testSourceTabAndSessionStayBound();
100 console.log("task monitor navigation: 3 passed");
101
101 lines TYPESCRIPT