test: fix tests failing due to close event changes in childProcessFallback and add missing config mocks

This commit is contained in:
Spencer
2026-04-09 22:08:54 +00:00
parent 8dd39fbf9e
commit c8f94e952c
2 changed files with 25 additions and 28 deletions
@@ -607,6 +607,8 @@ describe('ToolExecutor', () => {
it('should preserve temporary file when fullOutputFilePath is provided but output is not truncated', async () => {
// 1. Setup Config for Truncation
vi.spyOn(config, 'getTruncateToolOutputThreshold').mockReturnValue(100);
vi.spyOn(config.storage, 'getProjectTempDir').mockReturnValue('/tmp');
vi.spyOn(config, 'getSessionId').mockReturnValue('test-session-id');
const unlinkSpy = vi
.spyOn(fsPromises, 'unlink')
.mockResolvedValue(undefined);
@@ -652,7 +654,7 @@ describe('ToolExecutor', () => {
SHELL_TOOL_NAME,
'call-short-full',
expect.any(String),
expect.any(String),
'test-session-id',
);
expect(unlinkSpy).not.toHaveBeenCalled();
expect(fileUtils.formatTruncatedToolOutput).not.toHaveBeenCalled();
@@ -1327,7 +1327,7 @@ describe('ShellExecutionService child_process fallback', () => {
const { result, handle } = await simulateExecution('ls -l', (cp) => {
cp.stdout?.emit('data', Buffer.from('file1.txt\n'));
cp.stderr?.emit('data', Buffer.from('a warning'));
cp.emit('exit', 0, null);
cp.emit('close', 0, null);
cp.emit('close', 0, null);
});
@@ -1364,7 +1364,7 @@ describe('ShellExecutionService child_process fallback', () => {
it('should strip ANSI color codes from output', async () => {
const { result } = await simulateExecution('ls --color=auto', (cp) => {
cp.stdout?.emit('data', Buffer.from('a\u001b[31mred\u001b[0mword'));
cp.emit('exit', 0, null);
cp.emit('close', 0, null);
cp.emit('close', 0, null);
});
@@ -1385,7 +1385,7 @@ describe('ShellExecutionService child_process fallback', () => {
const multiByteChar = Buffer.from('你好', 'utf-8');
cp.stdout?.emit('data', multiByteChar.slice(0, 2));
cp.stdout?.emit('data', multiByteChar.slice(2));
cp.emit('exit', 0, null);
cp.emit('close', 0, null);
cp.emit('close', 0, null);
});
expect(result.output.trim()).toBe('你好');
@@ -1393,7 +1393,7 @@ describe('ShellExecutionService child_process fallback', () => {
it('should handle commands with no output', async () => {
const { result } = await simulateExecution('touch file', (cp) => {
cp.emit('exit', 0, null);
cp.emit('close', 0, null);
cp.emit('close', 0, null);
});
@@ -1415,7 +1415,7 @@ describe('ShellExecutionService child_process fallback', () => {
cp.stdout?.emit('data', Buffer.from(chunk1));
cp.stdout?.emit('data', Buffer.from(chunk2));
cp.stdout?.emit('data', Buffer.from(chunk3));
cp.emit('exit', 0, null);
cp.emit('close', 0, null);
});
const truncationMessage =
@@ -1440,7 +1440,7 @@ describe('ShellExecutionService child_process fallback', () => {
it('should capture a non-zero exit code and format output correctly', async () => {
const { result } = await simulateExecution('a-bad-command', (cp) => {
cp.stderr?.emit('data', Buffer.from('command not found'));
cp.emit('exit', 127, null);
cp.emit('close', 127, null);
cp.emit('close', 127, null);
});
@@ -1451,7 +1451,7 @@ describe('ShellExecutionService child_process fallback', () => {
it('should capture a termination signal', async () => {
const { result } = await simulateExecution('long-process', (cp) => {
cp.emit('exit', null, 'SIGTERM');
cp.emit('close', null, 'SIGTERM');
cp.emit('close', null, 'SIGTERM');
});
@@ -1463,7 +1463,7 @@ describe('ShellExecutionService child_process fallback', () => {
const spawnError = new Error('spawn EACCES');
const { result } = await simulateExecution('protected-cmd', (cp) => {
cp.emit('error', spawnError);
cp.emit('exit', 1, null);
cp.emit('close', 1, null);
cp.emit('close', 1, null);
});
@@ -1506,11 +1506,11 @@ describe('ShellExecutionService child_process fallback', () => {
(cp, abortController) => {
abortController.abort();
if (expectedExit.signal) {
cp.emit('exit', null, expectedExit.signal);
cp.emit('close', null, expectedExit.signal);
cp.emit('close', null, expectedExit.signal);
}
if (typeof expectedExit.code === 'number') {
cp.emit('exit', expectedExit.code, null);
cp.emit('close', expectedExit.code, null);
cp.emit('close', expectedExit.code, null);
}
},
@@ -1575,7 +1575,7 @@ describe('ShellExecutionService child_process fallback', () => {
);
// Finally, simulate the process exiting and await the result
mockChildProcess.emit('exit', null, 'SIGKILL');
mockChildProcess.emit('close', null, 'SIGKILL');
mockChildProcess.emit('close', null, 'SIGKILL');
const result = await handle.result;
@@ -1595,7 +1595,7 @@ describe('ShellExecutionService child_process fallback', () => {
await simulateExecution('cat image.png', (cp) => {
cp.stdout?.emit('data', binaryChunk1);
cp.stdout?.emit('data', binaryChunk2);
cp.emit('exit', 0, null);
cp.emit('close', 0, null);
});
// We don't check result here because result is not available in the test body as written
@@ -1625,7 +1625,6 @@ describe('ShellExecutionService child_process fallback', () => {
await simulateExecution('cat mixed_file', (cp) => {
cp.stdout?.emit('data', Buffer.from([0x00, 0x01, 0x02]));
cp.stdout?.emit('data', Buffer.from('more text'));
cp.emit('exit', 0, null);
cp.emit('close', 0, null);
});
@@ -1645,7 +1644,7 @@ describe('ShellExecutionService child_process fallback', () => {
it('should use powershell.exe on Windows', async () => {
mockPlatform.mockReturnValue('win32');
await simulateExecution('dir "foo bar"', (cp) => {
cp.emit('exit', 0, null);
cp.emit('close', 0, null);
});
expect(mockCpSpawn).toHaveBeenCalledWith(
@@ -1662,7 +1661,7 @@ describe('ShellExecutionService child_process fallback', () => {
it('should use bash and detached process group on Linux', async () => {
mockPlatform.mockReturnValue('linux');
await simulateExecution('ls "foo bar"', (cp) => {
cp.emit('exit', 0, null);
cp.emit('close', 0, null);
});
expect(mockCpSpawn).toHaveBeenCalledWith(
@@ -1772,7 +1771,7 @@ describe('ShellExecutionService execution method selection', () => {
);
// Simulate exit to allow promise to resolve
mockChildProcess.emit('exit', 0, null);
mockChildProcess.emit('close', 0, null);
const result = await handle.result;
expect(mockGetPty).not.toHaveBeenCalled();
@@ -1795,7 +1794,7 @@ describe('ShellExecutionService execution method selection', () => {
);
// Simulate exit to allow promise to resolve
mockChildProcess.emit('exit', 0, null);
mockChildProcess.emit('close', 0, null);
const result = await handle.result;
expect(mockGetPty).toHaveBeenCalled();
@@ -1859,10 +1858,6 @@ describe('ShellExecutionService environment variables', () => {
// Small delay to allow async ops to complete
setTimeout(() => mockPtyProcess.emit('exit', { exitCode, signal }), 0);
});
mockChildProcess.on('exit', (code, signal) => {
// Small delay to allow async ops to complete
setTimeout(() => mockChildProcess.emit('close', code, signal), 0);
});
});
afterEach(() => {
@@ -1925,7 +1920,7 @@ describe('ShellExecutionService environment variables', () => {
expect(cpEnv).toHaveProperty('GEMINI_CLI_TEST_VAR', 'test-value');
// Ensure child_process exits
mockChildProcess.emit('exit', 0, null);
mockChildProcess.emit('close', 0, null);
mockChildProcess.emit('close', 0, null);
await new Promise(process.nextTick);
});
@@ -1985,7 +1980,7 @@ describe('ShellExecutionService environment variables', () => {
expect(cpEnv).toHaveProperty('GEMINI_CLI_TEST_VAR', 'test-value');
// Ensure child_process exits
mockChildProcess.emit('exit', 0, null);
mockChildProcess.emit('close', 0, null);
mockChildProcess.emit('close', 0, null);
await new Promise(process.nextTick);
});
@@ -2033,7 +2028,7 @@ describe('ShellExecutionService environment variables', () => {
expect(cpEnv).toHaveProperty('GEMINI_CLI', '1');
// Ensure child_process exits
mockChildProcess.emit('exit', 0, null);
mockChildProcess.emit('close', 0, null);
mockChildProcess.emit('close', 0, null);
await new Promise(process.nextTick);
});
@@ -2090,7 +2085,7 @@ describe('ShellExecutionService environment variables', () => {
);
// Clean up
mockChild.emit('exit', 0, null);
mockChild.emit('close', 0, null);
mockChild.emit('close', 0, null);
await handle.result;
});
@@ -2139,7 +2134,7 @@ describe('ShellExecutionService environment variables', () => {
expect(cpEnv).toHaveProperty('GIT_CONFIG_VALUE_2', '');
// Ensure child_process exits
mockChildProcess.emit('exit', 0, null);
mockChildProcess.emit('close', 0, null);
mockChildProcess.emit('close', 0, null);
await new Promise(process.nextTick);
@@ -2179,7 +2174,7 @@ describe('ShellExecutionService environment variables', () => {
expect(cpEnv).not.toHaveProperty('GIT_CONFIG_COUNT');
// Ensure child_process exits
mockChildProcess.emit('exit', 0, null);
mockChildProcess.emit('close', 0, null);
mockChildProcess.emit('close', 0, null);
await new Promise(process.nextTick);