mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-17 01:21:10 -07:00
Fix tests to wrap all calls changing the UI with act. (#12268)
This commit is contained in:
@@ -5,7 +5,8 @@
|
||||
*/
|
||||
|
||||
import { act } from 'react';
|
||||
import { render } from 'ink-testing-library';
|
||||
import { render } from '../../test-utils/render.js';
|
||||
import { waitFor } from '../../test-utils/async.js';
|
||||
import {
|
||||
vi,
|
||||
describe,
|
||||
@@ -18,13 +19,30 @@ import {
|
||||
|
||||
const mockIsBinary = vi.hoisted(() => vi.fn());
|
||||
const mockShellExecutionService = vi.hoisted(() => vi.fn());
|
||||
vi.mock('@google/gemini-cli-core', () => ({
|
||||
ShellExecutionService: { execute: mockShellExecutionService },
|
||||
isBinary: mockIsBinary,
|
||||
}));
|
||||
vi.mock('fs');
|
||||
vi.mock('os');
|
||||
vi.mock('crypto');
|
||||
vi.mock('@google/gemini-cli-core', async (importOriginal) => {
|
||||
const actual =
|
||||
await importOriginal<typeof import('@google/gemini-cli-core')>();
|
||||
return {
|
||||
...actual,
|
||||
ShellExecutionService: { execute: mockShellExecutionService },
|
||||
isBinary: mockIsBinary,
|
||||
};
|
||||
});
|
||||
vi.mock('node:fs');
|
||||
vi.mock('node:os', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import('node:os')>();
|
||||
const mocked = {
|
||||
...actual,
|
||||
homedir: vi.fn(() => '/home/user'),
|
||||
platform: vi.fn(() => 'linux'),
|
||||
tmpdir: vi.fn(() => '/tmp'),
|
||||
};
|
||||
return {
|
||||
...mocked,
|
||||
default: mocked,
|
||||
};
|
||||
});
|
||||
vi.mock('node:crypto');
|
||||
vi.mock('../utils/textUtils.js');
|
||||
|
||||
import {
|
||||
@@ -134,7 +152,7 @@ describe('useShellCommandProcessor', () => {
|
||||
it('should initiate command execution and set pending state', async () => {
|
||||
const { result } = renderProcessorHook();
|
||||
|
||||
act(() => {
|
||||
await act(async () => {
|
||||
result.current.handleShellCommand('ls -l', new AbortController().signal);
|
||||
});
|
||||
|
||||
@@ -233,7 +251,7 @@ describe('useShellCommandProcessor', () => {
|
||||
|
||||
it('should update UI for text streams (non-interactive)', async () => {
|
||||
const { result } = renderProcessorHook();
|
||||
act(() => {
|
||||
await act(async () => {
|
||||
result.current.handleShellCommand(
|
||||
'stream',
|
||||
new AbortController().signal,
|
||||
@@ -256,7 +274,7 @@ describe('useShellCommandProcessor', () => {
|
||||
|
||||
// Wait for the async PID update to happen.
|
||||
// Call 1: Initial, Call 2: PID update
|
||||
await vi.waitFor(() => {
|
||||
await waitFor(() => {
|
||||
expect(setPendingHistoryItemMock).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
@@ -365,7 +383,7 @@ describe('useShellCommandProcessor', () => {
|
||||
vi.mocked(os.platform).mockReturnValue('win32');
|
||||
const { result } = renderProcessorHook();
|
||||
|
||||
act(() => {
|
||||
await act(async () => {
|
||||
result.current.handleShellCommand('dir', new AbortController().signal);
|
||||
});
|
||||
|
||||
@@ -377,6 +395,11 @@ describe('useShellCommandProcessor', () => {
|
||||
false,
|
||||
expect.any(Object),
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
resolveExecutionPromise(createMockServiceResult());
|
||||
});
|
||||
await act(async () => await onExecMock.mock.calls[0][0]);
|
||||
});
|
||||
|
||||
it('should handle command abort and display cancelled status', async () => {
|
||||
@@ -559,23 +582,21 @@ describe('useShellCommandProcessor', () => {
|
||||
it('should set activeShellPtyId when a command with a PID starts', async () => {
|
||||
const { result } = renderProcessorHook();
|
||||
|
||||
act(() => {
|
||||
await act(async () => {
|
||||
result.current.handleShellCommand('ls', new AbortController().signal);
|
||||
});
|
||||
|
||||
await vi.waitFor(() => {
|
||||
expect(result.current.activeShellPtyId).toBe(12345);
|
||||
});
|
||||
expect(result.current.activeShellPtyId).toBe(12345);
|
||||
});
|
||||
|
||||
it('should update the pending history item with the ptyId', async () => {
|
||||
const { result } = renderProcessorHook();
|
||||
|
||||
act(() => {
|
||||
await act(async () => {
|
||||
result.current.handleShellCommand('ls', new AbortController().signal);
|
||||
});
|
||||
|
||||
await vi.waitFor(() => {
|
||||
await waitFor(() => {
|
||||
// Wait for the second call which is the functional update
|
||||
expect(setPendingHistoryItemMock).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
@@ -594,16 +615,14 @@ describe('useShellCommandProcessor', () => {
|
||||
it('should reset activeShellPtyId to null after successful execution', async () => {
|
||||
const { result } = renderProcessorHook();
|
||||
|
||||
act(() => {
|
||||
await act(async () => {
|
||||
result.current.handleShellCommand('ls', new AbortController().signal);
|
||||
});
|
||||
const execPromise = onExecMock.mock.calls[0][0];
|
||||
|
||||
await vi.waitFor(() => {
|
||||
expect(result.current.activeShellPtyId).toBe(12345);
|
||||
});
|
||||
expect(result.current.activeShellPtyId).toBe(12345);
|
||||
|
||||
act(() => {
|
||||
await act(async () => {
|
||||
resolveExecutionPromise(createMockServiceResult());
|
||||
});
|
||||
await act(async () => await execPromise);
|
||||
@@ -614,7 +633,7 @@ describe('useShellCommandProcessor', () => {
|
||||
it('should reset activeShellPtyId to null after failed execution', async () => {
|
||||
const { result } = renderProcessorHook();
|
||||
|
||||
act(() => {
|
||||
await act(async () => {
|
||||
result.current.handleShellCommand(
|
||||
'bad-cmd',
|
||||
new AbortController().signal,
|
||||
@@ -622,11 +641,9 @@ describe('useShellCommandProcessor', () => {
|
||||
});
|
||||
const execPromise = onExecMock.mock.calls[0][0];
|
||||
|
||||
await vi.waitFor(() => {
|
||||
expect(result.current.activeShellPtyId).toBe(12345);
|
||||
});
|
||||
expect(result.current.activeShellPtyId).toBe(12345);
|
||||
|
||||
act(() => {
|
||||
await act(async () => {
|
||||
resolveExecutionPromise(createMockServiceResult({ exitCode: 1 }));
|
||||
});
|
||||
await act(async () => await execPromise);
|
||||
@@ -638,7 +655,7 @@ describe('useShellCommandProcessor', () => {
|
||||
let rejectResultPromise: (reason?: unknown) => void;
|
||||
mockShellExecutionService.mockImplementation(() =>
|
||||
Promise.resolve({
|
||||
pid: 1234_5,
|
||||
pid: 12345,
|
||||
result: new Promise((_, reject) => {
|
||||
rejectResultPromise = reject;
|
||||
}),
|
||||
@@ -646,16 +663,14 @@ describe('useShellCommandProcessor', () => {
|
||||
);
|
||||
const { result } = renderProcessorHook();
|
||||
|
||||
act(() => {
|
||||
await act(async () => {
|
||||
result.current.handleShellCommand('cmd', new AbortController().signal);
|
||||
});
|
||||
const execPromise = onExecMock.mock.calls[0][0];
|
||||
|
||||
await vi.waitFor(() => {
|
||||
expect(result.current.activeShellPtyId).toBe(12345);
|
||||
});
|
||||
expect(result.current.activeShellPtyId).toBe(12345);
|
||||
|
||||
act(() => {
|
||||
await act(async () => {
|
||||
rejectResultPromise(new Error('Failure'));
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user