summaryrefslogtreecommitdiff
path: root/official_climb/official_climb_test.go
diff options
context:
space:
mode:
authorMartin Kagamino Lehoux <martin@lehoux.net>2026-08-18 11:24:34 +0200
committerMartin Kagamino Lehoux <martin@lehoux.net>2026-08-18 11:24:34 +0200
commit51613971c1e25dedbc808c66b79d15111d250160 (patch)
tree1465d108719c4bcc345b3b1496ff618504f537d3 /official_climb/official_climb_test.go
parent3ed9fa051bd92c924980a796e414a5b3481b1921 (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.go48
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)
}