From 077aa1700fbcaf3f499c2178e0e58e89ae9dcaf8 Mon Sep 17 00:00:00 2001 From: Martin Kagamino Lehoux Date: Fri, 25 Sep 2026 08:46:58 +0200 Subject: Chart power vs time for official climb attempts Snapshot average power per attempt in a nullable average_power_w column (backfilled from stored rides), plot each powered attempt on the climb page as duration vs average watts with ride hover and click-through, and show avg power in the attempts table. --- web/frontend/climb-attempts-logic.test.ts | 35 +++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 web/frontend/climb-attempts-logic.test.ts (limited to 'web/frontend/climb-attempts-logic.test.ts') diff --git a/web/frontend/climb-attempts-logic.test.ts b/web/frontend/climb-attempts-logic.test.ts new file mode 100644 index 0000000..6ce7353 --- /dev/null +++ b/web/frontend/climb-attempts-logic.test.ts @@ -0,0 +1,35 @@ +import assert from "node:assert/strict"; +import test from "node:test"; +import { attemptsDomain, formatAttemptDuration, formatPower } from "./climb-attempts-logic.ts"; +import type { ClimbAttemptPoint } from "./types.js"; + +const makePoint = (durationS: number, averagePowerW: number): ClimbAttemptPoint => ({ + durationS, + averagePowerW, + date: "01 Sep 2026, 10:00", + rideName: "ride", + url: "/rides/1", +}); + +test("formats attempt durations as mm:ss and h:mm:ss", () => { + assert.equal(formatAttemptDuration(0), "0:00"); + assert.equal(formatAttemptDuration(1110), "18:30"); + assert.equal(formatAttemptDuration(3723), "1:02:03"); + assert.equal(formatAttemptDuration(-5), "0:00"); +}); + +test("formats power in whole watts", () => { + assert.equal(formatPower(235.5), "236 W"); + assert.equal(formatPower(200), "200 W"); +}); + +test("pads zero-based axis domains above the data", () => { + const domain = attemptsDomain([makePoint(100, 250), makePoint(200, 150)]); + assert.equal(domain.maxDurationS, 216); + assert.equal(domain.maxPowerW, 270); +}); + +test("keeps a drawable domain when data is empty or zero", () => { + assert.deepEqual(attemptsDomain([]), { maxDurationS: 1, maxPowerW: 1 }); + assert.deepEqual(attemptsDomain([makePoint(0, 0)]), { maxDurationS: 1, maxPowerW: 1 }); +}); -- cgit v1.3