SPB Git forge

spb/cancerindex

Public
37commits 1branches 0releases
2.9 MBsize
maindefault branch
10 days agolast push
TypeScript 97.2% SQL 1.5% CSS 0.6% JavaScript 0.5%
3.3 KB · 55 lines typescript
Raw Blame History
1import { describe, expect, it } from 'vitest';2import { DRUG_PIPELINE_FORMULA_VERSION, PIPELINE_STAGES, maxPhase, phaseLabel, stageFor } from './drug-pipeline.js';34describe('drug pipeline — highest phase', () => {5  it('ranks registry phases and treats EARLY_PHASE1 as phase 1', () => {6    expect(maxPhase([['PHASE2'], ['PHASE3']])).toBe('PHASE3');7    expect(maxPhase([['PHASE2', 'PHASE3']])).toBe('PHASE3');8    expect(maxPhase([['PHASE1', 'PHASE2']])).toBe('PHASE2');9    expect(maxPhase([['PHASE4'], ['NA']])).toBe('PHASE4');10    expect(maxPhase([['EARLY_PHASE1']])).toBe('EARLY_PHASE1');11    expect(maxPhase([['EARLY_PHASE1'], ['PHASE1']])).toBe('PHASE1');12    expect(maxPhase([['NA'], []])).toBe('NA');13    expect(maxPhase([[], ['UNKNOWN_LABEL']])).toBeNull();14    expect(maxPhase([])).toBeNull();15  });16  it('phaseLabel mirrors maxPhase for SQL-side ranks', () => {17    expect(phaseLabel(4, false)).toBe('PHASE4');18    expect(phaseLabel(3, true)).toBe('PHASE3');19    expect(phaseLabel(2, false)).toBe('PHASE2');20    expect(phaseLabel(1, true)).toBe('PHASE1');21    expect(phaseLabel(1, false)).toBe('EARLY_PHASE1');22    expect(phaseLabel(0, false)).toBe('NA');23    expect(phaseLabel(null, false)).toBeNull();24  });25});2627describe('drug pipeline — stage rule', () => {28  it('approval beats everything; withdrawn only when every approval is withdrawn/superseded', () => {29    expect(stageFor({ approvedLike: 1, withdrawnLike: 0, totalTrials: 0, maxPhase: null })).toBe('approved');30    expect(stageFor({ approvedLike: 1, withdrawnLike: 3, totalTrials: 12, maxPhase: 'PHASE3' })).toBe('approved');31    expect(stageFor({ approvedLike: 0, withdrawnLike: 2, totalTrials: 40, maxPhase: 'PHASE4' })).toBe('withdrawn');32  });33  it('otherwise the highest phase among interventional trials decides', () => {34    expect(stageFor({ approvedLike: 0, withdrawnLike: 0, totalTrials: 3, maxPhase: 'PHASE4' })).toBe('phase4');35    expect(stageFor({ approvedLike: 0, withdrawnLike: 0, totalTrials: 3, maxPhase: 'PHASE3' })).toBe('phase3');36    expect(stageFor({ approvedLike: 0, withdrawnLike: 0, totalTrials: 3, maxPhase: 'PHASE2' })).toBe('phase2');37    expect(stageFor({ approvedLike: 0, withdrawnLike: 0, totalTrials: 3, maxPhase: 'PHASE1' })).toBe('phase1');38    expect(stageFor({ approvedLike: 0, withdrawnLike: 0, totalTrials: 3, maxPhase: 'EARLY_PHASE1' })).toBe('phase1');39    expect(stageFor({ approvedLike: 0, withdrawnLike: 0, totalTrials: 3, maxPhase: 'NA' })).toBe('phase_not_stated');40    expect(stageFor({ approvedLike: 0, withdrawnLike: 0, totalTrials: 3, maxPhase: null })).toBe('phase_not_stated');41  });42  it('no trials and no approvals → no row', () => {43    expect(stageFor({ approvedLike: 0, withdrawnLike: 0, totalTrials: 0, maxPhase: null })).toBeNull();44  });45  it('every stage the rule can return is a declared stage; the formula is versioned', () => {46    const inputs = [47      { approvedLike: 1, withdrawnLike: 0, totalTrials: 0, maxPhase: null },48      { approvedLike: 0, withdrawnLike: 1, totalTrials: 0, maxPhase: null },49      ...['PHASE4', 'PHASE3', 'PHASE2', 'PHASE1', 'EARLY_PHASE1', 'NA'].map((p) => ({ approvedLike: 0, withdrawnLike: 0, totalTrials: 1, maxPhase: p })),50    ];51    for (const i of inputs) expect(PIPELINE_STAGES).toContain(stageFor(i));52    expect(DRUG_PIPELINE_FORMULA_VERSION).toMatch(/^ci-drug-pipeline-v\d+$/);53  });54});55