fix: Windows test compat — shell quoting, line endings, binary names

- Replace single-quoted git commit messages in worktree tests with
  double quotes (cmd.exe doesn't treat single quotes as delimiters)
- Trim stdout in spawn tests to handle \r\n vs \n
- Use nonexistent binary name in executable test not-found case
This commit is contained in:
Mohamed Boudra
2026-04-13 20:36:59 +07:00
parent 6dfcb4daa9
commit 61201d68a6
3 changed files with 38 additions and 37 deletions
+2 -1
View File
@@ -49,6 +49,7 @@ async function loadExecutableModule(params?: {
describe("findExecutable", () => { describe("findExecutable", () => {
const originalPlatform = process.platform; const originalPlatform = process.platform;
const missingBinaryName = "nonexistent-binary-xyz-12345";
function setPlatform(value: string) { function setPlatform(value: string) {
Object.defineProperty(process, "platform", { value, writable: true }); Object.defineProperty(process, "platform", { value, writable: true });
@@ -118,7 +119,7 @@ describe("findExecutable", () => {
}, },
}); });
await expect(findExecutable("codex")).resolves.toBeNull(); await expect(findExecutable(missingBinaryName)).resolves.toBeNull();
}); });
test("on Windows, falls back to the first extensionless candidate when needed", async () => { test("on Windows, falls back to the first extensionless candidate when needed", async () => {
+8 -8
View File
@@ -16,10 +16,10 @@ describe("execCommand", () => {
}); });
test("returns stdout and stderr for a successful command", async () => { test("returns stdout and stderr for a successful command", async () => {
await expect(execCommand("echo", ["hello"])).resolves.toEqual({ const result = await execCommand("echo", ["hello"]);
stdout: "hello\n",
stderr: "", expect(result.stdout.trim()).toBe("hello");
}); expect(result.stderr).toBe("");
}); });
test("rejects when the command times out", async () => { test("rejects when the command times out", async () => {
@@ -46,9 +46,9 @@ describe("execCommand", () => {
} }
: { command: "pwd", args: [] }; : { command: "pwd", args: [] };
await expect(execCommand(command.command, command.args, { cwd })).resolves.toEqual({ const result = await execCommand(command.command, command.args, { cwd });
stdout: `${cwd}\n`,
stderr: "", expect(result.stdout.trim()).toBe(cwd);
}); expect(result.stderr).toBe("");
}); });
}); });
+28 -28
View File
@@ -40,11 +40,11 @@ describe("createWorktree", () => {
// Create a git repo with an initial commit // Create a git repo with an initial commit
mkdirSync(repoDir, { recursive: true }); mkdirSync(repoDir, { recursive: true });
execSync("git init -b main", { cwd: repoDir }); execSync("git init -b main", { cwd: repoDir });
execSync("git config user.email 'test@test.com'", { cwd: repoDir }); execSync('git config user.email "test@test.com"', { cwd: repoDir });
execSync("git config user.name 'Test'", { cwd: repoDir }); execSync('git config user.name "Test"', { cwd: repoDir });
execSync("echo 'hello' > file.txt", { cwd: repoDir }); execSync('echo "hello" > file.txt', { cwd: repoDir });
execSync("git add .", { cwd: repoDir }); execSync("git add .", { cwd: repoDir });
execSync("git -c commit.gpgsign=false commit -m 'initial'", { cwd: repoDir }); execSync('git -c commit.gpgsign=false commit -m "initial"', { cwd: repoDir });
}); });
afterEach(() => { afterEach(() => {
@@ -78,11 +78,11 @@ describe("createWorktree", () => {
const varPaseoHome = join(varTempDir, "paseo-home"); const varPaseoHome = join(varTempDir, "paseo-home");
mkdirSync(varRepoDir, { recursive: true }); mkdirSync(varRepoDir, { recursive: true });
execSync("git init -b main", { cwd: varRepoDir }); execSync("git init -b main", { cwd: varRepoDir });
execSync("git config user.email 'test@test.com'", { cwd: varRepoDir }); execSync('git config user.email "test@test.com"', { cwd: varRepoDir });
execSync("git config user.name 'Test'", { cwd: varRepoDir }); execSync('git config user.name "Test"', { cwd: varRepoDir });
execSync("echo 'hello' > file.txt", { cwd: varRepoDir }); execSync('echo "hello" > file.txt', { cwd: varRepoDir });
execSync("git add .", { cwd: varRepoDir }); execSync("git add .", { cwd: varRepoDir });
execSync("git -c commit.gpgsign=false commit -m 'initial'", { cwd: varRepoDir }); execSync('git -c commit.gpgsign=false commit -m "initial"', { cwd: varRepoDir });
const result = await createWorktree({ const result = await createWorktree({
branchName: "main", branchName: "main",
@@ -163,19 +163,19 @@ describe("createWorktree", () => {
execSync("git push -u origin main", { cwd: repoDir }); execSync("git push -u origin main", { cwd: repoDir });
execSync(`git clone ${remoteDir} ${remoteCloneDir}`); execSync(`git clone ${remoteDir} ${remoteCloneDir}`);
execSync("git config user.email 'test@test.com'", { cwd: remoteCloneDir }); execSync('git config user.email "test@test.com"', { cwd: remoteCloneDir });
execSync("git config user.name 'Test'", { cwd: remoteCloneDir }); execSync('git config user.name "Test"', { cwd: remoteCloneDir });
execSync("git checkout -B main origin/main", { cwd: remoteCloneDir }); execSync("git checkout -B main origin/main", { cwd: remoteCloneDir });
writeFileSync(join(remoteCloneDir, "file.txt"), "from-origin\n"); writeFileSync(join(remoteCloneDir, "file.txt"), "from-origin\n");
execSync("git add file.txt", { cwd: remoteCloneDir }); execSync("git add file.txt", { cwd: remoteCloneDir });
execSync("git -c commit.gpgsign=false commit -m 'advance origin main'", { execSync('git -c commit.gpgsign=false commit -m "advance origin main"', {
cwd: remoteCloneDir, cwd: remoteCloneDir,
}); });
execSync("git push origin main", { cwd: remoteCloneDir }); execSync("git push origin main", { cwd: remoteCloneDir });
writeFileSync(join(repoDir, "file.txt"), "from-local\n"); writeFileSync(join(repoDir, "file.txt"), "from-local\n");
execSync("git add file.txt", { cwd: repoDir }); execSync("git add file.txt", { cwd: repoDir });
execSync("git -c commit.gpgsign=false commit -m 'advance local main'", { cwd: repoDir }); execSync('git -c commit.gpgsign=false commit -m "advance local main"', { cwd: repoDir });
execSync("git fetch origin", { cwd: repoDir }); execSync("git fetch origin", { cwd: repoDir });
@@ -194,7 +194,7 @@ describe("createWorktree", () => {
it("falls back to local {branch} when origin/{branch} does not exist", async () => { it("falls back to local {branch} when origin/{branch} does not exist", async () => {
writeFileSync(join(repoDir, "file.txt"), "from-local-only\n"); writeFileSync(join(repoDir, "file.txt"), "from-local-only\n");
execSync("git add file.txt", { cwd: repoDir }); execSync("git add file.txt", { cwd: repoDir });
execSync("git -c commit.gpgsign=false commit -m 'advance local main only'", { cwd: repoDir }); execSync('git -c commit.gpgsign=false commit -m "advance local main only"', { cwd: repoDir });
const result = await createWorktree({ const result = await createWorktree({
branchName: "prefer-local-fallback-feature", branchName: "prefer-local-fallback-feature",
@@ -286,7 +286,7 @@ describe("createWorktree", () => {
}, },
}; };
writeFileSync(join(repoDir, "paseo.json"), JSON.stringify(paseoConfig)); writeFileSync(join(repoDir, "paseo.json"), JSON.stringify(paseoConfig));
execSync("git add paseo.json && git -c commit.gpgsign=false commit -m 'add paseo.json'", { execSync('git add paseo.json && git -c commit.gpgsign=false commit -m "add paseo.json"', {
cwd: repoDir, cwd: repoDir,
}); });
@@ -320,7 +320,7 @@ describe("createWorktree", () => {
}, },
}; };
writeFileSync(join(repoDir, "paseo.json"), JSON.stringify(paseoConfig)); writeFileSync(join(repoDir, "paseo.json"), JSON.stringify(paseoConfig));
execSync("git add paseo.json && git -c commit.gpgsign=false commit -m 'add paseo.json'", { execSync('git add paseo.json && git -c commit.gpgsign=false commit -m "add paseo.json"', {
cwd: repoDir, cwd: repoDir,
}); });
@@ -344,7 +344,7 @@ describe("createWorktree", () => {
}, },
}; };
writeFileSync(join(repoDir, "paseo.json"), JSON.stringify(paseoConfig)); writeFileSync(join(repoDir, "paseo.json"), JSON.stringify(paseoConfig));
execSync("git add paseo.json && git -c commit.gpgsign=false commit -m 'add streaming setup'", { execSync('git add paseo.json && git -c commit.gpgsign=false commit -m "add streaming setup"', {
cwd: repoDir, cwd: repoDir,
}); });
@@ -434,7 +434,7 @@ describe("createWorktree", () => {
}, },
}; };
writeFileSync(join(repoDir, "paseo.json"), JSON.stringify(paseoConfig)); writeFileSync(join(repoDir, "paseo.json"), JSON.stringify(paseoConfig));
execSync("git add paseo.json && git -c commit.gpgsign=false commit -m 'add paseo.json'", { execSync('git add paseo.json && git -c commit.gpgsign=false commit -m "add paseo.json"', {
cwd: repoDir, cwd: repoDir,
}); });
@@ -504,11 +504,11 @@ describe("paseo worktree manager", () => {
mkdirSync(repoDir, { recursive: true }); mkdirSync(repoDir, { recursive: true });
execSync("git init -b main", { cwd: repoDir }); execSync("git init -b main", { cwd: repoDir });
execSync("git config user.email 'test@test.com'", { cwd: repoDir }); execSync('git config user.email "test@test.com"', { cwd: repoDir });
execSync("git config user.name 'Test'", { cwd: repoDir }); execSync('git config user.name "Test"', { cwd: repoDir });
execSync("echo 'hello' > file.txt", { cwd: repoDir }); execSync('echo "hello" > file.txt', { cwd: repoDir });
execSync("git add .", { cwd: repoDir }); execSync("git add .", { cwd: repoDir });
execSync("git -c commit.gpgsign=false commit -m 'initial'", { cwd: repoDir }); execSync('git -c commit.gpgsign=false commit -m "initial"', { cwd: repoDir });
}); });
afterEach(() => { afterEach(() => {
@@ -522,11 +522,11 @@ describe("paseo worktree manager", () => {
for (const repo of [repoA, repoB]) { for (const repo of [repoA, repoB]) {
mkdirSync(repo, { recursive: true }); mkdirSync(repo, { recursive: true });
execSync("git init -b main", { cwd: repo }); execSync("git init -b main", { cwd: repo });
execSync("git config user.email 'test@test.com'", { cwd: repo }); execSync('git config user.email "test@test.com"', { cwd: repo });
execSync("git config user.name 'Test'", { cwd: repo }); execSync('git config user.name "Test"', { cwd: repo });
execSync("echo 'hello' > file.txt", { cwd: repo }); execSync('echo "hello" > file.txt', { cwd: repo });
execSync("git add .", { cwd: repo }); execSync("git add .", { cwd: repo });
execSync("git -c commit.gpgsign=false commit -m 'initial'", { cwd: repo }); execSync('git -c commit.gpgsign=false commit -m "initial"', { cwd: repo });
} }
const fromRepoA = await createWorktree({ const fromRepoA = await createWorktree({
@@ -615,7 +615,7 @@ describe("paseo worktree manager", () => {
}; };
writeFileSync(join(repoDir, "paseo.json"), JSON.stringify(paseoConfig)); writeFileSync(join(repoDir, "paseo.json"), JSON.stringify(paseoConfig));
execSync( execSync(
"git add paseo.json && git -c commit.gpgsign=false commit -m 'add teardown commands'", 'git add paseo.json && git -c commit.gpgsign=false commit -m "add teardown commands"',
{ {
cwd: repoDir, cwd: repoDir,
}, },
@@ -654,7 +654,7 @@ describe("paseo worktree manager", () => {
}; };
writeFileSync(join(repoDir, "paseo.json"), JSON.stringify(paseoConfig)); writeFileSync(join(repoDir, "paseo.json"), JSON.stringify(paseoConfig));
execSync( execSync(
"git add paseo.json && git -c commit.gpgsign=false commit -m 'add teardown port logging'", 'git add paseo.json && git -c commit.gpgsign=false commit -m "add teardown port logging"',
{ cwd: repoDir }, { cwd: repoDir },
); );
@@ -683,7 +683,7 @@ describe("paseo worktree manager", () => {
}; };
writeFileSync(join(repoDir, "paseo.json"), JSON.stringify(paseoConfig)); writeFileSync(join(repoDir, "paseo.json"), JSON.stringify(paseoConfig));
execSync( execSync(
"git add paseo.json && git -c commit.gpgsign=false commit -m 'add failing teardown commands'", 'git add paseo.json && git -c commit.gpgsign=false commit -m "add failing teardown commands"',
{ cwd: repoDir }, { cwd: repoDir },
); );