import { describe, expect, it } from 'vitest'; import { rankEntities, percentiles, inputsHash } from '../src/rank.js'; describe('rankEntities', () => { it('is deterministic and handles ties with competition ranking', () => { const items = [ { id: 'b', value: 10 }, { id: 'a', value: 10 }, { id: 'c', value: 5 }, { id: 'd', value: 1 }, ]; const r = rankEntities(items); expect(r.map((x) => [x.id, x.rank])).toEqual([ ['a', 1], ['b', 1], ['c', 3], ['d', 4], ]); expect(r[0]!.percentile).toBe(100); expect(r[3]!.percentile).toBe(0); expect(rankEntities([...items].reverse())).toEqual(r); }); it('drops non-finite values and ranks ascending when requested', () => { const r = rankEntities([{ id: 'x', value: NaN }, { id: 'y', value: 2 }, { id: 'z', value: 1 }], { descending: false }); expect(r.map((x) => x.id)).toEqual(['z', 'y']); expect(r[0]!.eligible).toBe(2); }); it('percentiles and hash are stable', async () => { const items = [{ id: 'a', value: 3 }, { id: 'b', value: 1 }]; expect(percentiles(items).get('a')).toBe(100); expect(await inputsHash(items)).toBe(await inputsHash([...items].reverse())); }); });