diff options
Diffstat (limited to 'web/frontend/official-climb-profile-logic.test.ts')
| -rw-r--r-- | web/frontend/official-climb-profile-logic.test.ts | 102 |
1 files changed, 0 insertions, 102 deletions
diff --git a/web/frontend/official-climb-profile-logic.test.ts b/web/frontend/official-climb-profile-logic.test.ts deleted file mode 100644 index ca8dea2..0000000 --- a/web/frontend/official-climb-profile-logic.test.ts +++ /dev/null @@ -1,102 +0,0 @@ -import test from "node:test"; -import assert from "node:assert/strict"; -import { officialProfileSections, profileBandForSlope } from "./official-climb-profile-logic.ts"; -import type { ProfilePoint } from "./types.js"; - -test("assigns each slope to its color band", () => { - assert.equal(profileBandForSlope(-0.1), "downhill"); - assert.equal(profileBandForSlope(0), "downhill"); - assert.equal(profileBandForSlope(0.1), "0-3"); - assert.equal(profileBandForSlope(2.9), "0-3"); - assert.equal(profileBandForSlope(3), "3-6"); - assert.equal(profileBandForSlope(6), "6-9"); - assert.equal(profileBandForSlope(9), "9-plus"); - assert.equal(profileBandForSlope(12), "9-plus"); -}); - -// buildProfile lays out one recorded point every 50 m along the given [length in km, slope in %] stretches. -const buildProfile = (stretches: [number, number][]): ProfilePoint[] => { - const points: ProfilePoint[] = [{ distanceKm: 0, elevationM: 0 }]; - let distanceKm = 0; - let elevationM = 0; - for (const [lengthKm, slopePercent] of stretches) { - const pointCount = Math.round(lengthKm * 20); - for (let index = 1; index <= pointCount; index++) { - const distanceStepKm = (lengthKm * index) / pointCount; - points.push({ distanceKm: distanceKm + distanceStepKm, elevationM: elevationM + distanceStepKm * 1000 * (slopePercent / 100) }); - } - distanceKm += lengthKm; - elevationM += lengthKm * 1000 * (slopePercent / 100); - } - return points; -}; - -test("keeps a short steep ramp as its own section", () => { - const points = buildProfile([ - [0.3, 4], - [0.3, 12], - [0.3, 4], - ]); - const sections = officialProfileSections(points, 0, points.length - 1); - - assert.equal(sections.length, 3); - assert.ok(Math.abs(sections[1].slopePercent - 12) < 0.01); - assert.equal(sections[1].band, "9-plus"); - assert.equal(Math.round((sections[1].endDistanceKm - sections[1].startDistanceKm) * 1000), 300); - assert.ok(Math.abs(sections[0].slopePercent - 4) < 0.01); - assert.ok(Math.abs(sections[2].slopePercent - 4) < 0.01); -}); - -test("collapses a constant slope into a single section", () => { - const points = buildProfile([[5, 6]]); - const sections = officialProfileSections(points, 0, points.length - 1); - - assert.equal(sections.length, 1); - assert.ok(Math.abs(sections[0].slopePercent - 6) < 0.01); - assert.equal(sections[0].startDistanceKm, 0); - assert.equal(sections[0].endDistanceKm, 5); -}); - -test("reports a descending stretch as downhill", () => { - const points = buildProfile([[2, -5]]); - const sections = officialProfileSections(points, 0, points.length - 1); - - assert.equal(sections.length, 1); - assert.equal(sections[0].band, "downhill"); -}); - -test("keeps a noisy profile within the readable section budget", () => { - const points: ProfilePoint[] = []; - for (let index = 0; index <= 200; index++) { - const distanceKm = index * 0.05; - points.push({ distanceKm, elevationM: distanceKm * 1000 * 0.05 + Math.sin(index) * 4 }); - } - const sections = officialProfileSections(points, 0, points.length - 1); - - assert.ok(sections.length > 10 && sections.length <= 24, `expected 10-24 sections, got ${sections.length}`); - assert.equal(sections[0].startDistanceKm, 0); - assert.equal(sections[sections.length - 1].endDistanceKm, 10); -}); - -test("reads a slice of a longer profile", () => { - const points = buildProfile([ - [1, 20], - [1, 8], - [1, 20], - ]); - const startIndex = points.findIndex((point) => point.distanceKm >= 1); - const endIndex = points.findIndex((point) => point.distanceKm >= 2); - const sections = officialProfileSections(points, startIndex, endIndex); - - assert.equal(sections.length, 1); - assert.equal(Math.round(sections[0].slopePercent), 8); - assert.equal(sections[0].startDistanceKm, points[startIndex].distanceKm); - assert.equal(sections[0].endDistanceKm, points[endIndex].distanceKm); -}); - -test("returns no section for an empty range", () => { - const points = buildProfile([[1, 6]]); - - assert.deepEqual(officialProfileSections(points, 3, 3), []); - assert.deepEqual(officialProfileSections(points, 0, points.length), []); -}); |
