mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-15 00:21:09 -07:00
154 lines
3.9 KiB
TypeScript
154 lines
3.9 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2025 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
import { act } from 'react';
|
|
import type { EventEmitter } from 'node:events';
|
|
import { renderWithProviders } from '../../test-utils/render.js';
|
|
import { waitFor } from '../../test-utils/async.js';
|
|
import { ConfigInitDisplay } from './ConfigInitDisplay.js';
|
|
import {
|
|
describe,
|
|
it,
|
|
expect,
|
|
vi,
|
|
beforeEach,
|
|
afterEach,
|
|
type MockInstance,
|
|
} from 'vitest';
|
|
import {
|
|
CoreEvent,
|
|
MCPServerStatus,
|
|
type McpClient,
|
|
coreEvents,
|
|
} from '@google/gemini-cli-core';
|
|
import { Text } from 'ink';
|
|
|
|
// Mock GeminiSpinner
|
|
vi.mock('./GeminiSpinner.js', () => ({
|
|
GeminiSpinner: () => <Text>Spinner</Text>,
|
|
}));
|
|
|
|
describe('ConfigInitDisplay', () => {
|
|
let onSpy: MockInstance<EventEmitter['on']>;
|
|
|
|
beforeEach(() => {
|
|
onSpy = vi.spyOn(coreEvents as EventEmitter, 'on');
|
|
});
|
|
|
|
afterEach(() => {
|
|
vi.restoreAllMocks();
|
|
});
|
|
|
|
it('renders initial state', async () => {
|
|
const { lastFrame, waitUntilReady } = renderWithProviders(
|
|
<ConfigInitDisplay />,
|
|
);
|
|
await waitUntilReady();
|
|
expect(lastFrame()).toMatchSnapshot();
|
|
});
|
|
|
|
it('updates message on McpClientUpdate event', async () => {
|
|
let listener: ((clients?: Map<string, McpClient>) => void) | undefined;
|
|
onSpy.mockImplementation((event: unknown, fn: unknown) => {
|
|
if (event === CoreEvent.McpClientUpdate) {
|
|
listener = fn as (clients?: Map<string, McpClient>) => void;
|
|
}
|
|
return coreEvents;
|
|
});
|
|
|
|
const { lastFrame } = renderWithProviders(<ConfigInitDisplay />);
|
|
|
|
// Wait for listener to be registered
|
|
await waitFor(() => {
|
|
if (!listener) throw new Error('Listener not registered yet');
|
|
});
|
|
|
|
const mockClient1 = {
|
|
getStatus: () => MCPServerStatus.CONNECTED,
|
|
} as McpClient;
|
|
const mockClient2 = {
|
|
getStatus: () => MCPServerStatus.CONNECTING,
|
|
} as McpClient;
|
|
const clients = new Map<string, McpClient>([
|
|
['server1', mockClient1],
|
|
['server2', mockClient2],
|
|
]);
|
|
|
|
// Trigger the listener manually since we mocked the event emitter
|
|
act(() => {
|
|
listener!(clients);
|
|
});
|
|
|
|
// Wait for the UI to update
|
|
await waitFor(() => {
|
|
expect(lastFrame()).toMatchSnapshot();
|
|
});
|
|
});
|
|
|
|
it('truncates list of waiting servers if too many', async () => {
|
|
let listener: ((clients?: Map<string, McpClient>) => void) | undefined;
|
|
onSpy.mockImplementation((event: unknown, fn: unknown) => {
|
|
if (event === CoreEvent.McpClientUpdate) {
|
|
listener = fn as (clients?: Map<string, McpClient>) => void;
|
|
}
|
|
return coreEvents;
|
|
});
|
|
|
|
const { lastFrame } = renderWithProviders(<ConfigInitDisplay />);
|
|
|
|
await waitFor(() => {
|
|
if (!listener) throw new Error('Listener not registered yet');
|
|
});
|
|
|
|
const mockClientConnecting = {
|
|
getStatus: () => MCPServerStatus.CONNECTING,
|
|
} as McpClient;
|
|
|
|
const clients = new Map<string, McpClient>([
|
|
['s1', mockClientConnecting],
|
|
['s2', mockClientConnecting],
|
|
['s3', mockClientConnecting],
|
|
['s4', mockClientConnecting],
|
|
['s5', mockClientConnecting],
|
|
]);
|
|
|
|
act(() => {
|
|
listener!(clients);
|
|
});
|
|
|
|
await waitFor(() => {
|
|
expect(lastFrame()).toMatchSnapshot();
|
|
});
|
|
});
|
|
|
|
it('handles empty clients map', async () => {
|
|
let listener: ((clients?: Map<string, McpClient>) => void) | undefined;
|
|
onSpy.mockImplementation((event: unknown, fn: unknown) => {
|
|
if (event === CoreEvent.McpClientUpdate) {
|
|
listener = fn as (clients?: Map<string, McpClient>) => void;
|
|
}
|
|
return coreEvents;
|
|
});
|
|
|
|
const { lastFrame } = renderWithProviders(<ConfigInitDisplay />);
|
|
|
|
await waitFor(() => {
|
|
if (!listener) throw new Error('Listener not registered yet');
|
|
});
|
|
|
|
if (listener) {
|
|
const safeListener = listener;
|
|
act(() => {
|
|
safeListener(new Map());
|
|
});
|
|
}
|
|
|
|
await waitFor(() => {
|
|
expect(lastFrame()).toMatchSnapshot();
|
|
});
|
|
});
|
|
});
|