import { describe, it, expect, beforeEach, vi } from 'vitest'; import { skillTool } from '../../../../src/tools/skill/skill.js'; import { getSkillRegistry, resetSkillRegistry } from '../../../../src/skills/registry.js'; import type { Skill } from '../../../../src/skills/types.js'; // Mock loader to prevent file system access vi.mock('../../../../src/skills/loader.js', () => ({ skillLoader: { loadFromDirectory: vi.fn().mockResolvedValue([]), getUserSkillsDir: vi.fn().mockReturnValue('/mock/user/skills'), getProjectSkillsDir: vi.fn().mockReturnValue('/mock/project/skills'), }, })); // Mock builtin skills vi.mock('../../../../src/skills/builtin/index.js', () => ({ builtinSkills: [ { name: 'code-review', description: '代码审查', promptTemplate: '请审查以下代码:\n\n{{code}}\n\n重点:{{focus}}', parameters: { code: { type: 'string', required: true, description: '代码' }, focus: { type: 'string', required: false, default: '代码质量', description: '审查重点' }, }, category: 'development', source: 'builtin', enabled: true, }, { name: 'disabled-skill', description: '禁用的 Skill', promptTemplate: '不应该执行', source: 'builtin', enabled: false, }, ], })); describe('skillTool - Skill 工具', () => { beforeEach(async () => { vi.clearAllMocks(); resetSkillRegistry(); // 初始化注册表 const registry = getSkillRegistry(); await registry.initialize(); }); describe('工具定义', () => { it('有正确的名称', () => { expect(skillTool.name).toBe('skill'); }); it('有正确的元数据', () => { expect(skillTool.metadata.category).toBe('agent'); expect(skillTool.metadata.keywords).toContain('skill'); }); it('skill_name 参数是必须的', () => { expect(skillTool.parameters.skill_name.required).toBe(true); }); it('params 参数是可选的', () => { expect(skillTool.parameters.params.required).toBe(false); }); }); describe('execute - 执行', () => { it('成功执行 Skill 并渲染模板', async () => { const result = await skillTool.execute({ skill_name: 'code-review', params: { code: 'function add(a, b) { return a + b; }', focus: '性能', }, }); expect(result.success).toBe(true); expect(result.output).toContain('function add'); expect(result.output).toContain('性能'); expect(result.metadata?.skill).toBe('code-review'); }); it('使用默认参数值', async () => { const result = await skillTool.execute({ skill_name: 'code-review', params: { code: 'const x = 1;', }, }); expect(result.success).toBe(true); expect(result.output).toContain('代码质量'); // 默认值 }); it('Skill 不存在时返回错误', async () => { const result = await skillTool.execute({ skill_name: 'non-existent', params: {}, }); expect(result.success).toBe(false); expect(result.error).toContain('不存在'); }); it('Skill 不存在时提供建议', async () => { const result = await skillTool.execute({ skill_name: 'code-rev', // 类似 code-review params: {}, }); expect(result.success).toBe(false); expect(result.error).toContain('code-review'); // 建议 }); it('缺少必需参数时返回错误', async () => { const result = await skillTool.execute({ skill_name: 'code-review', params: {}, // 缺少 code 参数 }); expect(result.success).toBe(false); expect(result.error).toContain('缺少必需参数'); }); it('禁用的 Skill 返回错误', async () => { const result = await skillTool.execute({ skill_name: 'disabled-skill', params: {}, }); expect(result.success).toBe(false); expect(result.error).toContain('禁用'); }); it('返回正确的 metadata', async () => { const result = await skillTool.execute({ skill_name: 'code-review', params: { code: 'test' }, }); expect(result.metadata?.skill).toBe('code-review'); expect(result.metadata?.category).toBe('development'); expect(result.metadata?.source).toBe('builtin'); }); }); });