-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathsupermemo2_plus_test.go
98 lines (80 loc) · 3.16 KB
/
supermemo2_plus_test.go
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 leaf
import (
"encoding/json"
"fmt"
"sort"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestSM2PlusNextReviewAt(t *testing.T) {
sm := &Supermemo2Plus{LastReviewedAt: time.Unix(100, 0), Interval: 1}
assert.Equal(t, int64(86500), sm.NextReviewAt().Unix())
sm = &Supermemo2Plus{LastReviewedAt: time.Unix(100, 0).Add(-24 * time.Hour), Interval: 1}
assert.Equal(t, int64(100), sm.NextReviewAt().Unix())
sm = NewSupermemo2Plus()
assert.InDelta(t, time.Since(sm.NextReviewAt()), time.Duration(0), float64(time.Minute))
interval := sm.Advance(1)
assert.InDelta(t, time.Duration(24*interval)*time.Hour, time.Until(sm.NextReviewAt()), float64(time.Minute))
}
func TestSM2PlusPercentOverdue(t *testing.T) {
sm := Supermemo2Plus{LastReviewedAt: time.Now().Add(-time.Hour), Interval: 1}
assert.InDelta(t, 0.04, sm.PercentOverdue(), 0.01)
sm = Supermemo2Plus{LastReviewedAt: time.Now().Add(-48 * time.Hour), Interval: 1}
assert.InDelta(t, 2.0, sm.PercentOverdue(), 0.01)
}
func TestSM2PlusLess(t *testing.T) {
sm1 := &Supermemo2Plus{LastReviewedAt: time.Now().Add(-time.Hour), Interval: 1}
sm2 := &Supermemo2Plus{LastReviewedAt: time.Now().Add(-48 * time.Hour), Interval: 1}
slice := []SRSAlgorithm{sm1, sm2}
sort.Slice(slice, func(i, j int) bool { return slice[j].Less(slice[i]) })
assert.Equal(t, []SRSAlgorithm{sm2, sm1}, slice)
}
func TestSM2PlusRecord(t *testing.T) {
results := [][]float64{
{0.04, 0.01, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.41, 0.82, 1.45, 2.17, 2.82, 3.67, 4.77, 6.21, 8.07},
{0.46, 1.23, 3.42, 9.84, 29.27, 87.83, 263.49, 790.49, 2371.48},
}
for idx, rating := range []float64{0.5, 0.6, 1.0} {
t.Run(fmt.Sprintf("%f", rating), func(t *testing.T) {
sm := NewSupermemo2Plus()
intervals := []float64{}
for i := 0; i < 9; i++ {
interval := sm.Advance(rating)
intervals = append(intervals, interval)
curInterval := sm.Interval * 24 * float64(time.Hour)
sm.LastReviewedAt = time.Now().Add(-time.Duration(curInterval))
}
assert.InDeltaSlice(t, results[idx], intervals, 0.01)
})
}
t.Run("sequence", func(t *testing.T) {
sm := NewSupermemo2Plus()
intervals := []float64{}
for _, rating := range []float64{1, 1, 1, 1, 0.5, 1} {
interval := sm.Advance(rating)
intervals = append(intervals, interval)
curInterval := sm.Interval * 24 * float64(time.Hour)
sm.LastReviewedAt = time.Now().Add(-time.Duration(curInterval))
}
assert.InDeltaSlice(t, []float64{0.46, 1.23, 3.42, 9.84, 1.54, 4.05}, intervals, 0.01)
historical := []float64{}
for _, snap := range sm.Historical {
assert.NotNil(t, snap.Timestamp)
historical = append(historical, snap.Interval)
}
assert.InDeltaSlice(t, []float64{0.2, 0.46, 1.23, 3.42, 9.84, 1.54}, historical, 0.01)
})
}
func TestSM2PlusJsonMarshalling(t *testing.T) {
sm := &Supermemo2Plus{LastReviewedAt: time.Unix(100, 0), Interval: 1, Difficulty: 0.2}
res, err := json.Marshal(sm)
require.NoError(t, err)
newSM := new(Supermemo2Plus)
require.NoError(t, json.Unmarshal(res, newSM))
assert.Equal(t, int64(100), newSM.LastReviewedAt.Unix())
assert.Equal(t, 1.0, newSM.Interval)
assert.Equal(t, 0.2, newSM.Difficulty)
}