返回 DeepSeek-Reasonix
workspace-panel-swr-contract.test.ts
根目录 / desktop / frontend / src / __tests__ / workspace-panel-swr-contract.test.ts
1 import assert from "node:assert/strict";
2 import { readFileSync } from "node:fs";
3 import { dirname, resolve } from "node:path";
4 import { fileURLToPath } from "node:url";
5
6 const testDir = dirname(fileURLToPath(import.meta.url));
7 const panel = readFileSync(resolve(testDir, "../components/WorkspacePanel.tsx"), "utf8");
8 const stabilityCSS = readFileSync(resolve(testDir, "../components/WorkspacePanelStability.css"), "utf8");
9 const workspaceChangesResource = readFileSync(resolve(testDir, "../lib/useWorkspaceChangesResource.ts"), "utf8");
10 const workspaceTreeScrollPersistence = readFileSync(resolve(testDir, "../lib/useWorkspaceTreeScrollPersistence.ts"), "utf8");
11
12 assert.match(
13 workspaceChangesResource,
14 /emptyKeyedResource<WorkspaceChangesView>/,
15 "working-tree changes use the same keyed stale-while-revalidate resource as preview and history",
16 );
17 assert.match(
18 workspaceChangesResource,
19 /setResource\(\(current\) => rejectKeyedResourceRequest/,
20 "a failed working-tree refresh preserves the last painted data",
21 );
22 assert.doesNotMatch(
23 workspaceChangesResource,
24 /setResource\(\{\s*files:\s*\[\]/,
25 "a failed working-tree refresh never clears the visible list",
26 );
27 assert.match(
28 panel,
29 /loadingHistory\s*&&\s*gitHistory\.length\s*===\s*0/,
30 "history uses a loading placeholder only when there is no stale data to paint",
31 );
32 assert.doesNotMatch(
33 panel,
34 /\{loadingHistory\s*\?\s*\(/,
35 "history refresh does not replace an already-painted list with a loading branch",
36 );
37
38 const cwdReset = panel.match(/useEffect\(\(\) => \{[\s\S]*?\}, \[cwd, fileNavigation, fileScope, loadDir, open, workspaceMemoryKey\]\);/)?.[0] ?? "";
39 assert.ok(cwdReset, "workspace cwd reset effect is present");
40 assert.doesNotMatch(cwdReset, /setSelected(?:File|Change)Path\(null\)/, "cwd reset does not erase restored per-project selections");
41 // The preview key already carries its scope, path, mode and access context, so
42 // clearing it here would only discard the read another effect just started when
43 // this effect reconnects.
44 assert.doesNotMatch(cwdReset, /setPreviewResource\(emptyKeyedResource\(\)\)/, "cwd reset does not discard the preview a read just started");
45
46 const scopeReset = panel.match(/useEffect\(\(\) => \{[\s\S]*?\}, \[fileNavigation, fileScope, open, resetWorkspaceChanges, viewMode, workspaceScopeKey\]\);/)?.[0] ?? "";
47 assert.ok(scopeReset, "workspace scope reset effect is present");
48 assert.doesNotMatch(scopeReset, /setSelectedChangePath\(null\)/, "scope reset does not erase the restored change selection");
49
50 assert.match(
51 stabilityCSS,
52 /\.workspace-resource-status\s*\{[\s\S]*?position:\s*absolute;/,
53 "refresh and error badges overlay stale content without changing its layout",
54 );
55 assert.match(
56 panel,
57 /onScroll=\{onWorkspaceTreeScroll\}/,
58 "tree scrolling updates memory without synchronously serializing localStorage",
59 );
60 assert.match(
61 workspaceTreeScrollPersistence,
62 /addEventListener\("scrollend", flush\)/,
63 "tree scroll persistence flushes at the native scroll boundary",
64 );
65 assert.match(
66 workspaceTreeScrollPersistence,
67 /addEventListener\("pagehide", flush\)/,
68 "pending tree scroll state flushes before page suspension",
69 );
70
71 console.log(" PASS workspace panel SWR and per-project restoration contract");
72
72 lines TYPESCRIPT