-
Notifications
You must be signed in to change notification settings - Fork 10
/
fsrs_store_test.go
123 lines (108 loc) · 3.41 KB
/
fsrs_store_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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// Riff - Spaced repetition.
// Copyright (c) 2022-present, b3log.org
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package riff
import (
"os"
"strings"
"testing"
"time"
"github.com/88250/gulu"
"github.com/open-spaced-repetition/go-fsrs/v3"
)
const (
requestRetention = 0.9
maximumInterval = 36500
weights = "0.40, 0.60, 2.40, 5.80, 4.93, 0.94, 0.86, 0.01, 1.49, 0.14, 0.94, 2.18, 0.05, 0.34, 1.26, 0.29, 2.61"
)
func TestFSRSStore(t *testing.T) {
const storePath = "testdata"
os.MkdirAll(storePath, 0755)
defer os.RemoveAll(storePath)
store := NewFSRSStore("test-store", storePath, requestRetention, maximumInterval, weights)
p := fsrs.DefaultParam()
scheduler := *fsrs.NewFSRS(p)
start := time.Now()
repeatTime := start
ids := map[string]bool{}
var firstCardID, firstBlockID, lastCardID, lastBlockID string
max := 10000
for i := 0; i < max; i++ {
id, blockID := newID(), newID()
if 0 == i {
firstCardID = id
firstBlockID = blockID
} else if max-1 == i {
lastCardID = id
lastBlockID = blockID
}
store.AddCard(id, blockID)
card := store.GetCard(id)
c := *card.Impl().(*fsrs.Card)
ids[id] = true
for j := 0; j < 10; j++ {
schedulingInfo := scheduler.Repeat(c, repeatTime)
c = schedulingInfo[fsrs.Hard].Card
repeatTime = c.Due
}
repeatTime = start
}
cardsLen := len(store.cards)
t.Logf("cards len [%d]", cardsLen)
if len(ids) != len(store.cards) {
t.Fatalf("cards len [%d] != ids len [%d]", len(store.cards), len(ids))
}
count := store.CountCards()
if cardsLen != count {
t.Fatalf("cards len [%d] != count [%d]", cardsLen, count)
}
if err := store.Save(); nil != err {
t.Fatal(err)
}
t.Logf("saved cards [len=%d]", len(store.cards))
if err := store.Load(); nil != err {
t.Fatal(err)
}
t.Logf("loaded cards len [%d]", len(store.cards))
if cardsLen != len(store.cards) {
t.Fatal("cards len not equal")
}
cards := store.GetCardsByBlockID(firstBlockID)
if 1 != len(cards) {
t.Fatalf("cards by block id [len=%d]", len(cards))
}
if firstCardID != cards[0].ID() {
t.Fatalf("cards by block id [cardID=%s]", cards[0].ID())
}
cards = store.GetCardsByBlockID(lastBlockID)
if 1 != len(cards) {
t.Fatalf("cards by block id [len=%d]", len(cards))
}
if lastCardID != cards[0].ID() {
t.Fatalf("cards by block id [cardID=%s]", cards[0].ID())
}
cards = store.GetCardsByBlockIDs([]string{firstBlockID, lastBlockID})
if 2 != len(cards) {
t.Fatalf("cards by block ids [len=%d]", len(cards))
}
cardIDs := []string{cards[0].ID(), cards[1].ID()}
if !gulu.Str.Contains(firstCardID, cardIDs) {
t.Fatalf("cards by block ids [cardIDs=%v]", cardIDs)
}
if !gulu.Str.Contains(lastCardID, cardIDs) {
t.Fatalf("cards by block ids [cardIDs=%v]", cardIDs)
}
t.Logf("cards by block ids [len=%d], card ids [%s]", len(cards), strings.Join(cardIDs, ", "))
}