feat(FN-4737): parameterize worktree-escape test to use configured worktree

Adds parameterized test cases to the worktree-liveness test to exercise different configured `worktreesDir` paths, improving coverage of the worktree escape/isolation path.

Fusion-Task-Id: FN-4737

Fusion-Task-Lineage: 40e262ea-2507-461e-b9f5-940b3b4490f9
This commit is contained in:
Fusion (runfusion.ai)
2026-05-16 09:56:28 -07:00
committed by gsxdsm
parent f761f771d1
commit 477f79f3eb
6 changed files with 111 additions and 55 deletions

View File

@@ -21,7 +21,7 @@
"scripts": {
"dev": "tsx scripts/dev.ts",
"build": "tsx scripts/build.ts",
"test": "pnpm --filter @fusion/core build && pnpm --filter @fusion/dashboard build && vitest run --silent=passed-only --reporter=dot",
"test": "tsx scripts/test.ts",
"typecheck": "tsc --noEmit",
"generate:icons": "tsx scripts/generate-icons.ts",
"pack": "electron-builder --dir",

View File

@@ -1,43 +1,15 @@
import { build } from "esbuild";
import { cp, mkdir, rm, stat } from "node:fs/promises";
import { dirname, join, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { spawn } from "node:child_process";
const __dirname = dirname(fileURLToPath(import.meta.url));
const packageRoot = resolve(__dirname, "..");
const workspaceRoot = resolve(packageRoot, "..", "..");
import { join, resolve } from "node:path";
import { buildDashboardClient, packageRoot, workspaceRoot } from "./workspace-tools";
const dashboardClientDir = join(workspaceRoot, "packages", "dashboard", "dist", "client");
const desktopDistDir = join(packageRoot, "dist");
const desktopClientDistDir = join(desktopDistDir, "client");
const externalMainProcessPackages = ["electron", "@fusion/core", "@fusion/dashboard"];
function run(command: string, args: string[], cwd: string): Promise<void> {
return new Promise((resolvePromise, rejectPromise) => {
const child = spawn(command, args, {
cwd,
stdio: "inherit",
env: process.env,
});
child.on("error", (error) => {
rejectPromise(error);
});
child.on("exit", (code) => {
if (code === 0) {
resolvePromise();
return;
}
rejectPromise(new Error(`${command} ${args.join(" ")} exited with code ${code ?? "unknown"}`));
});
});
}
async function ensureDashboardBuild(): Promise<void> {
console.log("[desktop:build] Building dashboard client...");
await run("pnpm", ["--filter", "@fusion/dashboard", "build:client"], workspaceRoot);
await buildDashboardClient();
try {
await stat(dashboardClientDir);

View File

@@ -1,13 +1,9 @@
import { build } from "esbuild";
import { spawn, type ChildProcess } from "node:child_process";
import { mkdir } from "node:fs/promises";
import { dirname, join, resolve } from "node:path";
import { join } from "node:path";
import { createRequire } from "node:module";
import { fileURLToPath } from "node:url";
const __dirname = dirname(fileURLToPath(import.meta.url));
const packageRoot = resolve(__dirname, "..");
const workspaceRoot = resolve(packageRoot, "..", "..");
import { packageRoot, workspaceRoot } from "./workspace-tools";
const distDir = join(packageRoot, "dist");
const require = createRequire(import.meta.url);
@@ -94,19 +90,14 @@ async function main(): Promise<void> {
const dashboardPort = dashboardUrl.port || (dashboardUrl.protocol === "https:" ? "443" : "80");
console.log(`[desktop:dev] Starting dashboard Vite dev server on ${dashboardUrl.origin}...`);
const viteProcess = run(
"pnpm",
[
"--filter",
"@fusion/dashboard",
"dev:serve",
"--host",
dashboardHost,
"--port",
dashboardPort,
"--strictPort",
],
workspaceRoot,
const viteProcess = spawn(
join(workspaceRoot, "packages", "dashboard", "node_modules", ".bin", process.platform === "win32" ? "vite.cmd" : "vite"),
["dev", "--host", dashboardHost, "--port", dashboardPort, "--strictPort"],
{
cwd: join(workspaceRoot, "packages", "dashboard"),
env: process.env,
stdio: "inherit",
},
);
let isShuttingDown = false;

View File

@@ -0,0 +1,17 @@
import { buildCore, buildDashboard, packageRoot, runWorkspaceBin } from "./workspace-tools";
async function main(): Promise<void> {
console.log("[desktop:test] Building @fusion/core...");
await buildCore();
console.log("[desktop:test] Building @fusion/dashboard...");
await buildDashboard();
console.log("[desktop:test] Running desktop Vitest suite...");
await runWorkspaceBin("vitest", ["run", "--silent=passed-only", "--reporter=dot"], packageRoot);
}
void main().catch((error) => {
console.error("[desktop:test] Test run failed", error);
process.exitCode = 1;
});

View File

@@ -0,0 +1,52 @@
import { spawn } from "node:child_process";
import { dirname, resolve } from "node:path";
import { existsSync } from "node:fs";
import { fileURLToPath } from "node:url";
const __dirname = dirname(fileURLToPath(import.meta.url));
export const packageRoot = resolve(__dirname, "..");
export const workspaceRoot = resolve(packageRoot, "..", "..");
function resolveBin(command: string, cwd: string): string {
const suffix = process.platform === "win32" ? ".cmd" : "";
const localBin = resolve(cwd, "node_modules", ".bin", `${command}${suffix}`);
if (existsSync(localBin)) {
return localBin;
}
return resolve(workspaceRoot, "node_modules", ".bin", `${command}${suffix}`);
}
export function runWorkspaceBin(command: string, args: string[], cwd: string): Promise<void> {
return new Promise((resolvePromise, rejectPromise) => {
const child = spawn(resolveBin(command, cwd), args, {
cwd,
stdio: "inherit",
env: process.env,
});
child.on("error", rejectPromise);
child.on("exit", (code) => {
if (code === 0) {
resolvePromise();
return;
}
rejectPromise(new Error(`${command} ${args.join(" ")} exited with code ${code ?? "unknown"}`));
});
});
}
export async function buildCore(): Promise<void> {
await runWorkspaceBin("tsc", [], resolve(workspaceRoot, "packages", "core"));
}
export async function buildDashboard(): Promise<void> {
const dashboardRoot = resolve(workspaceRoot, "packages", "dashboard");
await runWorkspaceBin("vite", ["build"], dashboardRoot);
await runWorkspaceBin("tsc", [], dashboardRoot);
}
export async function buildDashboardClient(): Promise<void> {
await runWorkspaceBin("vite", ["build"], resolve(workspaceRoot, "packages", "dashboard"));
}