aboutsummaryrefslogtreecommitdiff
path: root/climb/difficulty_test.go
blob: 92c0a743bb86bcca5a1fffac1716493ae5d9ee8d (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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

package climb_test

import (
	"math"
	"testing"

	"github.com/martinlehoux/biking_home/climb"
	"github.com/martinlehoux/biking_home/internal/routetest"
	"github.com/stretchr/testify/assert"
)

func TestCotacolConstantClimb(t *testing.T) {
	route := routetest.MustRoute("2km at 7%")
	assert.InDelta(t, 98.0, climb.Cotacol(route.Distances, route.Elevations), 1e-9)
}

func TestCotacolIgnoresDescent(t *testing.T) {
	route := routetest.MustRoute("2km at 7% | 2km at -7%")
	assert.InDelta(t, 98.0, climb.Cotacol(route.Distances, route.Elevations), 1e-9)
}

func TestCotacolFlatIsZero(t *testing.T) {
	route := routetest.MustRoute("5km at 0%")
	assert.Zero(t, climb.Cotacol(route.Distances, route.Elevations))
}

func TestCotacolSteepShortCountsMore(t *testing.T) {
	steep := routetest.MustRoute("0.5km at 14%")
	long := routetest.MustRoute("1km at 7%")
	assert.InDelta(t, 98.0, climb.Cotacol(steep.Distances, steep.Elevations), 1e-9)
	assert.InDelta(t, 49.0, climb.Cotacol(long.Distances, long.Elevations), 1e-9)
}

func TestCotacolPrecisionInvariant(t *testing.T) {
	coarse := routetest.MustRoute("3km at 5%")
	fine := routetest.MustRoute("3km at 5%", routetest.Sampling(50))
	assert.InDelta(t, climb.Cotacol(coarse.Distances, coarse.Elevations), climb.Cotacol(fine.Distances, fine.Elevations), 1e-9)
}

func TestCotacolClimbNotAtStart(t *testing.T) {
	route := routetest.MustRoute("1km at 0% | 2km at 7%")
	detected := climb.Detect(route, nil, climb.ClimbSlopeMinimum)
	assert.Len(t, detected, 1)
	assert.InDelta(t, 98.0, detected[0].Climb.DifficultyScore(), 1e-9)
}

func TestCategoryOfBoundaries(t *testing.T) {
	cases := []struct {
		score float64
		want  climb.Category
	}{
		{-5, climb.CategoryNo},
		{30, climb.CategoryNo},
		{35, climb.CategoryFour}, // 35 is the first floor, not below it
		{79, climb.CategoryFour},
		{80, climb.CategoryThree},
		{179, climb.CategoryThree},
		{180, climb.CategoryTwo},
		{249, climb.CategoryTwo},
		{250, climb.CategoryOne},
		{599, climb.CategoryOne},
		{600, climb.CategoryHC},
		{700, climb.CategoryHC},
		{math.NaN(), climb.CategoryHC}, // reaches no floor, like the original switch default
	}

	for _, c := range cases {
		assert.Equal(t, c.want, climb.CategoryOf(c.score), "score %v", c.score)
	}
	assert.Equal(t, "Cat 1", climb.CategoryOne.String())
	assert.Equal(t, "NO", climb.CategoryNo.String())
}