mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-04-30 04:30:48 +00:00
fix ci test
This commit is contained in:
parent
143beb51ed
commit
b0c3e5d884
11 changed files with 381 additions and 293 deletions
|
|
@ -4,30 +4,51 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { describe, it, expect, vi, type MockInstance } from 'vitest';
|
||||
import {
|
||||
describe,
|
||||
it,
|
||||
expect,
|
||||
vi,
|
||||
beforeEach,
|
||||
afterEach,
|
||||
type MockInstance,
|
||||
} from 'vitest';
|
||||
import { handleInstall, installCommand } from './install.js';
|
||||
import yargs from 'yargs';
|
||||
|
||||
const mockInstallExtension = vi.hoisted(() => vi.fn());
|
||||
const mockRefreshCache = vi.hoisted(() => vi.fn());
|
||||
const mockParseInstallSource = vi.hoisted(() => vi.fn());
|
||||
const mockRequestConsentNonInteractive = vi.hoisted(() => vi.fn());
|
||||
const mockStat = vi.hoisted(() => vi.fn());
|
||||
const mockRequestConsentOrFail = vi.hoisted(() => vi.fn());
|
||||
const mockIsWorkspaceTrusted = vi.hoisted(() => vi.fn());
|
||||
const mockLoadSettings = vi.hoisted(() => vi.fn());
|
||||
|
||||
vi.mock('../../config/extension.js', () => ({
|
||||
installExtension: mockInstallExtension,
|
||||
vi.mock('@qwen-code/qwen-code-core', () => ({
|
||||
ExtensionManager: vi.fn().mockImplementation(() => ({
|
||||
installExtension: mockInstallExtension,
|
||||
refreshCache: mockRefreshCache,
|
||||
})),
|
||||
parseInstallSource: mockParseInstallSource,
|
||||
}));
|
||||
|
||||
vi.mock('./consent.js', () => ({
|
||||
requestConsentNonInteractive: mockRequestConsentNonInteractive,
|
||||
requestConsentOrFail: mockRequestConsentOrFail,
|
||||
}));
|
||||
|
||||
vi.mock('../../config/trustedFolders.js', () => ({
|
||||
isWorkspaceTrusted: mockIsWorkspaceTrusted,
|
||||
}));
|
||||
|
||||
vi.mock('../../config/settings.js', () => ({
|
||||
loadSettings: mockLoadSettings,
|
||||
}));
|
||||
|
||||
vi.mock('../../utils/errors.js', () => ({
|
||||
getErrorMessage: vi.fn((error: Error) => error.message),
|
||||
}));
|
||||
|
||||
vi.mock('node:fs/promises', () => ({
|
||||
stat: mockStat,
|
||||
default: {
|
||||
stat: mockStat,
|
||||
},
|
||||
}));
|
||||
|
||||
describe('extensions install command', () => {
|
||||
it('should fail if no source is provided', () => {
|
||||
const validationParser = yargs([])
|
||||
|
|
@ -51,17 +72,21 @@ describe('handleInstall', () => {
|
|||
processSpy = vi
|
||||
.spyOn(process, 'exit')
|
||||
.mockImplementation(() => undefined as never);
|
||||
mockRefreshCache.mockResolvedValue(undefined);
|
||||
mockLoadSettings.mockReturnValue({ merged: {} });
|
||||
mockIsWorkspaceTrusted.mockReturnValue(true);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
mockInstallExtension.mockClear();
|
||||
mockRequestConsentNonInteractive.mockClear();
|
||||
mockStat.mockClear();
|
||||
vi.resetAllMocks();
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should install an extension from a http source', async () => {
|
||||
mockInstallExtension.mockResolvedValue('http-extension');
|
||||
mockParseInstallSource.mockResolvedValue({
|
||||
type: 'http',
|
||||
url: 'http://google.com',
|
||||
});
|
||||
mockInstallExtension.mockResolvedValue({ name: 'http-extension' });
|
||||
|
||||
await handleInstall({
|
||||
source: 'http://google.com',
|
||||
|
|
@ -73,7 +98,11 @@ describe('handleInstall', () => {
|
|||
});
|
||||
|
||||
it('should install an extension from a https source', async () => {
|
||||
mockInstallExtension.mockResolvedValue('https-extension');
|
||||
mockParseInstallSource.mockResolvedValue({
|
||||
type: 'https',
|
||||
url: 'https://google.com',
|
||||
});
|
||||
mockInstallExtension.mockResolvedValue({ name: 'https-extension' });
|
||||
|
||||
await handleInstall({
|
||||
source: 'https://google.com',
|
||||
|
|
@ -85,7 +114,11 @@ describe('handleInstall', () => {
|
|||
});
|
||||
|
||||
it('should install an extension from a git source', async () => {
|
||||
mockInstallExtension.mockResolvedValue('git-extension');
|
||||
mockParseInstallSource.mockResolvedValue({
|
||||
type: 'git',
|
||||
url: 'git@some-url',
|
||||
});
|
||||
mockInstallExtension.mockResolvedValue({ name: 'git-extension' });
|
||||
|
||||
await handleInstall({
|
||||
source: 'git@some-url',
|
||||
|
|
@ -97,7 +130,9 @@ describe('handleInstall', () => {
|
|||
});
|
||||
|
||||
it('throws an error from an unknown source', async () => {
|
||||
mockStat.mockRejectedValue(new Error('ENOENT: no such file or directory'));
|
||||
mockParseInstallSource.mockRejectedValue(
|
||||
new Error('Install source not found.'),
|
||||
);
|
||||
await handleInstall({
|
||||
source: 'test://google.com',
|
||||
});
|
||||
|
|
@ -107,7 +142,11 @@ describe('handleInstall', () => {
|
|||
});
|
||||
|
||||
it('should install an extension from a sso source', async () => {
|
||||
mockInstallExtension.mockResolvedValue('sso-extension');
|
||||
mockParseInstallSource.mockResolvedValue({
|
||||
type: 'sso',
|
||||
url: 'sso://google.com',
|
||||
});
|
||||
mockInstallExtension.mockResolvedValue({ name: 'sso-extension' });
|
||||
|
||||
await handleInstall({
|
||||
source: 'sso://google.com',
|
||||
|
|
@ -119,8 +158,12 @@ describe('handleInstall', () => {
|
|||
});
|
||||
|
||||
it('should install an extension from a local path', async () => {
|
||||
mockInstallExtension.mockResolvedValue('local-extension');
|
||||
mockStat.mockResolvedValue({});
|
||||
mockParseInstallSource.mockResolvedValue({
|
||||
type: 'local',
|
||||
path: '/some/path',
|
||||
});
|
||||
mockInstallExtension.mockResolvedValue({ name: 'local-extension' });
|
||||
|
||||
await handleInstall({
|
||||
source: '/some/path',
|
||||
});
|
||||
|
|
@ -131,6 +174,10 @@ describe('handleInstall', () => {
|
|||
});
|
||||
|
||||
it('should throw an error if install extension fails', async () => {
|
||||
mockParseInstallSource.mockResolvedValue({
|
||||
type: 'git',
|
||||
url: 'git@some-url',
|
||||
});
|
||||
mockInstallExtension.mockRejectedValue(
|
||||
new Error('Install extension failed'),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -7,11 +7,16 @@
|
|||
import yargs from 'yargs';
|
||||
import { addCommand } from './add.js';
|
||||
import { loadSettings, SettingScope } from '../../config/settings.js';
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
|
||||
vi.mock('fs/promises', () => ({
|
||||
readFile: vi.fn(),
|
||||
writeFile: vi.fn(),
|
||||
}));
|
||||
vi.mock('fs/promises', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import('fs/promises')>();
|
||||
return {
|
||||
...actual,
|
||||
readFile: vi.fn(),
|
||||
writeFile: vi.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock('os', () => {
|
||||
const homedir = vi.fn(() => '/home/user');
|
||||
|
|
|
|||
|
|
@ -7,19 +7,15 @@
|
|||
import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
|
||||
import { listMcpServers } from './list.js';
|
||||
import { loadSettings } from '../../config/settings.js';
|
||||
import { loadExtensions } from '../../config/extension.js';
|
||||
import { ExtensionStorage } from '../../config/extensions/storage.js';
|
||||
import { createTransport } from '@qwen-code/qwen-code-core';
|
||||
import { isWorkspaceTrusted } from '../../config/trustedFolders.js';
|
||||
import { createTransport, ExtensionManager } from '@qwen-code/qwen-code-core';
|
||||
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
||||
|
||||
vi.mock('../../config/settings.js', () => ({
|
||||
loadSettings: vi.fn(),
|
||||
}));
|
||||
vi.mock('../../config/extension.js', () => ({
|
||||
loadExtensions: vi.fn(),
|
||||
ExtensionStorage: {
|
||||
getUserExtensionsDir: vi.fn(),
|
||||
},
|
||||
vi.mock('../../config/trustedFolders.js', () => ({
|
||||
isWorkspaceTrusted: vi.fn(),
|
||||
}));
|
||||
vi.mock('@qwen-code/qwen-code-core', () => ({
|
||||
createTransport: vi.fn(),
|
||||
|
|
@ -28,20 +24,15 @@ vi.mock('@qwen-code/qwen-code-core', () => ({
|
|||
CONNECTING: 'CONNECTING',
|
||||
DISCONNECTED: 'DISCONNECTED',
|
||||
},
|
||||
Storage: vi.fn().mockImplementation((_cwd: string) => ({
|
||||
getGlobalSettingsPath: () => '/tmp/qwen/settings.json',
|
||||
getWorkspaceSettingsPath: () => '/tmp/qwen/workspace-settings.json',
|
||||
getProjectTempDir: () => '/test/home/.qwen/tmp/mocked_hash',
|
||||
})),
|
||||
QWEN_CONFIG_DIR: '.qwen',
|
||||
ExtensionManager: vi.fn(),
|
||||
getErrorMessage: (e: unknown) => (e instanceof Error ? e.message : String(e)),
|
||||
}));
|
||||
vi.mock('@modelcontextprotocol/sdk/client/index.js');
|
||||
|
||||
const mockedExtensionStorage = ExtensionStorage as vi.Mock;
|
||||
const mockedLoadSettings = loadSettings as vi.Mock;
|
||||
const mockedLoadExtensions = loadExtensions as vi.Mock;
|
||||
const mockedIsWorkspaceTrusted = isWorkspaceTrusted as vi.Mock;
|
||||
const mockedCreateTransport = createTransport as vi.Mock;
|
||||
const MockedExtensionManager = ExtensionManager as vi.Mock;
|
||||
const MockedClient = Client as vi.Mock;
|
||||
|
||||
interface MockClient {
|
||||
|
|
@ -58,6 +49,10 @@ describe('mcp list command', () => {
|
|||
let consoleSpy: vi.SpyInstance;
|
||||
let mockClient: MockClient;
|
||||
let mockTransport: MockTransport;
|
||||
let mockExtensionManager: {
|
||||
refreshCache: vi.Mock;
|
||||
getLoadedExtensions: vi.Mock;
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
vi.resetAllMocks();
|
||||
|
|
@ -71,12 +66,15 @@ describe('mcp list command', () => {
|
|||
close: vi.fn(),
|
||||
};
|
||||
|
||||
mockExtensionManager = {
|
||||
refreshCache: vi.fn().mockResolvedValue(undefined),
|
||||
getLoadedExtensions: vi.fn().mockReturnValue([]),
|
||||
};
|
||||
|
||||
MockedClient.mockImplementation(() => mockClient);
|
||||
mockedCreateTransport.mockResolvedValue(mockTransport);
|
||||
mockedLoadExtensions.mockReturnValue([]);
|
||||
mockedExtensionStorage.getUserExtensionsDir.mockReturnValue(
|
||||
'/mocked/extensions/dir',
|
||||
);
|
||||
MockedExtensionManager.mockImplementation(() => mockExtensionManager);
|
||||
mockedIsWorkspaceTrusted.mockReturnValue(true);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
|
@ -152,8 +150,9 @@ describe('mcp list command', () => {
|
|||
},
|
||||
});
|
||||
|
||||
mockedLoadExtensions.mockReturnValue([
|
||||
mockExtensionManager.getLoadedExtensions.mockReturnValue([
|
||||
{
|
||||
isActive: true,
|
||||
config: {
|
||||
name: 'test-extension',
|
||||
mcpServers: { 'extension-server': { command: '/ext/server' } },
|
||||
|
|
|
|||
|
|
@ -9,10 +9,14 @@ import yargs from 'yargs';
|
|||
import { loadSettings, SettingScope } from '../../config/settings.js';
|
||||
import { removeCommand } from './remove.js';
|
||||
|
||||
vi.mock('fs/promises', () => ({
|
||||
readFile: vi.fn(),
|
||||
writeFile: vi.fn(),
|
||||
}));
|
||||
vi.mock('fs/promises', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import('fs/promises')>();
|
||||
return {
|
||||
...actual,
|
||||
readFile: vi.fn(),
|
||||
writeFile: vi.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock('../../config/settings.js', async () => {
|
||||
const actual = await vi.importActual('../../config/settings.js');
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue