FN-6004: add execFile to engine child_process test mocks

Update engine tests so child_process mocks cover execFile alongside exec.

- add execFile mock implementations and promisify support in branch/worktree tests that rely on child_process behavior
- extend simpler child_process mocks in integration, sandbox, and worktree tests to export execFile stubs
- keep existing exec and execSync mock behavior unchanged while restoring compatibility with code that now imports execFile

Files changed:
 packages/engine/src/__tests__/branch-autocorrect.test.ts       |  9 ++++++++-
 .../engine/src/__tests__/branch-conflicts-self-owned.test.ts   |  9 ++++++++-
 packages/engine/src/__tests__/branch-conflicts.test.ts         |  9 ++++++++-
 packages/engine/src/__tests__/integration-branch.test.ts       |  1 +
 .../engine/src/__tests__/sandbox/bubblewrap-detect.test.ts     |  1 +
 .../engine/src/__tests__/sandbox/sandbox-exec-backend.test.ts  |  1 +
 .../engine/src/__tests__/sandbox/sandbox-exec-detect.test.ts   |  1 +
 .../engine/src/__tests__/worktree-acquisition-backend.test.ts  |  2 +-
 .../src/__tests__/worktree-acquisition-worktrunk.test.ts       |  2 +-
 packages/engine/src/__tests__/worktree-backend.test.ts         |  2 +-
 .../engine/src/__tests__/worktree-hooks-cross-platform.test.ts |  2 +-
 packages/engine/src/__tests__/worktree-pool.test.ts            | 10 ++++++++--
 packages/engine/src/__tests__/worktree-stale-lock.test.ts      |  2 +-
 .../engine/src/__tests__/worktree-stale-registration.test.ts   |  2 +-
 14 files changed, 42 insertions(+), 11 deletions(-)

Fusion-Task-Id: FN-6004

Fusion-Task-Lineage: f87fb103-fe5d-4fc9-a640-9991c06e6448
This commit is contained in:
gsxdsm
2026-06-07 17:32:12 -07:00
parent fa23782dbb
commit 934f2f0d04
14 changed files with 42 additions and 11 deletions

View File

@@ -19,6 +19,10 @@ vi.mock("node:child_process", async () => {
});
});
const execFileFn: any = vi.fn((file: string, args: string[] | undefined, opts: any, cb: any) =>
execFn([file, ...(Array.isArray(args) ? args : [])].join(" "), opts, cb),
);
execFn[promisify.custom] = (cmd: string, opts?: any) =>
new Promise((resolve, reject) => {
execFn(cmd, opts, (err: any, stdout: string, stderr: string) => {
@@ -32,7 +36,10 @@ vi.mock("node:child_process", async () => {
});
});
return { exec: execFn, __execMock: execMock };
execFileFn[promisify.custom] = (file: string, args?: string[], opts?: any) =>
execFn[promisify.custom]([file, ...(Array.isArray(args) ? args : [])].join(" "), opts);
return { exec: execFn, execFile: execFileFn, __execMock: execMock };
});
import { attemptBranchAutocorrect } from "../branch-autocorrect.js";

View File

