返回 DeepSeek-Reasonix
read-snapshot-window.test.ts
根目录 / desktop / frontend / src / __tests__ / read-snapshot-window.test.ts
1 import assert from "node:assert/strict";
2 import { loadProjectTreePageWindow } from "../lib/projectTreeWindow";
3
4 for (const size of [205, 405, 1000]) {
5 const calls: string[] = [];
6 let expired = false;
7 const result = await loadProjectTreePageWindow("", size, async (cursor, limit) => {
8 calls.push(cursor);
9 if (cursor === "old:200") { expired = true; throw Object.assign(new Error("expired"), { code: "stale_cursor" }); }
10 const id = expired ? "fresh" : "old";
11 const offset = Number(cursor.split(":")[1] ?? 0);
12 return { snapshotId: id, items: Array.from({ length: Math.min(limit, size - offset) }, (_, i) => offset + i), nextCursor: offset + limit < size ? `${id}:${offset + limit}` : "", revision: 1 };
13 });
14 assert.equal(result.replacedSnapshot, true);
15 assert.equal(result.snapshotId, "fresh");
16 assert.deepEqual(result.items, Array.from({ length: size }, (_, i) => i));
17 assert.equal(calls.filter((cursor) => cursor === "").length, 2);
18 }
19
20 let attempts = 0;
21 await assert.rejects(loadProjectTreePageWindow("", 405, async (cursor) => {
22 if (!cursor) { attempts++; return { items: [1], nextCursor: "next", revision: 1 }; }
23 throw Object.assign(new Error("expired"), { code: "stale_cursor" });
24 }), /expired/);
25 assert.equal(attempts, 2, "one recovery per logical operation");
26
27 const replacement = await loadProjectTreePageWindow("expired:200", 5, async (cursor, limit) => {
28 if (cursor.startsWith("expired")) throw new Error("session_operation:stale_cursor:expired");
29 const offset = Number(cursor || 0);
30 return { items: Array.from({ length: limit }, (_, i) => offset + i), nextCursor: String(offset + limit), revision: 2, snapshotId: "replacement" };
31 }, 205);
32 assert.equal(replacement.items.length, 205, "append recovery restores the entire visible window");
33 assert.equal(replacement.replacedSnapshot, true);
34
35 await assert.rejects(loadProjectTreePageWindow("next", 5, async () => ({ items: [1], nextCursor: "next", revision: 1 })), /did not advance/);
36 await assert.rejects(loadProjectTreePageWindow("", 205, async (cursor) => ({ items: Array(200).fill(1), nextCursor: "next", snapshotId: cursor ? "b" : "a", revision: 1 })), /Mixed read snapshots/);
37 console.log("PASS immutable windows, internal-page expiry, bounded recovery and whole-window replacement");
38
38 lines TYPESCRIPT