mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-16 09:01:17 -07:00
feat(core): improve shell execution service reliability (#10607)
This commit is contained in:
@@ -219,7 +219,7 @@ describe('useShellCommandProcessor', () => {
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
it('should throttle pending UI updates for text streams (non-interactive)', async () => {
|
||||
it('should update UI for text streams (non-interactive)', async () => {
|
||||
const { result } = renderProcessorHook();
|
||||
act(() => {
|
||||
result.current.handleShellCommand(
|
||||
@@ -243,61 +243,43 @@ describe('useShellCommandProcessor', () => {
|
||||
);
|
||||
|
||||
// Wait for the async PID update to happen.
|
||||
// Call 1: Initial, Call 2: PID update
|
||||
await vi.waitFor(() => {
|
||||
// It's called once for initial, and once for the PID update.
|
||||
expect(setPendingHistoryItemMock).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
// Simulate rapid output
|
||||
// Get the state after the PID update to feed into the stream updaters
|
||||
const pidUpdateFn = setPendingHistoryItemMock.mock.calls[1][0];
|
||||
const initialState = setPendingHistoryItemMock.mock.calls[0][0];
|
||||
const stateAfterPid = pidUpdateFn(initialState);
|
||||
|
||||
// Simulate first output chunk
|
||||
act(() => {
|
||||
mockShellOutputCallback({
|
||||
type: 'data',
|
||||
chunk: 'hello',
|
||||
});
|
||||
});
|
||||
// The count should still be 2, as throttling is in effect.
|
||||
expect(setPendingHistoryItemMock).toHaveBeenCalledTimes(2);
|
||||
// A UI update should have occurred.
|
||||
expect(setPendingHistoryItemMock).toHaveBeenCalledTimes(3);
|
||||
|
||||
// Simulate more rapid output
|
||||
const streamUpdateFn1 = setPendingHistoryItemMock.mock.calls[2][0];
|
||||
const stateAfterStream1 = streamUpdateFn1(stateAfterPid);
|
||||
expect(stateAfterStream1.tools[0].resultDisplay).toBe('hello');
|
||||
|
||||
// Simulate second output chunk
|
||||
act(() => {
|
||||
mockShellOutputCallback({
|
||||
type: 'data',
|
||||
chunk: ' world',
|
||||
});
|
||||
});
|
||||
expect(setPendingHistoryItemMock).toHaveBeenCalledTimes(2);
|
||||
// Another UI update should have occurred.
|
||||
expect(setPendingHistoryItemMock).toHaveBeenCalledTimes(4);
|
||||
|
||||
// Advance time, but the update won't happen until the next event
|
||||
await act(async () => {
|
||||
await vi.advanceTimersByTimeAsync(OUTPUT_UPDATE_INTERVAL_MS + 1);
|
||||
});
|
||||
|
||||
// Trigger one more event to cause the throttled update to fire.
|
||||
act(() => {
|
||||
mockShellOutputCallback({
|
||||
type: 'data',
|
||||
chunk: '',
|
||||
});
|
||||
});
|
||||
|
||||
// Now the cumulative update should have occurred.
|
||||
// Call 1: Initial, Call 2: PID update, Call 3: Throttled stream update
|
||||
expect(setPendingHistoryItemMock).toHaveBeenCalledTimes(3);
|
||||
|
||||
const streamUpdateFn = setPendingHistoryItemMock.mock.calls[2][0];
|
||||
if (!streamUpdateFn || typeof streamUpdateFn !== 'function') {
|
||||
throw new Error(
|
||||
'setPendingHistoryItem was not called with a stream updater function',
|
||||
);
|
||||
}
|
||||
|
||||
// Get the state after the PID update to feed into the stream updater
|
||||
const pidUpdateFn = setPendingHistoryItemMock.mock.calls[1][0];
|
||||
const initialState = setPendingHistoryItemMock.mock.calls[0][0];
|
||||
const stateAfterPid = pidUpdateFn(initialState);
|
||||
|
||||
const stateAfterStream = streamUpdateFn(stateAfterPid);
|
||||
expect(stateAfterStream.tools[0].resultDisplay).toBe('hello world');
|
||||
const streamUpdateFn2 = setPendingHistoryItemMock.mock.calls[3][0];
|
||||
const stateAfterStream2 = streamUpdateFn2(stateAfterStream1);
|
||||
expect(stateAfterStream2.tools[0].resultDisplay).toBe('hello world');
|
||||
});
|
||||
|
||||
it('should show binary progress messages correctly', async () => {
|
||||
|
||||
Reference in New Issue
Block a user