ClaudeCliProtocol.mock.test.js 1.61 KB
/**
 * ClaudeCliProtocol · mock 模式 smoke test
 */

const { ClaudeCliProtocol } = require('./ClaudeCliProtocol');

describe('ClaudeCliProtocol · mock mode', () => {
  it('connect is no-op in mock mode', async () => {
    const p = new ClaudeCliProtocol({ name: 'devloop-pm' }, { mock: true });
    await p.connect(null, process.cwd());
    expect(p.isConnected).toBe(true);
    p.disconnect();
  });

  it('sendPrompt emits chunks + session/result from fixture', async () => {
    const p = new ClaudeCliProtocol({ name: 'devloop-pm' }, { mock: true });
    await p.connect(null, process.cwd());

    const chunks = [];
    let result = null;
    p.on('session_update', (u) => {
      if (u.update?.sessionUpdate === 'agent_message_chunk') {
        chunks.push(u.update.content.text);
      }
    });
    p.on('acp_event', (ev) => {
      if (ev.method === 'session/result') result = ev.params;
    });

    await p.sendPrompt('please plan the work');
    expect(chunks.length).toBeGreaterThan(0);
    expect(result).not.toBeNull();
    expect(result.mock).toBe(true);
    expect(result.stop_reason).toBe('end_turn');
    p.disconnect();
  });

  it('falls back to echo response when no fixture matches', async () => {
    const p = new ClaudeCliProtocol(
      { name: 'no-such-agent-zzz' },
      { mock: true, mockFixtureDir: '/tmp/devloop-mock-empty-' + Date.now() },
    );
    await p.connect(null, process.cwd());
    let result = null;
    p.on('acp_event', (ev) => { if (ev.method === 'session/result') result = ev.params; });
    await p.sendPrompt('hello');
    expect(result.result).toMatch(/mock-ok/);
    p.disconnect();
  });
});