|
| 1 | +import { describe, expect, it } from 'vitest'; |
| 2 | + |
| 3 | +import { compareBenchmarkRecency } from './json-provider.js'; |
| 4 | + |
| 5 | +/** |
| 6 | + * `compareBenchmarkRecency` is the shared dedup ordering used by both the SQL |
| 7 | + * date-filtered query (ORDER BY br.date DESC, wr.run_started_at DESC NULLS LAST) |
| 8 | + * and the JSON provider's getLatestBenchmarks. A negative result means `a` sorts |
| 9 | + * before `b`, so `a` is the more-recent record kept by DISTINCT ON. |
| 10 | + * |
| 11 | + * Regression guard for the same-day multi-run bug: when a config is swept more |
| 12 | + * than once on the same calendar day, the later sweep (greater run_started_at) |
| 13 | + * must win — otherwise the earlier run's points shadow the re-sweep on the chart. |
| 14 | + */ |
| 15 | +describe('compareBenchmarkRecency', () => { |
| 16 | + const later = '2026-06-14T06:43:25Z'; |
| 17 | + const earlier = '2026-06-14T04:08:16Z'; |
| 18 | + |
| 19 | + it('orders a more recent calendar day first regardless of run_started_at', () => { |
| 20 | + expect(compareBenchmarkRecency('2026-06-14', '2026-06-13', earlier, later)).toBeLessThan(0); |
| 21 | + expect(compareBenchmarkRecency('2026-06-13', '2026-06-14', later, earlier)).toBeGreaterThan(0); |
| 22 | + }); |
| 23 | + |
| 24 | + it('tiebreaks same-day sweeps by run_started_at (latest sweep wins)', () => { |
| 25 | + // a = later sweep → a should sort first (negative). |
| 26 | + expect(compareBenchmarkRecency('2026-06-14', '2026-06-14', later, earlier)).toBeLessThan(0); |
| 27 | + // a = earlier sweep → a should sort after (positive). |
| 28 | + expect(compareBenchmarkRecency('2026-06-14', '2026-06-14', earlier, later)).toBeGreaterThan(0); |
| 29 | + }); |
| 30 | + |
| 31 | + it('sorts a null run_started_at last on a same-day tie', () => { |
| 32 | + expect(compareBenchmarkRecency('2026-06-14', '2026-06-14', null, earlier)).toBeGreaterThan(0); |
| 33 | + expect(compareBenchmarkRecency('2026-06-14', '2026-06-14', earlier, null)).toBeLessThan(0); |
| 34 | + }); |
| 35 | + |
| 36 | + it('treats equal date and equal run_started_at as a tie', () => { |
| 37 | + expect(compareBenchmarkRecency('2026-06-14', '2026-06-14', later, later)).toBe(0); |
| 38 | + expect(compareBenchmarkRecency('2026-06-14', '2026-06-14', null, null)).toBe(0); |
| 39 | + }); |
| 40 | + |
| 41 | + it('keeps the latest sweep first when sorting a same-day candidate list', () => { |
| 42 | + interface Row { |
| 43 | + run: string; |
| 44 | + started: string | null; |
| 45 | + } |
| 46 | + const rows: Row[] = [ |
| 47 | + { run: 'old', started: earlier }, |
| 48 | + { run: 'new', started: later }, |
| 49 | + { run: 'unknown', started: null }, |
| 50 | + ]; |
| 51 | + rows.sort((a, b) => compareBenchmarkRecency('2026-06-14', '2026-06-14', a.started, b.started)); |
| 52 | + expect(rows.map((r) => r.run)).toEqual(['new', 'old', 'unknown']); |
| 53 | + }); |
| 54 | +}); |
0 commit comments