a8489a22c7
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
65 lines
3.1 KiB
JavaScript
65 lines
3.1 KiB
JavaScript
import { describe, it, expect } from 'vitest';
|
|
import { classifyJudgeOutcome, buildVerdictBanner, parseVerdictAck } from './verdict-outcome-line.mjs';
|
|
|
|
describe('classifyJudgeOutcome', () => {
|
|
it('GO / NO-GO / degraded / skip', () => {
|
|
expect(classifyJudgeOutcome({ wired: true, decision: 'GO' })).toBe('GO');
|
|
expect(classifyJudgeOutcome({ wired: true, decision: 'NO-GO' })).toBe('NO-GO');
|
|
expect(classifyJudgeOutcome({ wired: false })).toBe('degraded');
|
|
expect(classifyJudgeOutcome(null)).toBe('skip');
|
|
});
|
|
it('skip-вердикт (судья не судил) → skip, не degraded', () => {
|
|
expect(classifyJudgeOutcome({ wired: false, skip: 'no_mentor_go' })).toBe('skip');
|
|
expect(classifyJudgeOutcome({ wired: false, unavailable: true })).toBe('degraded');
|
|
});
|
|
});
|
|
describe('buildVerdictBanner', () => {
|
|
it('баннер с гейтом и дословной причиной', () => {
|
|
const b = buildVerdictBanner({ outcome: 'NO-GO', gate: 'judge', round: 1, version: 1, reason: 'шаг 3 не проверяем' });
|
|
expect(b).toContain('🚫 NO-GO [judge] круг 1 v1');
|
|
expect(b).toContain('причина (дословно): шаг 3 не проверяем');
|
|
});
|
|
it('опускает круг/версию если не заданы', () => {
|
|
const b = buildVerdictBanner({ outcome: 'GO', gate: 'mentor' });
|
|
expect(b).toContain('✅ GO [mentor]');
|
|
expect(b).not.toContain('круг');
|
|
});
|
|
});
|
|
describe('parseVerdictAck', () => {
|
|
it('ловит `вердикт:` первой строкой', () => {
|
|
expect(parseVerdictAck('вердикт: NO-GO\nдалее...')).toBe(true);
|
|
expect(parseVerdictAck('обычный ответ')).toBe(false);
|
|
});
|
|
});
|
|
|
|
import { classifyRouterOutcome } from './verdict-outcome-line.mjs';
|
|
|
|
describe('classifyRouterOutcome (видимость роутера)', () => {
|
|
it('recommended_chain непустой → recommend', () => {
|
|
expect(classifyRouterOutcome({ recommended_chain: ['skill-x'] })).toBe('recommend');
|
|
});
|
|
it('recommended_node не direct → recommend', () => {
|
|
expect(classifyRouterOutcome({ recommended_node: 'skill-y' })).toBe('recommend');
|
|
});
|
|
it('direct / пустой → skip (скил не нужен)', () => {
|
|
expect(classifyRouterOutcome({ recommended_node: 'direct' })).toBe('skip');
|
|
expect(classifyRouterOutcome({ recommended_chain: [] })).toBe('skip');
|
|
});
|
|
it('null / недоступен → degraded', () => {
|
|
expect(classifyRouterOutcome(null)).toBe('degraded');
|
|
expect(classifyRouterOutcome({ unavailable: true })).toBe('degraded');
|
|
expect(classifyRouterOutcome({ wired: false })).toBe('degraded');
|
|
});
|
|
});
|
|
|
|
describe('buildVerdictBanner + parseVerdictAck: recommend', () => {
|
|
it('баннер recommend несёт ярлык и гейт', () => {
|
|
const b = buildVerdictBanner({ outcome: 'recommend', gate: 'router', reason: 'рекомендую skill-x' });
|
|
expect(b).toContain('recommend');
|
|
expect(b).toContain('[router]');
|
|
});
|
|
it('parseVerdictAck ловит вердикт: recommend', () => {
|
|
expect(parseVerdictAck('вердикт: recommend')).toBe(true);
|
|
});
|
|
});
|