1// SPDX-License-Identifier: AGPL-3.0-or-later
2
3package web
4
5import (
6 "strconv"
7 "strings"
8 "testing"
9
10 "github.com/stretchr/testify/assert"
11 "github.com/stretchr/testify/require"
12)
13
14func TestHeartbeat(t *testing.T) {
15 t.Parallel()
16 assert.Nil(t, heartbeatOf("x", nil, false), "no data, no curve")
17
18 days := make([]int, 90)
19 days[10], days[60], days[88] = 30, 4, 2
20 h := heartbeatOf("proj", days, false)
21 require.NotNil(t, h)
22 assert.True(t, strings.HasPrefix(h.Line, "M0 "), h.Line)
23 assert.Equal(t, 45, strings.Count(h.Line, " C"), "a point every two days, and today")
24 assert.Less(t, len(h.Line)+len(h.Area), 4000, "light enough for every live update")
25 assert.True(t, strings.HasPrefix(h.Area, h.Line) && strings.HasSuffix(h.Area, " Z"))
26 assert.Equal(t, "hb-proj", h.GradID)
27 assert.Equal(t, "Activity: 36 commits in the last 90 days", h.Label)
28 assert.True(t, h.Live, "commits in the last week")
29 assert.Equal(t, num(heartbeatEndX), h.X)
30
31 // Every point stays inside the box: no overshoot below the base line or
32 // above the top.
33 for _, f := range strings.FieldsFunc(h.Line, func(r rune) bool { return r == 'M' || r == 'C' || r == ' ' }) {
34 v, err := strconv.ParseFloat(f, 64)
35 require.NoError(t, err, f)
36 assert.GreaterOrEqual(t, v, 0.0)
37 assert.LessOrEqual(t, v, heartbeatW)
38 }
39
40 quiet := heartbeatOf("q", make([]int, 90), false)
41 require.NotNil(t, quiet)
42 assert.False(t, quiet.Live)
43 assert.Equal(t, num(heartbeatH-heartbeatPad), quiet.Y, "a flat line on the base")
44 assert.Equal(t, 1, strings.Count(quiet.Line, " C"), "two points")
45 assert.Equal(t, "Activity: 0 commits in the last 90 days", quiet.Label)
46
47 assert.Equal(t, "Activity: at least 36 commits in the last 90 days", heartbeatOf("proj", days, true).Label)
48}
49
50func TestPulseCache(t *testing.T) {
51 t.Parallel()
52 var c pulseCache
53 days := make([]int, 90)
54 days[80] = 3
55 a := c.get("proj", days, false)
56 require.NotNil(t, a)
57 assert.Same(t, a, c.get("proj", days, false), "same figures, same curve")
58 assert.Equal(t, heartbeatOf("proj", days, false), a)
59
60 assert.NotSame(t, a, c.get("other", days, false), "per repository: the gradient id differs")
61 assert.NotSame(t, a, c.get("proj", days, true), "partial changes the label")
62 days[89] = 1
63 b := c.get("proj", days, false)
64 assert.NotSame(t, a, b, "new figures, new curve")
65 assert.True(t, b.Live)
66 assert.Nil(t, c.get("proj", nil, false))
67}
68
69func BenchmarkPulseCache(b *testing.B) {
70 var c pulseCache
71 days := make([]int, 90)
72 for i := range days {
73 days[i] = i * 7 % 11
74 }
75 b.ReportAllocs()
76 for b.Loop() {
77 c.get("neferwl", days, false)
78 }
79}