Files
gemini-cli/packages/cli/src/ui/commands/ideCommand.test.ts

205 lines
6.2 KiB
TypeScript
Raw Normal View History

/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import {
MockInstance,
vi,
describe,
it,
expect,
beforeEach,
afterEach,
} from 'vitest';
import { ideCommand } from './ideCommand.js';
import { type CommandContext } from './types.js';
2025-07-30 21:26:31 +00:00
import { type Config, DetectedIde } from '@google/gemini-cli-core';
import * as core from '@google/gemini-cli-core';
vi.mock('child_process');
vi.mock('glob');
2025-07-30 21:26:31 +00:00
vi.mock('@google/gemini-cli-core');
describe('ideCommand', () => {
let mockContext: CommandContext;
let mockConfig: Config;
let platformSpy: MockInstance;
beforeEach(() => {
mockContext = {
ui: {
addItem: vi.fn(),
},
} as unknown as CommandContext;
mockConfig = {
getIdeMode: vi.fn(),
getIdeClient: vi.fn(),
} as unknown as Config;
platformSpy = vi.spyOn(process, 'platform', 'get');
});
afterEach(() => {
vi.restoreAllMocks();
});
it('should return null if ideMode is not enabled', () => {
vi.mocked(mockConfig.getIdeMode).mockReturnValue(false);
const command = ideCommand(mockConfig);
expect(command).toBeNull();
});
it('should return the ide command if ideMode is enabled', () => {
vi.mocked(mockConfig.getIdeMode).mockReturnValue(true);
2025-07-30 21:26:31 +00:00
vi.mocked(mockConfig.getIdeClient).mockReturnValue({
getCurrentIde: () => DetectedIde.VSCode,
} as ReturnType<Config['getIdeClient']>);
const command = ideCommand(mockConfig);
expect(command).not.toBeNull();
expect(command?.name).toBe('ide');
expect(command?.subCommands).toHaveLength(2);
expect(command?.subCommands?.[0].name).toBe('status');
expect(command?.subCommands?.[1].name).toBe('install');
});
describe('status subcommand', () => {
const mockGetConnectionStatus = vi.fn();
beforeEach(() => {
vi.mocked(mockConfig.getIdeMode).mockReturnValue(true);
vi.mocked(mockConfig.getIdeClient).mockReturnValue({
getConnectionStatus: mockGetConnectionStatus,
2025-07-30 21:26:31 +00:00
getCurrentIde: () => DetectedIde.VSCode,
} as ReturnType<Config['getIdeClient']>);
});
it('should show connected status', () => {
mockGetConnectionStatus.mockReturnValue({
2025-07-30 21:26:31 +00:00
status: core.IDEConnectionStatus.Connected,
});
const command = ideCommand(mockConfig);
const result = command!.subCommands![0].action!(mockContext, '');
expect(mockGetConnectionStatus).toHaveBeenCalled();
expect(result).toEqual({
type: 'message',
messageType: 'info',
content: '🟢 Connected',
});
});
it('should show connecting status', () => {
mockGetConnectionStatus.mockReturnValue({
2025-07-30 21:26:31 +00:00
status: core.IDEConnectionStatus.Connecting,
});
const command = ideCommand(mockConfig);
const result = command!.subCommands![0].action!(mockContext, '');
expect(mockGetConnectionStatus).toHaveBeenCalled();
expect(result).toEqual({
type: 'message',
messageType: 'info',
content: `🟡 Connecting...`,
});
});
it('should show disconnected status', () => {
mockGetConnectionStatus.mockReturnValue({
2025-07-30 21:26:31 +00:00
status: core.IDEConnectionStatus.Disconnected,
});
const command = ideCommand(mockConfig);
const result = command!.subCommands![0].action!(mockContext, '');
expect(mockGetConnectionStatus).toHaveBeenCalled();
expect(result).toEqual({
type: 'message',
messageType: 'error',
content: `🔴 Disconnected`,
});
});
it('should show disconnected status with details', () => {
const details = 'Something went wrong';
mockGetConnectionStatus.mockReturnValue({
2025-07-30 21:26:31 +00:00
status: core.IDEConnectionStatus.Disconnected,
details,
});
const command = ideCommand(mockConfig);
const result = command!.subCommands![0].action!(mockContext, '');
expect(mockGetConnectionStatus).toHaveBeenCalled();
expect(result).toEqual({
type: 'message',
messageType: 'error',
content: `🔴 Disconnected: ${details}`,
});
});
});
describe('install subcommand', () => {
2025-07-30 21:26:31 +00:00
const mockInstall = vi.fn();
beforeEach(() => {
vi.mocked(mockConfig.getIdeMode).mockReturnValue(true);
2025-07-30 21:26:31 +00:00
vi.mocked(mockConfig.getIdeClient).mockReturnValue({
getCurrentIde: () => DetectedIde.VSCode,
} as ReturnType<Config['getIdeClient']>);
vi.mocked(core.getIdeInstaller).mockReturnValue({
install: mockInstall,
isInstalled: vi.fn(),
});
platformSpy.mockReturnValue('linux');
});
2025-07-30 21:26:31 +00:00
it('should install the extension', async () => {
mockInstall.mockResolvedValue({
success: true,
message: 'Successfully installed.',
});
const command = ideCommand(mockConfig);
await command!.subCommands![1].action!(mockContext, '');
2025-07-30 21:26:31 +00:00
expect(core.getIdeInstaller).toHaveBeenCalledWith('vscode');
expect(mockInstall).toHaveBeenCalled();
expect(mockContext.ui.addItem).toHaveBeenCalledWith(
expect.objectContaining({
type: 'info',
2025-07-30 21:26:31 +00:00
text: `Installing IDE companion extension...`,
}),
expect.any(Number),
);
expect(mockContext.ui.addItem).toHaveBeenCalledWith(
expect.objectContaining({
type: 'info',
2025-07-30 21:26:31 +00:00
text: 'Successfully installed.',
}),
expect.any(Number),
);
});
2025-07-30 21:26:31 +00:00
it('should show an error if installation fails', async () => {
mockInstall.mockResolvedValue({
success: false,
message: 'Installation failed.',
});
const command = ideCommand(mockConfig);
await command!.subCommands![1].action!(mockContext, '');
2025-07-30 21:26:31 +00:00
expect(core.getIdeInstaller).toHaveBeenCalledWith('vscode');
expect(mockInstall).toHaveBeenCalled();
expect(mockContext.ui.addItem).toHaveBeenCalledWith(
expect.objectContaining({
type: 'info',
2025-07-30 21:26:31 +00:00
text: `Installing IDE companion extension...`,
}),
expect.any(Number),
);
expect(mockContext.ui.addItem).toHaveBeenCalledWith(
expect.objectContaining({
type: 'error',
2025-07-30 21:26:31 +00:00
text: 'Installation failed.',
}),
expect.any(Number),
);
});
});
});