mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-26 13:04:49 -07:00
fix(cli): enable and fix types for MCP command tests (#11385)
This commit is contained in:
@@ -17,15 +17,38 @@ describe('mcp command', () => {
|
|||||||
expect(typeof mcpCommand.handler).toBe('function');
|
expect(typeof mcpCommand.handler).toBe('function');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have exactly one option (help flag)', () => {
|
it('should show help when no subcommand is provided', async () => {
|
||||||
// Test to ensure that the global 'gemini' flags are not added to the mcp command
|
|
||||||
const yargsInstance = yargs();
|
const yargsInstance = yargs();
|
||||||
const builtYargs = mcpCommand.builder(yargsInstance);
|
(mcpCommand.builder as (y: Argv) => Argv)(yargsInstance);
|
||||||
const options = builtYargs.getOptions();
|
|
||||||
|
|
||||||
// Should have exactly 1 option (help flag)
|
const parser = yargsInstance.command(mcpCommand).help();
|
||||||
expect(Object.keys(options.key).length).toBe(1);
|
|
||||||
expect(options.key).toHaveProperty('help');
|
// Mock console.log and console.error to catch help output
|
||||||
|
const consoleLogMock = vi
|
||||||
|
.spyOn(console, 'log')
|
||||||
|
.mockImplementation(() => {});
|
||||||
|
const consoleErrorMock = vi
|
||||||
|
.spyOn(console, 'error')
|
||||||
|
.mockImplementation(() => {});
|
||||||
|
|
||||||
|
try {
|
||||||
|
await parser.parse('mcp');
|
||||||
|
} catch (_error) {
|
||||||
|
// yargs might throw an error when demandCommand is not met
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if help output is shown
|
||||||
|
const helpOutput =
|
||||||
|
consoleLogMock.mock.calls.join('\n') +
|
||||||
|
consoleErrorMock.mock.calls.join('\n');
|
||||||
|
expect(helpOutput).toContain('Manage MCP servers');
|
||||||
|
expect(helpOutput).toContain('Commands:');
|
||||||
|
expect(helpOutput).toContain('add');
|
||||||
|
expect(helpOutput).toContain('remove');
|
||||||
|
expect(helpOutput).toContain('list');
|
||||||
|
|
||||||
|
consoleLogMock.mockRestore();
|
||||||
|
consoleErrorMock.mockRestore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should register add, remove, and list subcommands', () => {
|
it('should register add, remove, and list subcommands', () => {
|
||||||
@@ -35,7 +58,7 @@ describe('mcp command', () => {
|
|||||||
version: vi.fn().mockReturnThis(),
|
version: vi.fn().mockReturnThis(),
|
||||||
};
|
};
|
||||||
|
|
||||||
mcpCommand.builder(mockYargs as unknown as Argv);
|
(mcpCommand.builder as (y: Argv) => Argv)(mockYargs as unknown as Argv);
|
||||||
|
|
||||||
expect(mockYargs.command).toHaveBeenCalledTimes(3);
|
expect(mockYargs.command).toHaveBeenCalledTimes(3);
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import yargs from 'yargs';
|
import { describe, it, expect, vi, type Mock } from 'vitest';
|
||||||
|
import yargs, { type Argv } from 'yargs';
|
||||||
import { addCommand } from './add.js';
|
import { addCommand } from './add.js';
|
||||||
import { loadSettings, SettingScope } from '../../config/settings.js';
|
import { loadSettings, SettingScope } from '../../config/settings.js';
|
||||||
|
|
||||||
@@ -31,12 +32,12 @@ vi.mock('../../config/settings.js', async () => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
const mockedLoadSettings = loadSettings as vi.Mock;
|
const mockedLoadSettings = loadSettings as Mock;
|
||||||
|
|
||||||
describe('mcp add command', () => {
|
describe('mcp add command', () => {
|
||||||
let parser: yargs.Argv;
|
let parser: Argv;
|
||||||
let mockSetValue: vi.Mock;
|
let mockSetValue: Mock;
|
||||||
let mockConsoleError: vi.Mock;
|
let mockConsoleError: Mock;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.resetAllMocks();
|
vi.resetAllMocks();
|
||||||
@@ -207,7 +208,7 @@ describe('mcp add command', () => {
|
|||||||
.spyOn(process, 'exit')
|
.spyOn(process, 'exit')
|
||||||
.mockImplementation((() => {
|
.mockImplementation((() => {
|
||||||
throw new Error('process.exit called');
|
throw new Error('process.exit called');
|
||||||
}) as (code?: number) => never);
|
}) as (code?: number | string | null) => never);
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
parser.parseAsync(`add ${serverName} ${command}`),
|
parser.parseAsync(`add ${serverName} ${command}`),
|
||||||
@@ -225,7 +226,7 @@ describe('mcp add command', () => {
|
|||||||
.spyOn(process, 'exit')
|
.spyOn(process, 'exit')
|
||||||
.mockImplementation((() => {
|
.mockImplementation((() => {
|
||||||
throw new Error('process.exit called');
|
throw new Error('process.exit called');
|
||||||
}) as (code?: number) => never);
|
}) as (code?: number | string | null) => never);
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
parser.parseAsync(`add --scope project ${serverName} ${command}`),
|
parser.parseAsync(`add --scope project ${serverName} ${command}`),
|
||||||
|
|||||||
@@ -4,8 +4,16 @@
|
|||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
|
import {
|
||||||
import yargs from 'yargs';
|
vi,
|
||||||
|
describe,
|
||||||
|
it,
|
||||||
|
expect,
|
||||||
|
beforeEach,
|
||||||
|
afterEach,
|
||||||
|
type Mock,
|
||||||
|
} from 'vitest';
|
||||||
|
import yargs, { type Argv } from 'yargs';
|
||||||
import { SettingScope, type LoadedSettings } from '../../config/settings.js';
|
import { SettingScope, type LoadedSettings } from '../../config/settings.js';
|
||||||
import { removeCommand } from './remove.js';
|
import { removeCommand } from './remove.js';
|
||||||
import * as fs from 'node:fs';
|
import * as fs from 'node:fs';
|
||||||
@@ -20,8 +28,8 @@ vi.mock('fs/promises', () => ({
|
|||||||
|
|
||||||
describe('mcp remove command', () => {
|
describe('mcp remove command', () => {
|
||||||
describe('unit tests with mocks', () => {
|
describe('unit tests with mocks', () => {
|
||||||
let parser: yargs.Argv;
|
let parser: Argv;
|
||||||
let mockSetValue: vi.Mock;
|
let mockSetValue: Mock;
|
||||||
let mockSettings: Record<string, unknown>;
|
let mockSettings: Record<string, unknown>;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
@@ -42,7 +50,9 @@ describe('mcp remove command', () => {
|
|||||||
).mockReturnValue({
|
).mockReturnValue({
|
||||||
forScope: () => ({ settings: mockSettings }),
|
forScope: () => ({ settings: mockSettings }),
|
||||||
setValue: mockSetValue,
|
setValue: mockSetValue,
|
||||||
} as Partial<LoadedSettings> as LoadedSettings);
|
workspace: { path: '/path/to/project' },
|
||||||
|
user: { path: '/home/user' },
|
||||||
|
} as unknown as LoadedSettings);
|
||||||
|
|
||||||
const yargsInstance = yargs([]).command(removeCommand);
|
const yargsInstance = yargs([]).command(removeCommand);
|
||||||
parser = yargsInstance;
|
parser = yargsInstance;
|
||||||
@@ -73,7 +83,7 @@ describe('mcp remove command', () => {
|
|||||||
let tempDir: string;
|
let tempDir: string;
|
||||||
let settingsDir: string;
|
let settingsDir: string;
|
||||||
let settingsPath: string;
|
let settingsPath: string;
|
||||||
let parser: yargs.Argv;
|
let parser: Argv;
|
||||||
let cwdSpy: ReturnType<typeof vi.spyOn>;
|
let cwdSpy: ReturnType<typeof vi.spyOn>;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|||||||
@@ -17,10 +17,6 @@
|
|||||||
"node_modules",
|
"node_modules",
|
||||||
"dist",
|
"dist",
|
||||||
// TODO(5691): Fix type errors and remove excludes.
|
// TODO(5691): Fix type errors and remove excludes.
|
||||||
"src/commands/mcp.test.ts",
|
|
||||||
"src/commands/mcp/add.test.ts",
|
|
||||||
"src/commands/mcp/list.test.ts",
|
|
||||||
"src/commands/mcp/remove.test.ts",
|
|
||||||
"src/config/config.integration.test.ts",
|
"src/config/config.integration.test.ts",
|
||||||
"src/config/config.test.ts",
|
"src/config/config.test.ts",
|
||||||
"src/config/extension.test.ts",
|
"src/config/extension.test.ts",
|
||||||
|
|||||||
Reference in New Issue
Block a user