aboutsummaryrefslogtreecommitdiff
path: root/rideanalysis/profile_test.go
blob: 5fb0772b9fbad7324dd8199a99821f006fc9a554 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

package rideanalysis_test

import (
	"testing"

	"github.com/martinlehoux/biking_home/climb"
	"github.com/martinlehoux/biking_home/internal/ridetest"
	"github.com/martinlehoux/biking_home/official_climb"
	"github.com/martinlehoux/biking_home/ride"
	"github.com/martinlehoux/biking_home/rideanalysis"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

func TestMergeClimbProfileMediansRecordedPassages(t *testing.T) {
	parsed, officialClimb := attemptRideForClimb(t)
	officialClimb.ID = 42
	// Same trace 10 m higher: the merge must average the two passages, not pick one.
	shifted := ridetest.MustRide("1km at 14.7% | 1km at -6.7%", ridetest.StartCoord(43.61, 5.42), ridetest.StartElevation(310), ridetest.Sampling(1000), ridetest.StartTime(attemptRideStart))
	analysis := rideanalysis.Analyze(parsed, nil, []official_climb.OfficialClimb{officialClimb}, official_climb.DefaultMatchPolicy())
	aggregate := official_climb.AggregateAttempts(rideanalysis.Attempts(1, analysis, parsed))

	profile := rideanalysis.MergeClimbProfile(officialClimb, []ride.Ride{parsed, shifted}, aggregate, official_climb.DefaultMatchPolicy(), climb.DefaultProfilePolicy())

	assert.InDelta(t, 1000, profile.DistanceM, 0.01)
	require.NotEmpty(t, profile.Sections)
	assert.InDelta(t, 305, profile.Sections[0].StartElevationM, 1)
	lastSection := profile.Sections[len(profile.Sections)-1]
	assert.InDelta(t, 452, lastSection.EndElevationM, 2)
	assert.InDelta(t, 1000, lastSection.EndDistanceM, 0.01)
}

func TestMergeClimbProfileRouteKeepsRecordedPoints(t *testing.T) {
	parsed, officialClimb := attemptRideForClimb(t)
	officialClimb.ID = 42
	analysis := rideanalysis.Analyze(parsed, nil, []official_climb.OfficialClimb{officialClimb}, official_climb.DefaultMatchPolicy())
	aggregate := official_climb.AggregateAttempts(rideanalysis.Attempts(1, analysis, parsed))

	profile := rideanalysis.MergeClimbProfile(officialClimb, []ride.Ride{parsed}, aggregate, official_climb.DefaultMatchPolicy(), climb.DefaultProfilePolicy())

	// Full recorded precision: every matched segment point is present, not a fixed resample.
	require.Len(t, profile.Route, 2)
	assert.InDelta(t, parsed.Coords[0].Lon, profile.Route[0].Lon, 1e-9)
	assert.InDelta(t, parsed.Coords[0].Lat, profile.Route[0].Lat, 1e-9)
	assert.InDelta(t, parsed.Coords[1].Lon, profile.Route[1].Lon, 1e-9)
	assert.InDelta(t, parsed.Coords[1].Lat, profile.Route[1].Lat, 1e-9)
}

func TestMergeClimbProfileWithoutRides(t *testing.T) {
	_, officialClimb := attemptRideForClimb(t)

	profile := rideanalysis.MergeClimbProfile(officialClimb, nil, official_climb.Aggregate{DistanceM: 1000}, official_climb.DefaultMatchPolicy(), climb.DefaultProfilePolicy())

	assert.Empty(t, profile.Sections)
	assert.Nil(t, profile.Route)
}