spb/cancerindex
Public
TypeScript 97.2%
SQL 1.5%
CSS 0.6%
JavaScript 0.5%
1import { describe, expect, it } from 'vitest';2import { rankSearchHits, TIER, type SearchHit } from '../src/lib/search.js';34const hit = (p: Partial<SearchHit> & { id: string; tier: SearchHit['tier'] }): SearchHit => ({ type: 'cancer', slug: p.id, name: p.id, subtitle: null, score: 0.5, ...p });56describe('rankSearchHits', () => {7 it('orders exact > alias > prefix > fuzzy regardless of input order', () => {8 const out = rankSearchHits([hit({ id: 'fz', tier: TIER.fuzzy, score: 0.99 }), hit({ id: 'pf', tier: TIER.prefix }), hit({ id: 'ex', tier: TIER.exact, score: 0.1 }), hit({ id: 'al', tier: TIER.alias })]);9 expect(out.map((r) => r.id)).toEqual(['ex', 'al', 'pf', 'fz']);10 expect(out.map((r) => r.match)).toEqual(['exact', 'alias', 'prefix', 'fuzzy']);11 });1213 it('is deterministic within a tier: score desc, entity type, shorter name, name, id', () => {14 const out = rankSearchHits([15 hit({ id: 'b', tier: TIER.prefix, score: 0.5, name: 'Lung Cancer' }),16 hit({ id: 'a', tier: TIER.prefix, score: 0.5, name: 'Lung Adenocarcinoma' }),17 hit({ id: 'g', tier: TIER.prefix, score: 0.5, type: 'gene', name: 'LUNG' }),18 hit({ id: 'c', tier: TIER.prefix, score: 0.9, name: 'Lung Neoplasm' }),19 ]);20 expect(out.map((r) => r.id)).toEqual(['c', 'b', 'a', 'g']);21 expect(rankSearchHits([hit({ id: 'x', tier: TIER.prefix }), hit({ id: 'y', tier: TIER.prefix })]).map((r) => r.id)).toEqual(['x', 'y']);22 });2324 it('keeps one result per (type,id) using the best tier', () => {25 const out = rankSearchHits([hit({ id: 'x', tier: TIER.fuzzy }), hit({ id: 'x', tier: TIER.exact }), hit({ id: 'x', tier: TIER.alias })]);26 expect(out).toHaveLength(1);27 expect(out[0]!.match).toBe('exact');28 });2930 it('caps the result count', () => {31 const many = Array.from({ length: 50 }, (_, i) => hit({ id: `id${String(i).padStart(2, '0')}`, tier: TIER.prefix }));32 expect(rankSearchHits(many, 20)).toHaveLength(20);33 });34});35