Skip to content

Commit 3aee8ce

Browse files
committed
test(child_process): add JS integration tests for exec and execFile
Add integration tests following the existing spawn test patterns: - exec: 5 tests (stdout, options, stderr, nonexistent, maxBuffer) - execFile: 7 tests (stdout, no args, options, nonexistent, exit code, maxBuffer, shell) All tests use cross-platform commands (IS_WINDOWS checks) to ensure compatibility with Windows CI.
1 parent 0975c6d commit 3aee8ce

File tree

1 file changed

+203
-1
lines changed

1 file changed

+203
-1
lines changed

tests/unit/child_process.test.ts

Lines changed: 203 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ it("node:child_process should be the same as child_process", () => {
99
expect(defaultImport).toStrictEqual(legacyImport);
1010
});
1111

12-
const { spawn } = defaultImport;
12+
const { spawn, exec, execFile } = defaultImport;
1313

1414
describe("spawn", () => {
1515
it("should spawn a child process", (done) => {
@@ -227,3 +227,205 @@ describe("spawn", () => {
227227
});
228228
});
229229
});
230+
231+
describe("exec", () => {
232+
it("should execute a shell command and return stdout", (done) => {
233+
exec("echo Hello", (error, stdout, stderr) => {
234+
try {
235+
expect(error).toBeNull();
236+
expect(stdout.trim()).toEqual("Hello");
237+
expect(stderr).toEqual("");
238+
done();
239+
} catch (err) {
240+
done(err);
241+
}
242+
});
243+
});
244+
245+
it("should execute a command with options", (done) => {
246+
const cwd = IS_WINDOWS ? process.cwd() : "/tmp";
247+
const pwdCmd = IS_WINDOWS ? "cd" : "pwd";
248+
exec(pwdCmd, { cwd }, (error, stdout, stderr) => {
249+
try {
250+
expect(error).toBeNull();
251+
if (IS_WINDOWS) {
252+
expect(stdout.trim().toLowerCase()).toContain(
253+
process.cwd().toLowerCase()
254+
);
255+
} else {
256+
expect(stdout.trim()).toContain("/tmp");
257+
}
258+
expect(stderr).toEqual("");
259+
done();
260+
} catch (err) {
261+
done(err);
262+
}
263+
});
264+
});
265+
266+
it("should capture stderr on command failure", (done) => {
267+
if (process.env._VIRTUAL_ENV) {
268+
// QEMU may handle errors differently
269+
return done();
270+
}
271+
// Use a command that writes to stderr and exits with error
272+
const cmd = IS_WINDOWS
273+
? "cmd /c exit 1"
274+
: "sh -c 'echo error >&2 && exit 1'";
275+
exec(cmd, (error, stdout, stderr) => {
276+
try {
277+
expect(error).not.toBeNull();
278+
expect(error!.code).toEqual(1);
279+
done();
280+
} catch (err) {
281+
done(err);
282+
}
283+
});
284+
});
285+
286+
it("should handle nonexistent commands", (done) => {
287+
if (process.env._VIRTUAL_ENV) {
288+
// QEMU may handle errors differently
289+
return done();
290+
}
291+
exec("nonexistent_command_12345", (error, stdout, stderr) => {
292+
try {
293+
expect(error).not.toBeNull();
294+
done();
295+
} catch (err) {
296+
done(err);
297+
}
298+
});
299+
});
300+
301+
it("should respect maxBuffer option", (done) => {
302+
// Generate output larger than maxBuffer
303+
const cmd = IS_WINDOWS
304+
? 'cmd /c "echo AAAAAAAAAA"'
305+
: "echo AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
306+
exec(cmd, { maxBuffer: 10 }, (error, stdout, stderr) => {
307+
try {
308+
expect(error).not.toBeNull();
309+
expect(error!.message).toContain("maxBuffer");
310+
done();
311+
} catch (err) {
312+
done(err);
313+
}
314+
});
315+
});
316+
});
317+
318+
describe("execFile", () => {
319+
it("should execute a file and return stdout", (done) => {
320+
execFile("echo", ["Hello", "World"], (error, stdout, stderr) => {
321+
try {
322+
expect(error).toBeNull();
323+
expect(stdout.trim()).toEqual("Hello World");
324+
expect(stderr).toEqual("");
325+
done();
326+
} catch (err) {
327+
done(err);
328+
}
329+
});
330+
});
331+
332+
it("should execute a file without arguments", (done) => {
333+
const cmd = IS_WINDOWS ? "cmd" : "pwd";
334+
const args = IS_WINDOWS ? ["/c", "cd"] : [];
335+
execFile(cmd, args, (error, stdout, stderr) => {
336+
try {
337+
expect(error).toBeNull();
338+
expect(stdout.length).toBeGreaterThan(0);
339+
expect(stderr).toEqual("");
340+
done();
341+
} catch (err) {
342+
done(err);
343+
}
344+
});
345+
});
346+
347+
it("should execute with options", (done) => {
348+
const cwd = IS_WINDOWS ? process.cwd() : "/tmp";
349+
const cmd = IS_WINDOWS ? "cmd" : "pwd";
350+
const args = IS_WINDOWS ? ["/c", "cd"] : [];
351+
execFile(cmd, args, { cwd }, (error, stdout, stderr) => {
352+
try {
353+
expect(error).toBeNull();
354+
if (IS_WINDOWS) {
355+
expect(stdout.trim().toLowerCase()).toContain(
356+
process.cwd().toLowerCase()
357+
);
358+
} else {
359+
expect(stdout.trim()).toContain("/tmp");
360+
}
361+
done();
362+
} catch (err) {
363+
done(err);
364+
}
365+
});
366+
});
367+
368+
it("should handle nonexistent executable", (done) => {
369+
if (process.env._VIRTUAL_ENV) {
370+
// QEMU may handle errors differently
371+
return done();
372+
}
373+
execFile("nonexistent_command_12345", [], (error, stdout, stderr) => {
374+
try {
375+
expect(error).not.toBeNull();
376+
done();
377+
} catch (err) {
378+
done(err);
379+
}
380+
});
381+
});
382+
383+
it("should handle executable failure with exit code", (done) => {
384+
if (process.env._VIRTUAL_ENV) {
385+
// QEMU may handle errors differently
386+
return done();
387+
}
388+
const cmd = IS_WINDOWS ? "cmd" : "sh";
389+
const args = IS_WINDOWS ? ["/c", "exit 42"] : ["-c", "exit 42"];
390+
execFile(cmd, args, (error, stdout, stderr) => {
391+
try {
392+
expect(error).not.toBeNull();
393+
expect(error!.code).toEqual(42);
394+
done();
395+
} catch (err) {
396+
done(err);
397+
}
398+
});
399+
});
400+
401+
it("should respect maxBuffer option", (done) => {
402+
execFile(
403+
"echo",
404+
["AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"],
405+
{ maxBuffer: 10 },
406+
(error, stdout, stderr) => {
407+
try {
408+
expect(error).not.toBeNull();
409+
expect(error!.message).toContain("maxBuffer");
410+
done();
411+
} catch (err) {
412+
done(err);
413+
}
414+
}
415+
);
416+
});
417+
418+
it("should execute with shell option", (done) => {
419+
// When shell is true, execFile should use shell to execute
420+
const cmd = IS_WINDOWS ? "echo %PATH%" : "echo $PATH";
421+
execFile(cmd, [], { shell: true }, (error, stdout, stderr) => {
422+
try {
423+
expect(error).toBeNull();
424+
expect(stdout.length).toBeGreaterThan(0);
425+
done();
426+
} catch (err) {
427+
done(err);
428+
}
429+
});
430+
});
431+
});

0 commit comments

Comments
 (0)