// ============================================================ // BILIRUBIN parity tests — drives the TS port against vectors // captured from the authoritative vanilla implementation. // Regenerate vectors with `node scripts/capture-calc-vectors.js`. // ============================================================ import { describe, expect, it } from 'vitest'; import * as fs from 'node:fs'; import * as path from 'node:path'; import { classifyBhutani, classifyAapBili, type BiliRisk } from './bilirubin'; interface BhutaniCase { name: string; inputs: { hours: number; tsb: number }; output: { p95: number; p75: number; p40: number; zone: string }; } interface AapCase { name: string; inputs: { gaWeeks: number; hours: number; tsb: number; risk: BiliRisk }; output: { photoThreshold: number; exchangeThreshold: number; status: string }; } interface Vectors { bhutani: BhutaniCase[]; aap: AapCase[]; } const vectors: Vectors = JSON.parse( fs.readFileSync(path.join(__dirname, '..', '..', 'e2e', 'fixtures', 'calc-vectors.json'), 'utf8'), ); describe('Bhutani nomogram — parity with vanilla calculators.js', () => { it.each(vectors.bhutani)('$name', ({ inputs, output }) => { const actual = classifyBhutani(inputs.hours, inputs.tsb); expect(actual.p95).toBeCloseTo(output.p95, 10); expect(actual.p75).toBeCloseTo(output.p75, 10); expect(actual.p40).toBeCloseTo(output.p40, 10); expect(actual.zone).toBe(output.zone); }); }); describe('AAP 2022 bilirubin — parity with vanilla calculators.js', () => { it.each(vectors.aap)('$name', ({ inputs, output }) => { const actual = classifyAapBili(inputs.gaWeeks, inputs.hours, inputs.tsb, inputs.risk); expect(actual.photoThreshold).toBeCloseTo(output.photoThreshold, 10); expect(actual.exchangeThreshold).toBeCloseTo(output.exchangeThreshold, 10); expect(actual.status).toBe(output.status); }); });