// tests/verifier_core.test.mjs import { describe, it, expect, vi } from 'vitest'; import { runVerifier } from '../src/verifier/verifier_core.mjs'; describe('verifier_core.mjs', () => { it('returns ok=true when SCORE >= 0.5 JSON', async () => { const sample = { question: 'What is love?', context: [{ content: 'ctx' }], gen: { answer: 'Love is unity.', raw: 'Love is unity.' }, }; const provider = { generate: vi.fn(async () => JSON.stringify({ REASONING: ['ok'], SCORE: 0.9 }), ), }; const result = await runVerifier( { question: sample.question, context: sample.context, gen: sample.gen, }, provider, ); expect(provider.generate).toHaveBeenCalledOnce(); expect(result.ok).toBe(true); expect(result.score).toBe(0.9); expect(result.reasoning).toEqual(['ok']); }); it('returns ok=false when SCORE < 0.5 JSON', async () => { const sample = { question: 'What is love?', context: [{ content: 'ctx' }], gen: { answer: 'Bad answer', raw: 'Bad answer' }, }; const provider = { generate: vi.fn(async () => JSON.stringify({ REASONING: ['bad'], SCORE: 0.1 }), ), }; const result = await runVerifier( { question: sample.question, context: sample.context, gen: sample.gen, }, provider, ); expect(result.ok).toBe(false); expect(result.score).toBe(0.1); }); it('handles numeric string SCORE and preserves reasoning', async () => { const sample = { question: 'What is love?', context: [{ content: 'ctx' }], gen: { answer: 'Reasonable answer', raw: 'Reasonable answer' }, }; const provider = { generate: vi.fn(async () => JSON.stringify({ REASONING: ['fine'], SCORE: '0.7' }), ), }; const result = await runVerifier( { question: sample.question, context: sample.context, gen: sample.gen, }, provider, ); expect(result.ok).toBe(true); expect(result.score).toBe(0.7); expect(result.reasoning).toEqual(['fine']); }); it('handles PASS/FAIL SCORE strings', async () => { const sample = { question: 'What is love?', context: [{ content: 'ctx' }], gen: { answer: 'Reasonable answer', raw: 'Reasonable answer' }, }; const providerPass = { generate: vi.fn(async () => JSON.stringify({ REASONING: ['ok'], SCORE: 'PASS' }), ), }; const resPass = await runVerifier( { question: sample.question, context: sample.context, gen: sample.gen }, providerPass, ); expect(resPass.ok).toBe(true); expect(resPass.score).toBe('PASS'); const providerFail = { generate: vi.fn(async () => JSON.stringify({ REASONING: ['bad'], SCORE: 'FAIL' }), ), }; const resFail = await runVerifier( { question: sample.question, context: sample.context, gen: sample.gen }, providerFail, ); expect(resFail.ok).toBe(false); expect(resFail.score).toBe('FAIL'); }); it('parses unquoted PASS with noisy prefix', async () => { const sample = { question: 'What is love?', context: [{ content: 'ctx' }], gen: { answer: 'Reasonable answer', raw: 'Reasonable answer' }, }; const provider = { generate: vi.fn(async () => 'PROMPT = ["x","y"], "SCORE": PASS}', ), }; const res = await runVerifier( { question: sample.question, context: sample.context, gen: sample.gen }, provider, ); expect(res.ok).toBe(true); expect(res.score).toBe('PASS'); }); it('parses complex PASS transcript with PROMPT array and REASONING', async () => { const sample = { question: 'What is love?', context: [{ content: 'ctx' }], gen: { answer: 'Reasonable answer', raw: 'Reasonable answer' }, }; const provider = { generate: vi.fn(async () => `PROMPT = ["The QUESTION asks how Q'uo differentiates between spiritual advancement and the skill of channeling or using astrology.", 'The CONTEXT provides a detailed discussion from Q\\'uo on this differentiation.', "Specifically, the CONTEXT states that being able to use astrology or channeling is not necessarily a sign of spiritual advancement; rather, it indicates past psychic work in those areas.", 'Q\\'uo uses the analogy of a world-class pianist to illustrate that having great talents does not automatically make one spiritually advanced.', 'The ANSWER accurately reflects this differentiation and example provided by Q\\'uo in the CONTEXT.', "Therefore, the ANSWER is faithful to the CONTEXT given the QUESTION."], "REASONING": ['The QUESTION asks for the distinction made by Q\\'uo between spiritual advancement and the skill of channeling or using astrology.', 'The CONTEXT provides a detailed discussion where Q\\'uo explains that using astrology or channeling is not necessarily a sign of spiritual advancement but rather indicates past psychic work.', 'Q\\'uo uses the example of a world-class pianist to illustrate that great talents do not automatically make one spiritually advanced.', "The ANSWER correctly identifies this differentiation and uses the pianist analogy as provided in the CONTEXT.", 'Therefore, the ANSWER is faithful to the CONTEXT given the QUESTION.'], "SCORE": PASS}` ), }; const res = await runVerifier( { question: sample.question, context: sample.context, gen: sample.gen }, provider, ); expect(res.ok).toBe(true); expect(res.score).toBe('PASS'); expect(Array.isArray(res.reasoning) || res.reasoning == null).toBe(true); }); it('treats raw PASS token as ok', async () => { const sample = { question: 'What is love?', context: [{ content: 'ctx' }], gen: { answer: 'Reasonable answer', raw: 'Reasonable answer' }, }; const provider = { generate: vi.fn(async () => 'PROMPT = PASS'), }; const res = await runVerifier( { question: sample.question, context: sample.context, gen: sample.gen }, provider, ); expect(res.ok).toBe(true); expect(res.score).toBe('PASS'); }); });