Files
ai-terminal-assistant/tests/unit/tools/load_description.test.ts
T
kurihada bca19b7741 test: 补充单元测试提升代码覆盖率
新增测试文件:
- agent/executor-extended.test.ts, presets/
- context/manager-extended.test.ts
- core/agent.test.ts, providers.test.ts
- lsp/cli.test.ts, client-extended.test.ts, index.test.ts
- permission/file-prompt.test.ts, prompt.test.ts
- skills/builtin/
- tools/filesystem/write_file-extended.test.ts
- tools/git/git_commit-extended.test.ts
- tools/load_description.test.ts
- tools/todo/todo-manager.test.ts
- tools/tool-search.test.ts
- types/
- utils/config-extended.test.ts, diff-extended.test.ts

修改现有测试:
- agent/manager.test.ts
- tools/skill/skill.test.ts
- utils/config.test.ts, diff.test.ts, image.test.ts
2025-12-11 20:37:03 +08:00

206 lines
6.1 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from 'vitest';
// Mock fs
vi.mock('fs', () => ({
readFileSync: vi.fn(),
}));
import * as fs from 'fs';
import { loadDescription } from '../../../src/tools/load_description.js';
describe('loadDescription', () => {
beforeEach(() => {
vi.clearAllMocks();
});
describe('带分类的工具', () => {
it('加载 shell 类工具描述', () => {
vi.mocked(fs.readFileSync).mockReturnValue(' Bash 工具描述 ');
const result = loadDescription('bash');
expect(result).toBe('Bash 工具描述');
expect(fs.readFileSync).toHaveBeenCalledWith(
expect.stringContaining('descriptions/shell/bash.txt'),
'utf-8'
);
});
it('加载 filesystem 类工具描述', () => {
vi.mocked(fs.readFileSync).mockReturnValue('读取文件描述');
const result = loadDescription('read_file');
expect(result).toBe('读取文件描述');
expect(fs.readFileSync).toHaveBeenCalledWith(
expect.stringContaining('descriptions/filesystem/read_file.txt'),
'utf-8'
);
});
it('加载 write_file 描述', () => {
vi.mocked(fs.readFileSync).mockReturnValue('写入文件描述');
loadDescription('write_file');
expect(fs.readFileSync).toHaveBeenCalledWith(
expect.stringContaining('descriptions/filesystem/write_file.txt'),
'utf-8'
);
});
it('加载 edit_file 描述', () => {
vi.mocked(fs.readFileSync).mockReturnValue('编辑文件描述');
loadDescription('edit_file');
expect(fs.readFileSync).toHaveBeenCalledWith(
expect.stringContaining('descriptions/filesystem/edit_file.txt'),
'utf-8'
);
});
it('加载 git 类工具描述', () => {
vi.mocked(fs.readFileSync).mockReturnValue('Git status 描述');
loadDescription('git_status');
expect(fs.readFileSync).toHaveBeenCalledWith(
expect.stringContaining('descriptions/git/git_status.txt'),
'utf-8'
);
});
it('加载 web 类工具描述', () => {
vi.mocked(fs.readFileSync).mockReturnValue('Web search 描述');
loadDescription('web_search');
expect(fs.readFileSync).toHaveBeenCalledWith(
expect.stringContaining('descriptions/web/web_search.txt'),
'utf-8'
);
});
it('加载 todo 类工具描述', () => {
vi.mocked(fs.readFileSync).mockReturnValue('Todo read 描述');
loadDescription('todo_read');
expect(fs.readFileSync).toHaveBeenCalledWith(
expect.stringContaining('descriptions/todo/todo_read.txt'),
'utf-8'
);
});
});
describe('不带分类的工具', () => {
it('未知工具使用根目录', () => {
vi.mocked(fs.readFileSync).mockReturnValue('未知工具描述');
loadDescription('unknown_tool');
expect(fs.readFileSync).toHaveBeenCalledWith(
expect.stringContaining('descriptions/unknown_tool.txt'),
'utf-8'
);
// 确保不包含子目录
expect(fs.readFileSync).not.toHaveBeenCalledWith(
expect.stringContaining('descriptions/filesystem/unknown_tool.txt'),
'utf-8'
);
});
});
describe('错误处理', () => {
it('文件不存在时抛出错误', () => {
vi.mocked(fs.readFileSync).mockImplementation(() => {
throw new Error('ENOENT');
});
expect(() => loadDescription('nonexistent')).toThrow('无法加载工具描述文件');
});
it('错误信息包含文件路径', () => {
vi.mocked(fs.readFileSync).mockImplementation(() => {
throw new Error('ENOENT');
});
expect(() => loadDescription('some_tool')).toThrow('some_tool.txt');
});
});
describe('内容处理', () => {
it('去除前后空白', () => {
vi.mocked(fs.readFileSync).mockReturnValue('\n\n 内容 \n\n');
const result = loadDescription('bash');
expect(result).toBe('内容');
});
it('保留中间空白', () => {
vi.mocked(fs.readFileSync).mockReturnValue('第一行\n第二行\n第三行');
const result = loadDescription('bash');
expect(result).toBe('第一行\n第二行\n第三行');
});
it('空文件返回空字符串', () => {
vi.mocked(fs.readFileSync).mockReturnValue(' ');
const result = loadDescription('bash');
expect(result).toBe('');
});
});
describe('所有映射的工具', () => {
const toolCategories = [
// shell
{ tool: 'bash', category: 'shell' },
// filesystem
{ tool: 'read_file', category: 'filesystem' },
{ tool: 'write_file', category: 'filesystem' },
{ tool: 'edit_file', category: 'filesystem' },
{ tool: 'list_directory', category: 'filesystem' },
{ tool: 'create_directory', category: 'filesystem' },
{ tool: 'search_files', category: 'filesystem' },
{ tool: 'grep_content', category: 'filesystem' },
{ tool: 'get_file_info', category: 'filesystem' },
{ tool: 'move_file', category: 'filesystem' },
{ tool: 'copy_file', category: 'filesystem' },
{ tool: 'delete_file', category: 'filesystem' },
// web
{ tool: 'web_search', category: 'web' },
{ tool: 'web_extract', category: 'web' },
// git
{ tool: 'git_status', category: 'git' },
{ tool: 'git_diff', category: 'git' },
{ tool: 'git_log', category: 'git' },
{ tool: 'git_branch', category: 'git' },
{ tool: 'git_add', category: 'git' },
{ tool: 'git_commit', category: 'git' },
{ tool: 'git_push', category: 'git' },
{ tool: 'git_pull', category: 'git' },
{ tool: 'git_checkout', category: 'git' },
{ tool: 'git_stash', category: 'git' },
// todo
{ tool: 'todo_read', category: 'todo' },
{ tool: 'todo_write', category: 'todo' },
];
it.each(toolCategories)('$tool 映射到 $category 目录', ({ tool, category }) => {
vi.mocked(fs.readFileSync).mockReturnValue('描述');
loadDescription(tool);
expect(fs.readFileSync).toHaveBeenCalledWith(
expect.stringContaining(`descriptions/${category}/${tool}.txt`),
'utf-8'
);
});
});
});