sync gemini-cli 0.1.17

Co-Authored-By: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
Yiheng Xu
2025-08-05 16:44:06 +08:00
235 changed files with 16997 additions and 3736 deletions

View File

@@ -4,15 +4,36 @@
* SPDX-License-Identifier: Apache-2.0
*/
const { logSlashCommand, SlashCommandEvent } = vi.hoisted(() => ({
logSlashCommand: vi.fn(),
SlashCommandEvent: vi.fn((command, subCommand) => ({ command, subCommand })),
}));
vi.mock('@qwen-code/qwen-code-core', async (importOriginal) => {
const original =
await importOriginal<typeof import('@qwen-code/qwen-code-core')>();
return {
...original,
logSlashCommand,
SlashCommandEvent,
getIdeInstaller: vi.fn().mockReturnValue(null),
};
});
const { mockProcessExit } = vi.hoisted(() => ({
mockProcessExit: vi.fn((_code?: number): never => undefined as never),
}));
vi.mock('node:process', () => ({
default: {
vi.mock('node:process', () => {
const mockProcess = {
exit: mockProcessExit,
},
}));
platform: 'test-platform',
};
return {
...mockProcess,
default: mockProcess,
};
});
const mockBuiltinLoadCommands = vi.fn();
vi.mock('../../services/BuiltinCommandLoader.js', () => ({
@@ -69,16 +90,18 @@ describe('useSlashCommandProcessor', () => {
const mockAddItem = vi.fn();
const mockClearItems = vi.fn();
const mockLoadHistory = vi.fn();
const mockSetShowHelp = vi.fn();
const mockOpenThemeDialog = vi.fn();
const mockOpenAuthDialog = vi.fn();
const mockSetQuittingMessages = vi.fn();
const mockConfig = {
getProjectRoot: () => '/mock/cwd',
getSessionId: () => 'test-session',
getGeminiClient: () => ({
getProjectRoot: vi.fn(() => '/mock/cwd'),
getSessionId: vi.fn(() => 'test-session'),
getGeminiClient: vi.fn(() => ({
setHistory: vi.fn().mockResolvedValue(undefined),
}),
})),
getExtensions: vi.fn(() => []),
getIdeMode: vi.fn(() => false),
} as unknown as Config;
const mockSettings = {} as LoadedSettings;
@@ -109,9 +132,8 @@ describe('useSlashCommandProcessor', () => {
mockClearItems,
mockLoadHistory,
vi.fn(), // refreshStatic
mockSetShowHelp,
vi.fn(), // onDebugMessage
vi.fn(), // openThemeDialog
mockOpenThemeDialog, // openThemeDialog
mockOpenAuthDialog,
vi.fn(), // openEditorDialog
vi.fn(), // toggleCorgiMode
@@ -311,19 +333,19 @@ describe('useSlashCommandProcessor', () => {
});
describe('Action Result Handling', () => {
it('should handle "dialog: help" action', async () => {
it('should handle "dialog: theme" action', async () => {
const command = createTestCommand({
name: 'helpcmd',
action: vi.fn().mockResolvedValue({ type: 'dialog', dialog: 'help' }),
name: 'themecmd',
action: vi.fn().mockResolvedValue({ type: 'dialog', dialog: 'theme' }),
});
const result = setupProcessorHook([command]);
await waitFor(() => expect(result.current.slashCommands).toHaveLength(1));
await act(async () => {
await result.current.handleSlashCommand('/helpcmd');
await result.current.handleSlashCommand('/themecmd');
});
expect(mockSetShowHelp).toHaveBeenCalledWith(true);
expect(mockOpenThemeDialog).toHaveBeenCalled();
});
it('should handle "load_history" action', async () => {
@@ -796,15 +818,15 @@ describe('useSlashCommandProcessor', () => {
mockClearItems,
mockLoadHistory,
vi.fn(), // refreshStatic
mockSetShowHelp,
vi.fn(), // onDebugMessage
vi.fn(), // openThemeDialog
mockOpenAuthDialog,
vi.fn(), // openEditorDialog,
vi.fn(), // openEditorDialog
vi.fn(), // toggleCorgiMode
mockSetQuittingMessages,
vi.fn(), // openPrivacyNotice
vi.fn(), // toggleVimEnabled
vi.fn().mockResolvedValue(false), // toggleVimEnabled
vi.fn(), // setIsProcessing
),
);
@@ -813,4 +835,83 @@ describe('useSlashCommandProcessor', () => {
expect(abortSpy).toHaveBeenCalledTimes(1);
});
});
describe('Slash Command Logging', () => {
const mockCommandAction = vi.fn().mockResolvedValue({ type: 'handled' });
const loggingTestCommands: SlashCommand[] = [
createTestCommand({
name: 'logtest',
action: mockCommandAction,
}),
createTestCommand({
name: 'logwithsub',
subCommands: [
createTestCommand({
name: 'sub',
action: mockCommandAction,
}),
],
}),
createTestCommand({
name: 'logalias',
altNames: ['la'],
action: mockCommandAction,
}),
];
beforeEach(() => {
mockCommandAction.mockClear();
vi.mocked(logSlashCommand).mockClear();
vi.mocked(SlashCommandEvent).mockClear();
});
it('should log a simple slash command', async () => {
const result = setupProcessorHook(loggingTestCommands);
await waitFor(() =>
expect(result.current.slashCommands.length).toBeGreaterThan(0),
);
await act(async () => {
await result.current.handleSlashCommand('/logtest');
});
expect(logSlashCommand).toHaveBeenCalledTimes(1);
expect(SlashCommandEvent).toHaveBeenCalledWith('logtest', undefined);
});
it('should log a slash command with a subcommand', async () => {
const result = setupProcessorHook(loggingTestCommands);
await waitFor(() =>
expect(result.current.slashCommands.length).toBeGreaterThan(0),
);
await act(async () => {
await result.current.handleSlashCommand('/logwithsub sub');
});
expect(logSlashCommand).toHaveBeenCalledTimes(1);
expect(SlashCommandEvent).toHaveBeenCalledWith('logwithsub', 'sub');
});
it('should log the command path when an alias is used', async () => {
const result = setupProcessorHook(loggingTestCommands);
await waitFor(() =>
expect(result.current.slashCommands.length).toBeGreaterThan(0),
);
await act(async () => {
await result.current.handleSlashCommand('/la');
});
expect(logSlashCommand).toHaveBeenCalledTimes(1);
expect(SlashCommandEvent).toHaveBeenCalledWith('logalias', undefined);
});
it('should not log for unknown commands', async () => {
const result = setupProcessorHook(loggingTestCommands);
await waitFor(() =>
expect(result.current.slashCommands.length).toBeGreaterThan(0),
);
await act(async () => {
await result.current.handleSlashCommand('/unknown');
});
expect(logSlashCommand).not.toHaveBeenCalled();
});
});
});