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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
package ride_test
import (
"fmt"
"strings"
"testing"
"time"
"github.com/martinlehoux/biking_home/ride"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func gpxWithPoints(t *testing.T, points string) ride.Ride {
t.Helper()
data := parserTestGPXPrefix + points + parserTestGPXSuffix
parsed, err := (ride.GPXRideParser{}).Parse(strings.NewReader(data))
require.NoError(t, err)
return parsed
}
func trackPoint(lat, lon string, timestamp string) string {
return `<trkpt lat="` + lat + `" lon="` + lon + `">` +
`<ele>100</ele>` +
`<time>` + timestamp + `</time>` +
`</trkpt>`
}
func metricTrackPoint(lat, lon, timestamp string, cadence, power int) string {
return `<trkpt lat="` + lat + `" lon="` + lon + `">` +
`<ele>100</ele>` +
`<time>` + timestamp + `</time>` +
`<extensions><gpxtpx:TrackPointExtension>` +
`<gpxtpx:cad>` + fmt.Sprint(cadence) + `</gpxtpx:cad>` +
`<gpxtpx:watts>` + fmt.Sprint(power) + `</gpxtpx:watts>` +
`</gpxtpx:TrackPointExtension></extensions>` +
`</trkpt>`
}
func TestMovingTimeCountsSteadyRiding(t *testing.T) {
parsed := gpxWithPoints(t,
trackPoint("43.0", "5.0", "2026-01-01T10:00:00Z")+
trackPoint("43.009", "5.0", "2026-01-01T10:01:00Z")+
trackPoint("43.018", "5.0", "2026-01-01T10:02:00Z"),
)
assert.Equal(t, 2*time.Minute, ride.MovingTime(parsed))
}
func TestMovingTimeExcludesSlowInterval(t *testing.T) {
parsed := gpxWithPoints(t,
trackPoint("43.0", "5.0", "2026-01-01T10:00:00Z")+
trackPoint("43.0005", "5.0", "2026-01-01T10:10:00Z")+
trackPoint("43.009", "5.0", "2026-01-01T10:12:00Z"),
)
assert.Equal(t, 2*time.Minute, ride.MovingTime(parsed))
}
func TestMovingTimeExcludesLunchBreak(t *testing.T) {
parsed := gpxWithPoints(t,
trackPoint("43.0", "5.0", "2026-01-01T10:00:00Z")+
trackPoint("43.0001", "5.0", "2026-01-01T10:30:00Z")+
trackPoint("43.009", "5.0", "2026-01-01T10:31:00Z"),
)
assert.Equal(t, time.Minute, ride.MovingTime(parsed))
}
func TestMovingTimeCountsEffortMetricsWhenGPSSpeedIsLow(t *testing.T) {
data := parserTestGPXMetricsPrefix +
metricTrackPoint("43.0", "5.0", "2026-01-01T10:00:00Z", 0, 0) +
metricTrackPoint("43.000001", "5.0", "2026-01-01T10:01:00Z", 80, 0) +
metricTrackPoint("43.000002", "5.0", "2026-01-01T10:02:00Z", 0, 50) +
metricTrackPoint("43.000003", "5.0", "2026-01-01T10:03:00Z", 0, 10) +
metricTrackPoint("43.000004", "5.0", "2026-01-01T10:04:00Z", 0, 0) +
parserTestGPXSuffix
parsed, err := (ride.GPXRideParser{}).Parse(strings.NewReader(data))
require.NoError(t, err)
assert.Equal(t, 2*time.Minute, ride.MovingTime(parsed))
}
func TestMovingTimeWithoutTimestamps(t *testing.T) {
data := parserTestGPXPrefix +
`<trkpt lat="43.0" lon="5.0"><ele>100</ele></trkpt>` +
`<trkpt lat="43.009" lon="5.0"><ele>100</ele></trkpt>` +
parserTestGPXSuffix
parsed, err := (ride.GPXRideParser{}).Parse(strings.NewReader(data))
require.NoError(t, err)
assert.Equal(t, time.Duration(0), ride.MovingTime(parsed))
}
func TestMovingTimeAlgorithmVersion(t *testing.T) {
assert.Equal(t, "v2", ride.MovingTimeAlgorithmVersion)
}
|