prompt-builder.test.js 3.67 KB
import { describe, it, expect, beforeEach } from 'vitest';
const path = require('path');
const fs = require('fs');
const { PromptBuilder } = require('../../core/prompt-builder');

describe('PromptBuilder', () => {
  const baseDir = path.join(__dirname, '..', 'fixtures');
  const configPath = path.join(baseDir, 'config.json');
  let config;
  let builder;

  beforeEach(() => {
    config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
    builder = new PromptBuilder(config, baseDir);
  });

  describe('getProtocol', () => {
    it('should load executor protocol', () => {
      const protocol = builder.getProtocol('executor');
      expect(protocol).toContain('[RESULT: DONE]');
      expect(protocol).toContain('[RESULT: ERROR]');
    });

    it('should load validator protocol', () => {
      const protocol = builder.getProtocol('validator');
      expect(protocol).toContain('[RESULT: PASS]');
      expect(protocol).toContain('[RESULT: FAIL]');
    });

    it('should load master protocol', () => {
      const protocol = builder.getProtocol('master');
      expect(protocol).toContain('[CALL:');
      expect(protocol).toContain('{{AVAILABLE_AGENTS}}');
    });

    it('should return empty string for unknown type', () => {
      const protocol = builder.getProtocol('unknown');
      expect(protocol).toBe('');
    });
  });

  describe('getAgentPrompt', () => {
    it('should load coder prompt', () => {
      const prompt = builder.getAgentPrompt('coder');
      expect(prompt).toContain('Coder');
      expect(prompt).toContain('代码');
    });

    it('should load verifier prompt', () => {
      const prompt = builder.getAgentPrompt('verifier');
      expect(prompt).toContain('Verifier');
    });

    it('should throw for unknown agent', () => {
      expect(() => builder.getAgentPrompt('unknown')).toThrow('Agent not found');
    });
  });

  describe('build', () => {
    it('should combine protocol and agent prompt for executor', () => {
      const result = builder.build('coder');

      // 应该包含 executor protocol
      expect(result).toContain('[RESULT: DONE]');
      expect(result).toContain('[RESULT: ERROR]');

      // 应该包含 coder prompt
      expect(result).toContain('Coder');
    });

    it('should combine protocol and agent prompt for validator', () => {
      const result = builder.build('verifier');

      // 应该包含 validator protocol
      expect(result).toContain('[RESULT: PASS]');
      expect(result).toContain('[RESULT: FAIL]');

      // 应该包含 verifier prompt
      expect(result).toContain('Verifier');
    });

    it('should replace {{AVAILABLE_AGENTS}} in master protocol', () => {
      const result = builder.build('master');

      // 不应该包含占位符
      expect(result).not.toContain('{{AVAILABLE_AGENTS}}');

      // 应该包含实际的 agent 列表
      expect(result).toContain('coder');
      expect(result).toContain('verifier');
      expect(result).toContain('frontend-tester');
    });

    it('should append user task when provided', () => {
      const result = builder.build('coder', '实现一个计算器');

      expect(result).toContain('当前任务');
      expect(result).toContain('实现一个计算器');
    });

    it('should not include task section when no task provided', () => {
      const result = builder.build('coder');

      expect(result).not.toContain('当前任务');
    });
  });

  describe('caching', () => {
    it('should cache loaded files', () => {
      // 第一次加载
      builder.build('coder');

      // 第二次加载应该使用缓存
      const cacheSize = builder.promptCache.size;
      builder.build('coder');

      expect(builder.promptCache.size).toBe(cacheSize);
    });
  });
});