#!/usr/bin/env node /** * role-router unit tests — 6 fixture (每角色 2 条) * 跑法: node role-router.test.mjs */ import { detectRoles, buildContext, DEV_RE, TEST_RE, PM_RE } from './role-router.mjs'; import { execFileSync } from 'child_process'; import { dirname, join } from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const HOOK = join(__dirname, 'role-router.mjs'); const fixtures = [ { prompt: '帮我实现一下登录页面', expect: ['dev'] }, { prompt: 'refactor the auth middleware', expect: ['dev'] }, { prompt: '跑一下回归测试看看', expect: ['test'] }, { prompt: 'write unit tests for the parser', expect: ['test'] }, { prompt: '排期一下下周的需求', expect: ['pm'] }, { prompt: 'draft the PRD for new chat module', expect: ['pm'] }, { prompt: '今天天气怎么样', expect: [] }, { prompt: 'PM 要我先调研后排期再让 dev 实现 + 写测试', expect: ['dev', 'test', 'pm'] }, ]; let pass = 0, fail = 0; const failures = []; for (const f of fixtures) { const got = detectRoles(f.prompt); const ok = JSON.stringify(got.sort()) === JSON.stringify(f.expect.sort()); if (ok) { pass++; console.log(`PASS "${f.prompt}" → [${got.join(',')}]`); } else { fail++; failures.push({ prompt: f.prompt, expected: f.expect, got }); console.log(`FAIL "${f.prompt}" expected=[${f.expect.join(',')}] got=[${got.join(',')}]`); } } // integration: pipe JSON to hook subprocess function runHook(promptObj) { const input = JSON.stringify(promptObj); const out = execFileSync('node', [HOOK], { input, encoding: 'utf8' }); return JSON.parse(out); } console.log('\n--- integration (subprocess pipe) ---'); const t1 = runHook({ prompt: '帮我修个 bug' }); const hasContextDev = t1?.hookSpecificOutput?.additionalContext?.includes('role="dev"'); if (hasContextDev) { pass++; console.log('PASS subprocess injects dev role'); } else { fail++; failures.push({prompt:'pipe-dev', got:t1}); console.log('FAIL subprocess dev:', JSON.stringify(t1)); } const t2 = runHook({ prompt: 'hello world' }); const continued = t2?.continue === true; if (continued) { pass++; console.log('PASS no-match passes through'); } else { fail++; failures.push({prompt:'pipe-noop', got:t2}); console.log('FAIL no-match:', JSON.stringify(t2)); } console.log(`\nResult: ${pass} pass, ${fail} fail`); if (fail > 0) { console.error('FAILURES:', JSON.stringify(failures, null, 2)); process.exit(1); } process.exit(0);