这是「GSD 全景代码解析」专题的第 50 篇。
一、Context Engine 测试解析
context-engine.test.js 是 GSD 测试体系中最复杂的单元测试之一,它验证上下文预算管理、截断策略和引用注入的正确性。
1.1 上下文预算测试
describe('ContextEngine', () => {
test('应正确计算当前上下文大小', () => {
const engine = new ContextEngine({ budget: 4000 });
engine.addSystemPrompt('你是一个助手'); // ~10 tokens
engine.addUserMessage('请帮我写代码'); // ~8 tokens
expect(engine.getCurrentUsage()).toBe(18);
expect(engine.getRemainingBudget()).toBe(3982);
});
test('超出预算应触发截断', () => {
const engine = new ContextEngine({ budget: 100 });
engine.addSystemPrompt('x'.repeat(500)); // 远超预算
expect(engine.isTruncated).toBe(true);
expect(engine.getCurrentUsage()).toBeLessThanOrEqual(100);
});
});1.2 截断策略测试
describe('Truncation Strategies', () => {
test('FIFO 截断应移除最早的消息', () => {
const engine = new ContextEngine({
budget: 50,
strategy: 'fifo'
});
engine.addMessage('msg1');
engine.addMessage('msg2');
engine.addMessage('msg3'); // 触发截断
const messages = engine.getMessages();
expect(messages.map(m => m.content)).not.toContain('msg1');
});
test('Summary 截断应保留摘要', () => {
const engine = new ContextEngine({
budget: 100,
strategy: 'summary'
});
// 添加足够多的消息触发截断
for (let i = 0; i < 20; i++) {
engine.addMessage(`重要信息 ${i}`);
}
const summary = engine.getSummary();
expect(summary).toContain('先前对话');
expect(engine.getCurrentUsage()).toBeLessThanOrEqual(100);
});
test('Priority 截断应保留高优先级内容', () => {
const engine = new ContextEngine({
budget: 50,
strategy: 'priority'
});
engine.addMessage({ content: '低优先级', priority: 1 });
engine.addMessage({ content: '高优先级', priority: 10 });
engine.addMessage({ content: '中等优先级', priority: 5 });
// 强制截断
engine.truncate();
const messages = engine.getMessages();
expect(messages.map(m => m.content)).toContain('高优先级');
expect(messages.map(m => m.content)).not.toContain('低优先级');
});
});1.3 @Reference 解析测试
test('应正确解析 @ 引用', async () => {
const engine = new ContextEngine();
const prompt = '请查看 @src/utils/helper.ts 的代码';
const resolved = await engine.resolveReferences(prompt, {
'src/utils/helper.ts': 'export function helper() {}'
});
expect(resolved).toContain('export function helper() {}');
expect(resolved).not.toContain('@src/utils/helper.ts');
});
test('不存在的引用应抛出 ReferenceError', async () => {
const engine = new ContextEngine();
const prompt = '请查看 @non-existent.md';
await expect(engine.resolveReferences(prompt, {}))
.rejects.toThrow(ReferenceError);
});二、Phase Runner 集成测试
phase-runner.integration.test.js 验证 Phase Runner 作为执行引擎核心组件的集成行为。
2.1 完整 Phase 执行测试
describe('PhaseRunner Integration', () => {
test('应完成完整的 plan-phase 执行', async () => {
const runner = new PhaseRunner();
const plan = await loadTestPlan('simple-project');
const result = await runner.run('plan-phase', plan);
expect(result.status).toBe('COMPLETED');
expect(result.artifacts).toContain('PROJECT.md');
expect(result.artifacts).toContain('ROADMAP.md');
expect(result.duration).toBeGreaterThan(0);
});
test('execute-phase 应正确调度任务', async () => {
const runner = new PhaseRunner();
const plan = await loadTestPlan('with-tasks');
const taskOrder = [];
runner.onTaskStart((task) => taskOrder.push(task.id));
await runner.run('execute-phase', plan);
// 验证依赖顺序:任务 2 依赖任务 1
expect(taskOrder.indexOf('1')).toBeLessThan(taskOrder.indexOf('2'));
});
});2.2 错误恢复测试
test('任务失败应触发 rollback', async () => {
const runner = new PhaseRunner();
const plan = await loadTestPlan('failing-task');
// 让第二个任务失败
mockAgent('coder').mockRejectedValue(new Error('编译失败'));
const result = await runner.run('execute-phase', plan);
expect(result.status).toBe('FAILED');
expect(result.rollbackActions).toHaveLengthGreaterThan(0);
// 验证已完成的任务被回滚
const rolledBackTasks = result.rollbackActions.map(a => a.taskId);
expect(rolledBackTasks).toContain('1');
});
test('部分失败应支持 continue 模式', async () => {
const runner = new PhaseRunner({ onFailure: 'continue' });
const plan = await loadTestPlan('failing-task');
mockAgent('coder').mockRejectedValue(new Error('编译失败'));
const result = await runner.run('execute-phase', plan);
expect(result.status).toBe('COMPLETED_WITH_WARNINGS');
expect(result.completedTasks).toHaveLength(2);
expect(result.failedTasks).toHaveLength(1);
});三、Hook System 生命周期测试
hook-system.integration.test.js 验证钩子系统的注册、触发顺序和错误处理。
3.1 钩子注册与触发
describe('HookSystem', () => {
test('应在正确生命周期点触发钩子', async () => {
const hooks = new HookSystem();
const events = [];
hooks.register('beforeTask', () => events.push('before'));
hooks.register('afterTask', () => events.push('after'));
hooks.register('onError', () => events.push('error'));
await hooks.trigger('beforeTask', { taskId: '1' });
await hooks.trigger('afterTask', { taskId: '1' });
expect(events).toEqual(['before', 'after']);
});
test('多个同类型钩子应按注册顺序执行', async () => {
const hooks = new HookSystem();
const order = [];
hooks.register('beforeTask', () => order.push(1));
hooks.register('beforeTask', () => order.push(2));
hooks.register('beforeTask', () => order.push(3));
await hooks.trigger('beforeTask', {});
expect(order).toEqual([1, 2, 3]);
});
});3.2 钩子错误传播
test('钩子错误不应中断主流程', async () => {
const hooks = new HookSystem();
let mainFlowCompleted = false;
hooks.register('beforeTask', () => {
throw new Error('钩子崩溃');
});
try {
await hooks.trigger('beforeTask', {});
mainFlowCompleted = true;
} catch (e) {
// 不应进入这里
}
expect(mainFlowCompleted).toBe(true);
});
test('应支持同步和异步钩子', async () => {
const hooks = new HookSystem();
const results = [];
hooks.register('afterTask', () => results.push('sync'));
hooks.register('afterTask', async () => {
await delay(10);
results.push('async');
});
await hooks.trigger('afterTask', {});
expect(results).toEqual(['sync', 'async']);
});四、Mock Agent 工厂
function createMockAgent(name, behavior = 'success') {
const responses = {
success: (task) => ({ result: `completed: ${task.name}` }),
failure: () => { throw new Error('Agent failed'); },
slow: async (task) => {
await delay(5000);
return { result: `slow: ${task.name}` };
}
};
return {
name,
invoke: jest.fn(async (task) => responses[behavior](task))
};
}五、测试性能基准
Plan Parser: ~50ms / 100 plans
State Machine: ~5ms / 1000 transitions
Agent Delegator: ~20ms / 100 selections
Context Engine: ~30ms / 100 truncations
Phase Runner: ~200ms / 1 full phase (mocked)
Hook System: ~10ms / 100 triggers下一篇预告: 第 51 篇《安全体系:secret-audit、credential-gate 与防注入机制》
我们将深入解析 GSD 的安全防护体系,包括敏感信息审计、凭据门控和提示词注入防御机制。敬请期待。