From 3232dff25a718faa8df1364d4ce3f2adbd393277 Mon Sep 17 00:00:00 2001 From: larssand Date: Thu, 10 Sep 2026 17:45:53 +0200 Subject: [PATCH] Add regression test: a DNS heat must not drop a driver's other heats The user asked specifically to confirm this: a driver who DNS'd in one qualifying heat but raced normally in others must still be fully counted across all of them, not dropped. Traced through the fix (buildQualifyingStandings backfills a DNS row per finished heat, accumulating into the same per-driver entry across every heat they're in) and confirmed it already handles this correctly - added a test that exercises exactly this scenario (DNS in heat 1, wins heat 2 and 3) to lock it in, since this specific multi-heat aggregation path had no prior coverage. Co-Authored-By: Claude Sonnet 5 --- tests/race_timing_logic.test.js | 44 +++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/tests/race_timing_logic.test.js b/tests/race_timing_logic.test.js index f55a198..2168a9a 100644 --- a/tests/race_timing_logic.test.js +++ b/tests/race_timing_logic.test.js @@ -657,6 +657,50 @@ test("qualifying standings keep a driver who never recorded a passing (DNS) so t assert.equal(standings[1].bestSingleLapMs, Number.MAX_SAFE_INTEGER, "a DNS driver's missing lap is never confused for a 0ms fastest lap"); }); +test("a driver who DNS'd in one heat but raced normally in the others is still fully counted across all of them, not dropped", () => { + const sessions = [ + { id: "q1h1", type: "qualification", name: "Q1 H1", status: "finished" }, + { id: "q2h1", type: "qualification", name: "Q2 H1", status: "finished" }, + { id: "q3h1", type: "qualification", name: "Q3 H1", status: "finished" }, + ]; + // driver_2 DNS'd heat 1 (dead battery), but raced - and won - heats 2 and 3. + const rowsBySession = { + q1h1: [{ driverId: "driver_1", driverName: "One", comparisonMs: 16000, bestLapMs: 16000, resultDisplay: "16.000" }], + q2h1: [ + { driverId: "driver_2", driverName: "Two", comparisonMs: 15000, bestLapMs: 15000, resultDisplay: "15.000" }, + { driverId: "driver_1", driverName: "One", comparisonMs: 16500, bestLapMs: 16500, resultDisplay: "16.500" }, + ], + q3h1: [ + { driverId: "driver_2", driverName: "Two", comparisonMs: 14800, bestLapMs: 14800, resultDisplay: "14.800" }, + { driverId: "driver_1", driverName: "One", comparisonMs: 16200, bestLapMs: 16200, resultDisplay: "16.200" }, + ], + }; + const entrants = [{ id: "driver_1", name: "One" }, { id: "driver_2", name: "Two" }]; + const standings = buildQualifyingStandings( + // Counting all 3 rounds (not just the best one) so a dropped round would be visible + // in the total score, not silently hidden by "best of N" already excluding it. + { id: "event_1", raceConfig: { countedQualRounds: 3 } }, + { + getSessionsForEvent: () => sessions, + buildLeaderboard: (session) => rowsBySession[session.id], + getSessionEntrants: () => entrants, + isHighPointsTable, + getQualifyingPointsValue, + compareNumberSet, + buildQualifyingTieBreakNote: (row, tieBreak) => buildQualifyingTieBreakNoteLogic(row, tieBreak, { t: testTranslate, formatLap: testFormatLap }), + formatLap: testFormatLap, + formatRaceClock: testFormatRaceClock, + t: testTranslate, + hasQualifyingPrimaryTie, + } + ); + + const driverTwo = standings.find((row) => row.driverId === "driver_2"); + assert.ok(driverTwo, "driver_2 still appears at all - not dropped because of the heat 1 DNS"); + assert.deepEqual(driverTwo.ranks.sort((a, b) => a - b), [1, 1, 2], "won heat 2 and heat 3 outright (rank 1), only heat 1's DNS counts against them (rank 2 of 2)"); + assert.equal(driverTwo.countedPoints.length, 3, "all three heats count toward the score, including the DNS one - it isn't excluded or silently skipped"); +}); + test("session channel statistics summarize splits and pit stops per competitor", () => { const result = { competitors: {