Files
gemini-cli/scripts/tests/tool-registry.test.ts
T

140 lines
4.2 KiB
TypeScript
Raw Normal View History

2026-06-25 05:21:30 +05:30
/**
* @license
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import { describe, expect, it } from 'vitest';
import {
buildToolRegistry,
resolveToolName,
getToolsByCategory,
type ToolCategory,
} from '../utils/tool-registry.js';
describe('tool-registry', () => {
const registry = buildToolRegistry();
describe('buildToolRegistry', () => {
it('includes all canonical built-in tools', () => {
expect(registry.totalTools).toBeGreaterThanOrEqual(26);
});
it('every tool has a valid category', () => {
for (const [name, entry] of registry.tools) {
expect(entry.category).toBeTruthy();
expect(entry.name).toBe(name);
}
});
it('byCategory entries match tools map', () => {
let categoryTotal = 0;
for (const [, entries] of registry.byCategory) {
for (const entry of entries) {
expect(registry.tools.get(entry.name)).toBe(entry);
}
categoryTotal += entries.length;
}
expect(categoryTotal).toBe(registry.totalTools);
});
it('aliasLookup covers every canonical name', () => {
for (const name of registry.tools.keys()) {
expect(registry.aliasLookup.get(name)).toBe(name);
}
});
it('aliasLookup covers every legacy alias', () => {
for (const [, entry] of registry.tools) {
for (const alias of entry.aliases) {
expect(registry.aliasLookup.get(alias)).toBe(entry.name);
}
}
});
it('is deterministic across calls', () => {
const second = buildToolRegistry();
expect([...second.tools.keys()]).toEqual([...registry.tools.keys()]);
expect(second.totalTools).toBe(registry.totalTools);
});
});
describe('resolveToolName', () => {
it('resolves canonical names to themselves', () => {
expect(resolveToolName(registry, 'grep_search')).toBe('grep_search');
expect(resolveToolName(registry, 'run_shell_command')).toBe(
'run_shell_command',
);
});
it('resolves legacy alias to canonical name', () => {
expect(resolveToolName(registry, 'search_file_content')).toBe(
'grep_search',
);
});
it('returns undefined for unknown tool names', () => {
expect(resolveToolName(registry, 'nonexistent_tool')).toBeUndefined();
});
it('returns undefined for empty string', () => {
expect(resolveToolName(registry, '')).toBeUndefined();
});
});
describe('getToolsByCategory', () => {
it('returns file-system tools', () => {
const tools = getToolsByCategory(registry, 'file-system');
const names = tools.map((t) => t.name);
expect(names).toContain('glob');
expect(names).toContain('grep_search');
expect(names).toContain('read_file');
expect(names).toContain('write_file');
expect(names).toContain('replace');
});
it('returns task-tracker tools', () => {
const tools = getToolsByCategory(registry, 'task-tracker');
const names = tools.map((t) => t.name);
expect(names).toContain('tracker_create_task');
expect(names).toContain('tracker_update_task');
expect(names).toContain('tracker_get_task');
expect(names).toContain('tracker_list_tasks');
expect(names).toContain('tracker_add_dependency');
expect(names).toContain('tracker_visualize');
expect(names).toHaveLength(6);
});
it('returns agent tools', () => {
const tools = getToolsByCategory(registry, 'agent');
const names = tools.map((t) => t.name);
expect(names).toContain('invoke_agent');
expect(names).toContain('complete_task');
expect(names).toContain('update_topic');
});
it('returns empty array for unknown category', () => {
expect(
getToolsByCategory(registry, 'nonexistent' as ToolCategory),
).toEqual([]);
});
it('every defined category has at least one tool', () => {
const expectedCategories: ToolCategory[] = [
'file-system',
'shell',
'web',
'planning',
'user-interaction',
'skills',
'task-tracker',
'agent',
'mcp',
];
for (const cat of expectedCategories) {
expect(getToolsByCategory(registry, cat).length).toBeGreaterThan(0);
}
});
});
});