返回 DeepSeek-Reasonix
add-project-entries.test.ts
根目录 / desktop / frontend / src / __tests__ / add-project-entries.test.ts
1 // Run: tsx src/__tests__/add-project-entries.test.ts
2 // Source-contract test: the add-project entry points must offer the remote
3 // connection action next to the local one, and the removed sidebar quick
4 // button must stay gone.
5
6 import { readFileSync } from "node:fs";
7 import { dirname, resolve } from "node:path";
8 import { fileURLToPath } from "node:url";
9
10 let passed = 0;
11 let failed = 0;
12 function ok(value: boolean, label: string) {
13 if (value) {
14 process.stdout.write(` PASS ${label}\n`);
15 passed += 1;
16 } else {
17 process.stdout.write(` FAIL ${label}\n`);
18 failed += 1;
19 }
20 }
21
22 console.log("\nAdd-project entry matrix");
23 const here = dirname(fileURLToPath(import.meta.url));
24 const treeSource = readFileSync(resolve(here, "../components/ProjectTree.tsx"), "utf8");
25 const addControlsSource = readFileSync(resolve(here, "../components/ProjectTreeAddControls.tsx"), "utf8");
26 const hookSource = readFileSync(resolve(here, "../components/useProjectCreation.tsx"), "utf8");
27 const appSource = readFileSync(resolve(here, "../AppRuntime.tsx"), "utf8");
28 const locales = ["en", "zh", "zh-TW"].map((name) =>
29 readFileSync(resolve(here, `../locales/${name}.ts`), "utf8"),
30 );
31
32 // Workbench "+" menu: three items, remote opens the wizard flow.
33 ok(
34 /onRemote: \(\) => \{ closeMenu\(\); openRemoteConnectFlow\(\); \}/.test(treeSource) &&
35 /key: "remote-connection"[\s\S]*?onSelect: onRemote/.test(addControlsSource),
36 "workbench + menu offers the remote connection item wired to the wizard flow",
37 );
38 ok(
39 /key: "blank-project"[\s\S]*?key: "open-local-folder"[\s\S]*?key: "remote-connection"/.test(addControlsSource),
40 "workbench + menu keeps blank project and existing folder before remote connection",
41 );
42
43 // Classic/creation "+": no longer a direct picker; renders a menu that
44 // contains the remote connection item.
45 ok(
46 /project-tree__add-project[\s\S]*?aria-haspopup="menu"/.test(addControlsSource),
47 "classic/creation + button opens a menu instead of the direct picker",
48 );
49 ok(
50 /ProjectTreeHeaderAddControl[\s\S]*?items=\{classicHeaderAddItems\}/.test(treeSource),
51 "classic/creation + menu is the two-item local/remote list",
52 );
53
54 // Empty state: primary local + secondary remote.
55 ok(
56 /project-tree__empty-primary[\s\S]*?ProjectTreeRemoteAction[\s\S]*?openRemoteConnectFlow/.test(treeSource) &&
57 /project-tree__empty-secondary/.test(addControlsSource),
58 "empty state pairs the local action with a remote connection action",
59 );
60
61 // The wizard mounts through the creation hook, outside the startup bundle.
62 ok(
63 /lazy\(\(\) => import\("\.\/RemoteConnectWizardEntry"\)/.test(hookSource),
64 "remote wizard loads lazily through useProjectCreation",
65 );
66
67 // Removed sidebar quick button: gone from App.tsx and no locale key remains.
68 ok(!/sidebar__new--remote/.test(appSource), "removed sidebar quick button leaves no JSX behind");
69 ok(!/creation\.sidebar\.remote/.test(appSource), "no creation.sidebar.remote usage in App.tsx");
70 for (const [index, source] of locales.entries()) {
71 ok(!/creation\.sidebar\.remote/.test(source), `creation.sidebar.remote removed from locale #${index + 1}`);
72 ok(/"projectTree\.remoteConnection"/.test(source), `projectTree.remoteConnection present in locale #${index + 1}`);
73 }
74
75 process.stdout.write(`\n${passed} passed, ${failed} failed\n`);
76 if (failed > 0) process.exit(1);
77
77 lines TYPESCRIPT