tool-registry.test.ts.disabled•7.54 kB
import { describe, expect, test } from "bun:test";
import { ToolRegistry, ToolCategory, EnhancedTool } from '../../src/tools/index.js';
describe('ToolRegistry', () => {
let registry: ToolRegistry;
let mockTool: EnhancedTool;
beforeEach(() => {
registry = new ToolRegistry();
mockTool = {
name: 'test_tool',
description: 'A test tool',
metadata: {
category: ToolCategory.DEVICE,
platform: 'test',
version: '1.0.0',
caching: {
enabled: true,
ttl: 1000
}
},
execute: mock().mockResolvedValue({ success: true }),
validate: mock().mockResolvedValue(true),
preExecute: mock().mockResolvedValue(undefined),
postExecute: mock().mockResolvedValue(undefined)
};
});
describe('Tool Registration', () => {
test('should register a tool successfully', () => {
registry.registerTool(mockTool);
const retrievedTool = registry.getTool('test_tool');
expect(retrievedTool).toBe(mockTool);
});
test('should categorize tools correctly', () => {
registry.registerTool(mockTool);
const deviceTools = registry.getToolsByCategory(ToolCategory.DEVICE);
expect(deviceTools).toContain(mockTool);
});
test('should handle multiple tools in the same category', () => {
const mockTool2 = {
...mockTool,
name: 'test_tool_2'
};
registry.registerTool(mockTool);
registry.registerTool(mockTool2);
const deviceTools = registry.getToolsByCategory(ToolCategory.DEVICE);
expect(deviceTools).toHaveLength(2);
expect(deviceTools).toContain(mockTool);
expect(deviceTools).toContain(mockTool2);
});
});
describe('Tool Execution', () => {
test('should execute a tool with all hooks', async () => {
registry.registerTool(mockTool);
await registry.executeTool('test_tool', { param: 'value' });
expect(mockTool.validate).toHaveBeenCalledWith({ param: 'value' });
expect(mockTool.preExecute).toHaveBeenCalledWith({ param: 'value' });
expect(mockTool.execute).toHaveBeenCalledWith({ param: 'value' });
expect(mockTool.postExecute).toHaveBeenCalled();
});
test('should throw error for non-existent tool', async () => {
await expect(registry.executeTool('non_existent', {}))
.rejects.toThrow('Tool non_existent not found');
});
test('should handle validation failure', async () => {
mockTool.validate = mock().mockResolvedValue(false);
registry.registerTool(mockTool);
await expect(registry.executeTool('test_tool', {}))
.rejects.toThrow('Invalid parameters');
});
test('should execute without optional hooks', async () => {
const simpleTool: EnhancedTool = {
name: 'simple_tool',
description: 'A simple tool',
metadata: {
category: ToolCategory.SYSTEM,
platform: 'test',
version: '1.0.0'
},
execute: mock().mockResolvedValue({ success: true })
};
registry.registerTool(simpleTool);
const result = await registry.executeTool('simple_tool', {});
expect(result).toEqual({ success: true });
});
});
describe('Caching', () => {
test('should cache tool results when enabled', async () => {
registry.registerTool(mockTool);
const params = { test: 'value' };
// First execution
await registry.executeTool('test_tool', params);
expect(mockTool.execute).toHaveBeenCalledTimes(1);
// Second execution within TTL
await registry.executeTool('test_tool', params);
expect(mockTool.execute).toHaveBeenCalledTimes(1);
});
test('should not cache results when disabled', async () => {
const uncachedTool: EnhancedTool = {
...mockTool,
metadata: {
...mockTool.metadata,
caching: {
enabled: false,
ttl: 1000
}
}
};
registry.registerTool(uncachedTool);
const params = { test: 'value' };
// Multiple executions
await registry.executeTool('test_tool', params);
await registry.executeTool('test_tool', params);
expect(uncachedTool.execute).toHaveBeenCalledTimes(2);
});
test('should expire cache after TTL', async () => {
mockTool.metadata.caching!.ttl = 100; // Short TTL for testing
registry.registerTool(mockTool);
const params = { test: 'value' };
// First execution
await registry.executeTool('test_tool', params);
// Wait for cache to expire
await new Promise(resolve => setTimeout(resolve, 150));
// Second execution after TTL
await registry.executeTool('test_tool', params);
expect(mockTool.execute).toHaveBeenCalledTimes(2);
});
test('should clean expired cache entries', async () => {
mockTool.metadata.caching!.ttl = 100;
registry.registerTool(mockTool);
const params = { test: 'value' };
// Execute and cache
await registry.executeTool('test_tool', params);
// Wait for cache to expire
await new Promise(resolve => setTimeout(resolve, 150));
// Clean cache
registry.cleanCache();
// Verify cache is cleaned by forcing a new execution
await registry.executeTool('test_tool', params);
expect(mockTool.execute).toHaveBeenCalledTimes(2);
});
});
describe('Category Management', () => {
test('should return empty array for unknown category', () => {
const tools = registry.getToolsByCategory('unknown' as ToolCategory);
expect(tools).toEqual([]);
});
test('should handle tools across multiple categories', () => {
const systemTool: EnhancedTool = {
...mockTool,
name: 'system_tool',
metadata: {
...mockTool.metadata,
category: ToolCategory.SYSTEM
}
};
const automationTool: EnhancedTool = {
...mockTool,
name: 'automation_tool',
metadata: {
...mockTool.metadata,
category: ToolCategory.AUTOMATION
}
};
registry.registerTool(mockTool); // DEVICE category
registry.registerTool(systemTool);
registry.registerTool(automationTool);
expect(registry.getToolsByCategory(ToolCategory.DEVICE)).toHaveLength(1);
expect(registry.getToolsByCategory(ToolCategory.SYSTEM)).toHaveLength(1);
expect(registry.getToolsByCategory(ToolCategory.AUTOMATION)).toHaveLength(1);
});
});
});