@@ -20,6 +20,10 @@ vi.mock("node:child_process", async () => {
}
});
const execFileFn: any = vi.fn((file: string, args: string[] | undefined, opts: any, cb: any) =>
execFn([file, ...(Array.isArray(args) ? args : [])].join(" "), opts, cb),
);
execFn[promisify.custom] = (cmd: string, opts?: any) =>
new Promise((resolve, reject) => {
execFn(cmd, opts, (err: any, stdout: string, stderr: string) => {
@@ -33,7 +37,10 @@ vi.mock("node:child_process", async () => {
});
});
return { exec: execFn, execSync: execSyncFn };
execFileFn[promisify.custom] = (file: string, args?: string[], opts?: any) =>
execFn[promisify.custom]([file, ...(Array.isArray(args) ? args : [])].join(" "), opts);
return { exec: execFn, execSync: execSyncFn, execFile: execFileFn };
});
vi.mock("node:fs", () => ({

View File

@@ -20,6 +20,10 @@ vi.mock("node:child_process", async () => {
}
});
const execFileFn: any = vi.fn((file: string, args: string[] | undefined, opts: any, cb: any) =>
execFn([file, ...(Array.isArray(args) ? args : [])].join(" "), opts, cb),
);
execFn[promisify.custom] = (cmd: string, opts?: any) =>
new Promise((resolve, reject) => {
execFn(cmd, opts, (err: any, stdout: string, stderr: string) => {
@@ -33,7 +37,10 @@ vi.mock("node:child_process", async () => {
});
});
return { exec: execFn, execSync: execSyncFn };
execFileFn[promisify.custom] = (file: string, args?: string[], opts?: any) =>
execFn[promisify.custom]([file, ...(Array.isArray(args) ? args : [])].join(" "), opts);
return { exec: execFn, execSync: execSyncFn, execFile: execFileFn };
});
vi.mock("node:fs", () => ({

View File

@@ -8,6 +8,7 @@ const { execMock, execSyncMock } = vi.hoisted(() => ({
vi.mock("node:child_process", () => ({
exec: execMock,
execSync: execSyncMock,
execFile: vi.fn(),
}));
import {

View File

@@ -5,6 +5,7 @@ const execMock = vi.fn();
vi.mock("node:child_process", () => ({
exec: execMock,
execFile: vi.fn(),
}));
const originalPlatform = process.platform;

View File

@@ -16,6 +16,7 @@ const { detectMock, policyToProfileMock, presetMock, nativeRunMock, nativePrepar
vi.mock("node:child_process", () => ({
exec: execMock,
execFile: vi.fn(),
}));
vi.mock("../../sandbox/sandbox-exec-detect.js", () => ({

View File

@@ -5,6 +5,7 @@ const execMock = vi.fn();
vi.mock("node:child_process", () => ({
exec: execMock,
execFile: vi.fn(),
}));
const originalPlatform = process.platform;

View File

@@ -22,7 +22,7 @@ const { execMock, existsSyncMock, accessMock } = vi.hoisted(() => {
return { execMock: mock, existsSyncMock: vi.fn(), accessMock: vi.fn().mockResolvedValue(undefined) };
});
vi.mock("node:child_process", () => ({ exec: execMock }));
vi.mock("node:child_process", () => ({ exec: execMock, execFile: vi.fn() }));
vi.mock("node:fs", () => ({ existsSync: existsSyncMock }));
vi.mock("node:fs/promises", () => ({ access: accessMock }));

View File

@@ -6,7 +6,7 @@ const { execMock, existsSyncMock } = vi.hoisted(() => {
return { execMock: mock, existsSyncMock: vi.fn() };
});
vi.mock("node:child_process", () => ({ exec: execMock }));
vi.mock("node:child_process", () => ({ exec: execMock, execFile: vi.fn() }));
vi.mock("node:fs", () => ({ existsSync: existsSyncMock }));
vi.mock("../worktree-hooks.js", () => ({
installTaskWorktreeIdentityGuard: vi.fn().mockResolvedValue(undefined),

View File

@@ -27,7 +27,7 @@ const { execMock, accessMock, rmMock, existsSyncMock, parseIndexLockPathMock, cl
};
});
vi.mock("node:child_process", () => ({ exec: execMock }));
vi.mock("node:child_process", () => ({ exec: execMock, execFile: vi.fn() }));
vi.mock("node:fs", () => ({ existsSync: existsSyncMock }));
vi.mock("node:fs/promises", () => ({ access: accessMock, rm: rmMock }));
vi.mock("../branch-conflicts.js", () => ({

View File

@@ -5,7 +5,7 @@ import { join } from "node:path";
import { describe, expect, it, vi } from "vitest";
const { execMock } = vi.hoisted(() => ({ execMock: vi.fn() }));
vi.mock("node:child_process", () => ({ exec: execMock }));
vi.mock("node:child_process", () => ({ exec: execMock, execFile: vi.fn() }));
import { writeFileAtomic } from "../worktree-hooks.js";

View File

@@ -21,7 +21,11 @@ vi.mock("node:child_process", async () => {
}
}
});
const execFileFn: any = vi.fn((file: string, args: string[] | undefined, opts: any, cb: any) =>
execFn([file, ...(Array.isArray(args) ? args : [])].join(" "), opts, cb),
);
execFn[promisify.custom] = (cmd: string, opts?: any) =>
new Promise((resolve, reject) => {
@@ -35,7 +39,9 @@ vi.mock("node:child_process", async () => {
}
});
});
return { execSync: execSyncFn, exec: execFn };
execFileFn[promisify.custom] = (file: string, args?: string[], opts?: any) =>
execFn[promisify.custom]([file, ...(Array.isArray(args) ? args : [])].join(" "), opts);
return { execSync: execSyncFn, exec: execFn, execFile: execFileFn };
});
vi.mock("../worktree-desktop-artifacts.js", () => ({

View File

@@ -10,7 +10,7 @@ const { execMock } = vi.hoisted(() => {
return { execMock: mock };
});
vi.mock("node:child_process", () => ({ exec: execMock }));
vi.mock("node:child_process", () => ({ exec: execMock, execFile: vi.fn() }));
describe("worktree-stale-lock", () => {
beforeEach(() => {

View File

@@ -7,7 +7,7 @@ const { execMock } = vi.hoisted(() => {
return { execMock: mock };
});
vi.mock("node:child_process", () => ({ exec: execMock }));
vi.mock("node:child_process", () => ({ exec: execMock, execFile: vi.fn() }));
describe("worktree-stale-registration", () => {
beforeEach(() => {