mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-05 19:01:12 -07:00
Improve test coverage for cli/src/ui/components (#13598)
This commit is contained in:
167
packages/cli/src/ui/components/EditorSettingsDialog.test.tsx
Normal file
167
packages/cli/src/ui/components/EditorSettingsDialog.test.tsx
Normal file
@@ -0,0 +1,167 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { render } from '../../test-utils/render.js';
|
||||
import { EditorSettingsDialog } from './EditorSettingsDialog.js';
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { SettingScope } from '../../config/settings.js';
|
||||
import type { LoadedSettings } from '../../config/settings.js';
|
||||
import { KeypressProvider } from '../contexts/KeypressContext.js';
|
||||
import { act } from 'react';
|
||||
import { waitFor } from '../../test-utils/async.js';
|
||||
|
||||
// Mock editorSettingsManager
|
||||
vi.mock('../editors/editorSettingsManager.js', () => ({
|
||||
editorSettingsManager: {
|
||||
getAvailableEditorDisplays: () => [
|
||||
{ name: 'VS Code', type: 'vscode', disabled: false },
|
||||
{ name: 'Vim', type: 'vim', disabled: false },
|
||||
],
|
||||
},
|
||||
}));
|
||||
|
||||
describe('EditorSettingsDialog', () => {
|
||||
const mockSettings = {
|
||||
forScope: (scope: string) => ({
|
||||
settings: {
|
||||
general: {
|
||||
preferredEditor: scope === SettingScope.User ? 'vscode' : undefined,
|
||||
},
|
||||
},
|
||||
}),
|
||||
merged: {
|
||||
general: {
|
||||
preferredEditor: 'vscode',
|
||||
},
|
||||
},
|
||||
} as unknown as LoadedSettings;
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
const renderWithProvider = (ui: React.ReactNode) =>
|
||||
render(<KeypressProvider>{ui}</KeypressProvider>);
|
||||
|
||||
it('renders correctly', () => {
|
||||
const { lastFrame } = renderWithProvider(
|
||||
<EditorSettingsDialog
|
||||
onSelect={vi.fn()}
|
||||
settings={mockSettings}
|
||||
onExit={vi.fn()}
|
||||
/>,
|
||||
);
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('calls onSelect when an editor is selected', () => {
|
||||
const onSelect = vi.fn();
|
||||
const { lastFrame } = renderWithProvider(
|
||||
<EditorSettingsDialog
|
||||
onSelect={onSelect}
|
||||
settings={mockSettings}
|
||||
onExit={vi.fn()}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(lastFrame()).toContain('VS Code');
|
||||
});
|
||||
|
||||
it('switches focus between editor and scope sections on Tab', async () => {
|
||||
const { lastFrame, stdin } = renderWithProvider(
|
||||
<EditorSettingsDialog
|
||||
onSelect={vi.fn()}
|
||||
settings={mockSettings}
|
||||
onExit={vi.fn()}
|
||||
/>,
|
||||
);
|
||||
|
||||
// Initial focus on editor
|
||||
expect(lastFrame()).toContain('> Select Editor');
|
||||
expect(lastFrame()).not.toContain('> Apply To');
|
||||
|
||||
// Press Tab
|
||||
await act(async () => {
|
||||
stdin.write('\t');
|
||||
});
|
||||
|
||||
// Focus should be on scope
|
||||
await waitFor(() => {
|
||||
const frame = lastFrame() || '';
|
||||
if (!frame.includes('> Apply To')) {
|
||||
console.log(
|
||||
'Waiting for scope focus. Current frame:',
|
||||
JSON.stringify(frame),
|
||||
);
|
||||
}
|
||||
expect(frame).toContain('> Apply To');
|
||||
});
|
||||
expect(lastFrame()).toContain(' Select Editor');
|
||||
|
||||
// Press Tab again
|
||||
await act(async () => {
|
||||
stdin.write('\t');
|
||||
});
|
||||
|
||||
// Focus should be back on editor
|
||||
await waitFor(() => {
|
||||
expect(lastFrame()).toContain('> Select Editor');
|
||||
});
|
||||
});
|
||||
|
||||
it('calls onExit when Escape is pressed', async () => {
|
||||
const onExit = vi.fn();
|
||||
const { stdin } = renderWithProvider(
|
||||
<EditorSettingsDialog
|
||||
onSelect={vi.fn()}
|
||||
settings={mockSettings}
|
||||
onExit={onExit}
|
||||
/>,
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
stdin.write('\u001B'); // Escape
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(onExit).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('shows modified message when setting exists in other scope', () => {
|
||||
const settingsWithOtherScope = {
|
||||
forScope: (_scope: string) => ({
|
||||
settings: {
|
||||
general: {
|
||||
preferredEditor: 'vscode', // Both scopes have it set
|
||||
},
|
||||
},
|
||||
}),
|
||||
merged: {
|
||||
general: {
|
||||
preferredEditor: 'vscode',
|
||||
},
|
||||
},
|
||||
} as unknown as LoadedSettings;
|
||||
|
||||
const { lastFrame } = renderWithProvider(
|
||||
<EditorSettingsDialog
|
||||
onSelect={vi.fn()}
|
||||
settings={settingsWithOtherScope}
|
||||
onExit={vi.fn()}
|
||||
/>,
|
||||
);
|
||||
|
||||
const frame = lastFrame() || '';
|
||||
if (!frame.includes('(Also modified')) {
|
||||
console.log(
|
||||
'Modified message test failure. Frame:',
|
||||
JSON.stringify(frame),
|
||||
);
|
||||
}
|
||||
expect(frame).toContain('(Also modified');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user