diff options
| author | Martin Kagamino Lehoux <martin@lehoux.net> | 2026-08-18 11:24:34 +0200 |
|---|---|---|
| committer | Martin Kagamino Lehoux <martin@lehoux.net> | 2026-08-18 11:24:34 +0200 |
| commit | 51613971c1e25dedbc808c66b79d15111d250160 (patch) | |
| tree | 1465d108719c4bcc345b3b1496ff618504f537d3 /official_climb/official_climb_test.go | |
| parent | 3ed9fa051bd92c924980a796e414a5b3481b1921 (diff) | |
fix: match official climbs outside detected bounds
Diffstat (limited to 'official_climb/official_climb_test.go')
| -rw-r--r-- | official_climb/official_climb_test.go | 48 |
1 files changed, 37 insertions, 11 deletions
diff --git a/official_climb/official_climb_test.go b/official_climb/official_climb_test.go index 848216c..f8b0fe3 100644 --- a/official_climb/official_climb_test.go +++ b/official_climb/official_climb_test.go @@ -48,11 +48,11 @@ func TestCreateRejectsInvalidOfficialClimb(t *testing.T) { } func TestMatchClimbUsesOrderedCoordinates(t *testing.T) { - climb := testClimb( + parsed, climb := testClimb( geodist.Coord{Lat: 43.1002, Lon: 5.1002}, geodist.Coord{Lat: 43.2002, Lon: 5.2002}, ) - match, found := official_climb.MatchClimb(climb, []official_climb.OfficialClimb{ + match, found := official_climb.MatchClimb(parsed, climb, []official_climb.OfficialClimb{ {Name: "Same direction", StartCoord: geodist.Coord{Lat: 43.1, Lon: 5.1}, EndCoord: geodist.Coord{Lat: 43.2, Lon: 5.2}}, {Name: "Reverse direction", StartCoord: geodist.Coord{Lat: 43.2, Lon: 5.2}, EndCoord: geodist.Coord{Lat: 43.1, Lon: 5.1}}, }, official_climb.DefaultMatchPolicy()) @@ -62,11 +62,11 @@ func TestMatchClimbUsesOrderedCoordinates(t *testing.T) { } func TestMatchClimbRejectsEndpointOutsideRadius(t *testing.T) { - climb := testClimb( + parsed, climb := testClimb( geodist.Coord{Lat: 43.1, Lon: 5.1}, geodist.Coord{Lat: 43.3, Lon: 5.3}, ) - _, found := official_climb.MatchClimb(climb, []official_climb.OfficialClimb{{ + _, found := official_climb.MatchClimb(parsed, climb, []official_climb.OfficialClimb{{ Name: "Partial match", StartCoord: geodist.Coord{Lat: 43.1, Lon: 5.1}, EndCoord: geodist.Coord{Lat: 43.2, Lon: 5.2}, @@ -87,7 +87,7 @@ func TestMatchClimbFindsOfficialEndpointsInsideDetectedClimb(t *testing.T) { []time.Time{time.Unix(0, 0), time.Unix(60, 0), time.Unix(120, 0), time.Unix(180, 0)}, ) climb := parsed.ClimbFromIndexes(0, 3) - matched, found := official_climb.MatchClimb(climb, []official_climb.OfficialClimb{{ + matched, found := official_climb.MatchClimb(parsed, climb, []official_climb.OfficialClimb{{ Name: "Corrected boundaries", StartCoord: parsed.Coord(1), EndCoord: parsed.Coord(2), @@ -97,6 +97,32 @@ func TestMatchClimbFindsOfficialEndpointsInsideDetectedClimb(t *testing.T) { assert.Equal(t, "Corrected boundaries", matched.Name) } +func TestMatchClimbAllowsOfficialStartBeforeDetectedClimb(t *testing.T) { + parsed := ride.FromColumns( + []float64{0, 1000, 2000, 3000, 4000}, + []float64{100, 120, 300, 500, 100}, + []geodist.Coord{ + {Lat: 43.100, Lon: 5.100}, + {Lat: 43.101, Lon: 5.101}, + {Lat: 43.102, Lon: 5.102}, + {Lat: 43.103, Lon: 5.103}, + {Lat: 43.104, Lon: 5.104}, + }, + []time.Time{time.Unix(0, 0), time.Unix(60, 0), time.Unix(120, 0), time.Unix(180, 0), time.Unix(240, 0)}, + ) + detected := parsed.ClimbFromIndexes(1, 4) + official := official_climb.OfficialClimb{ + Name: "Wider canonical climb", + StartCoord: parsed.Coord(0), + EndCoord: parsed.Coord(3), + } + + matched, found := official_climb.MatchClimb(parsed, detected, []official_climb.OfficialClimb{official}, official_climb.DefaultMatchPolicy()) + + require.True(t, found) + assert.Equal(t, official.Name, matched.Name) +} + func TestMatchClimbMatchesSameOfficialClimbAcrossRides(t *testing.T) { official := official_climb.OfficialClimb{ Name: "Shared official climb", @@ -127,8 +153,8 @@ func TestMatchClimbMatchesSameOfficialClimbAcrossRides(t *testing.T) { []time.Time{time.Unix(0, 0), time.Unix(45, 0), time.Unix(90, 0), time.Unix(135, 0), time.Unix(180, 0)}, ) - firstMatch, firstFound := official_climb.MatchClimb(firstRide.ClimbFromIndexes(0, 3), []official_climb.OfficialClimb{official}, official_climb.DefaultMatchPolicy()) - secondMatch, secondFound := official_climb.MatchClimb(secondRide.ClimbFromIndexes(1, 4), []official_climb.OfficialClimb{official}, official_climb.DefaultMatchPolicy()) + firstMatch, firstFound := official_climb.MatchClimb(firstRide, firstRide.ClimbFromIndexes(0, 3), []official_climb.OfficialClimb{official}, official_climb.DefaultMatchPolicy()) + secondMatch, secondFound := official_climb.MatchClimb(secondRide, secondRide.ClimbFromIndexes(1, 4), []official_climb.OfficialClimb{official}, official_climb.DefaultMatchPolicy()) require.True(t, firstFound) require.True(t, secondFound) @@ -137,11 +163,11 @@ func TestMatchClimbMatchesSameOfficialClimbAcrossRides(t *testing.T) { } func TestMatchClimbChoosesNearestCandidate(t *testing.T) { - climb := testClimb( + parsed, climb := testClimb( geodist.Coord{Lat: 43.1, Lon: 5.1}, geodist.Coord{Lat: 43.2, Lon: 5.2}, ) - match, found := official_climb.MatchClimb(climb, []official_climb.OfficialClimb{ + match, found := official_climb.MatchClimb(parsed, climb, []official_climb.OfficialClimb{ {ID: 2, Name: "Farther", StartCoord: geodist.Coord{Lat: 43.1005, Lon: 5.1005}, EndCoord: geodist.Coord{Lat: 43.2005, Lon: 5.2005}}, {ID: 1, Name: "Nearest", StartCoord: geodist.Coord{Lat: 43.1001, Lon: 5.1001}, EndCoord: geodist.Coord{Lat: 43.2001, Lon: 5.2001}}, }, official_climb.DefaultMatchPolicy()) @@ -154,12 +180,12 @@ func TestMatchPolicyRejectsInvalidRadius(t *testing.T) { assert.EqualError(t, (official_climb.MatchPolicy{}).Validate(), "official climb endpoint radius must be greater than zero") } -func testClimb(start, end geodist.Coord) ride.Climb { +func testClimb(start, end geodist.Coord) (ride.Ride, ride.Climb) { parsed := ride.FromColumns( []float64{0, 1000, 2000}, []float64{100, 150, 200}, []geodist.Coord{{}, start, end}, []time.Time{time.Unix(0, 0), time.Unix(60, 0), time.Unix(120, 0)}, ) - return parsed.ClimbFromDist(1000, 2000) + return parsed, parsed.ClimbFromDist(1000, 2000) } |