/** * Agent Adapter 测试 * * 测试 initCore、getOrCreateAgent、配置错误处理等关键功能 * * 注意:由于 adapter.ts 使用静态导入 @ai-assistant/core, * 模块状态在测试间共享,某些需要重置模块状态的测试已简化。 */ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; import { resetCoreMocks, configureMocks, getMocks, MockConfigurationError, } from '../../mocks/core.mock.js'; // Mock @ai-assistant/core 模块(静态导入) vi.mock('@ai-assistant/core', async () => { const mock = await import('../../mocks/core.mock.js'); return { Agent: mock.MockAgent, SessionManager: mock.MockSessionManager, toolRegistry: mock.getMocks().toolRegistry, loadConfig: () => mock.getMocks().loadConfig(), getPermissionManager: () => mock.getMocks().permissionManager, getProviderRegistry: () => mock.getMocks().providerRegistry, agentRegistry: mock.getMocks().agentRegistry, agentEventEmitter: mock.getMocks().agentEventEmitter, ConfigurationError: mock.MockConfigurationError, }; }); // Mock 其他依赖 vi.mock('../../../src/session/manager.js', () => ({ getSessionManager: vi.fn().mockReturnValue({ exists: vi.fn().mockReturnValue(true), get: vi.fn().mockReturnValue({ id: 'session-1' }), updateStatus: vi.fn(), updateMessageCount: vi.fn(), updateSessionName: vi.fn().mockResolvedValue({ id: 'session-1', name: 'Test' }), }), })); vi.mock('../../../src/permission/handler.js', () => ({ createServerPermissionCallback: vi.fn().mockReturnValue(async () => ({ allow: true })), setSessionAutoApprove: vi.fn(), })); vi.mock('../../../src/ws.js', () => ({ broadcastToSession: vi.fn(), })); vi.mock('../../../src/sse.js', () => ({ emitStatusEvent: vi.fn(), emitLogEvent: vi.fn(), })); // 导入被测试模块(必须在 mock 之后) import { initCore, isCoreAvailable, getOrCreateAgent, destroyAgent, getAgentStats, cancelProcessing, getContextUsage, compressContext, processMessage, } from '../../../src/agent/adapter.js'; import { getSessionManager } from '../../../src/session/manager.js'; import { broadcastToSession } from '../../../src/ws.js'; describe('Agent Adapter', () => { beforeEach(() => { vi.clearAllMocks(); resetCoreMocks(); }); afterEach(() => { vi.restoreAllMocks(); }); describe('initCore - Core 模块初始化', () => { it('成功初始化 Core 模块时返回 true', async () => { const result = await initCore(); expect(result).toBe(true); }); it('初始化后 isCoreAvailable 返回 true', async () => { await initCore(); expect(isCoreAvailable()).toBe(true); }); }); describe('getOrCreateAgent - Agent 创建与缓存', () => { it('成功创建 Agent 实例', async () => { await initCore(); const agent = await getOrCreateAgent('session-create'); expect(agent).not.toBeNull(); }); it('重复获取同一 session 返回缓存的 Agent', async () => { await initCore(); const agent1 = await getOrCreateAgent('session-cache'); const agent2 = await getOrCreateAgent('session-cache'); expect(agent1).toBe(agent2); }); }); describe('destroyAgent - Agent 销毁', () => { it('从缓存中移除 Agent', async () => { await initCore(); // 创建 Agent const agent1 = await getOrCreateAgent('session-destroy'); expect(agent1).not.toBeNull(); // 销毁 Agent await destroyAgent('session-destroy'); // 再次获取应创建新 Agent const agent2 = await getOrCreateAgent('session-destroy'); expect(agent2).not.toBe(agent1); }); }); describe('getAgentStats - Agent 统计信息', () => { it('Agent 不存在时返回 available: true 但无其他信息', async () => { await initCore(); const stats = getAgentStats('non-existent-session'); expect(stats).toEqual({ available: true }); }); it('Agent 存在时返回完整统计信息', async () => { await initCore(); await getOrCreateAgent('session-stats'); const stats = getAgentStats('session-stats'); expect(stats.available).toBe(true); expect(stats.toolCount).toEqual({ core: 5, discovered: 0, total: 5 }); expect(stats.contextUsage).toBe('10k / 200k'); }); }); describe('cancelProcessing - 取消处理', () => { it('更新会话状态为 idle', () => { const mockSessionManager = getSessionManager(); cancelProcessing('session-cancel'); expect(mockSessionManager.updateStatus).toHaveBeenCalledWith('session-cancel', 'idle'); }); }); describe('getContextUsage - 获取上下文使用情况', () => { it('Agent 不存在时返回 null', async () => { await initCore(); const usage = getContextUsage('non-existent-context'); expect(usage).toBeNull(); }); it('Agent 存在时返回使用情况', async () => { await initCore(); await getOrCreateAgent('session-context'); const usage = getContextUsage('session-context'); expect(usage).not.toBeNull(); expect(usage?.formatted).toBe('10k / 200k'); expect(usage?.input).toBe(10000); }); }); describe('compressContext - 上下文压缩', () => { it('Agent 不存在时返回 null', async () => { await initCore(); const result = await compressContext('non-existent-compress'); expect(result).toBeNull(); }); it('压缩成功时返回结果', async () => { await initCore(); await getOrCreateAgent('session-compress'); const result = await compressContext('session-compress'); expect(result).not.toBeNull(); expect(result?.type).toBe('prune'); expect(result?.freedTokens).toBe(1000); }); }); describe('processMessage - 消息处理', () => { it('成功处理消息并返回响应', async () => { await initCore(); await processMessage('session-msg', 'Hello'); // 应该发送 done 消息 expect(broadcastToSession).toHaveBeenCalledWith('session-msg', expect.objectContaining({ type: 'done', })); }); }); });