Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
kardolus
GitHub Repository: kardolus/chatgpt-cli
Path: blob/main/history/manager_test.go
2649 views
1
package history_test
2
3
import (
4
"errors"
5
"github.com/golang/mock/gomock"
6
"github.com/kardolus/chatgpt-cli/api"
7
"github.com/kardolus/chatgpt-cli/history"
8
. "github.com/onsi/gomega"
9
"github.com/sclevine/spec"
10
"github.com/sclevine/spec/report"
11
"os"
12
"testing"
13
)
14
15
//go:generate mockgen -destination=historymocks_test.go -package=history_test github.com/kardolus/chatgpt-cli/history Store
16
17
var (
18
mockCtrl *gomock.Controller
19
mockHistoryStore *MockStore
20
subject *history.Manager
21
)
22
23
func TestUnitHistory(t *testing.T) {
24
spec.Run(t, "Testing the History", testHistory, spec.Report(report.Terminal{}))
25
}
26
27
func testHistory(t *testing.T, when spec.G, it spec.S) {
28
it.Before(func() {
29
RegisterTestingT(t)
30
mockCtrl = gomock.NewController(t)
31
mockHistoryStore = NewMockStore(mockCtrl)
32
subject = history.NewHistory(mockHistoryStore)
33
})
34
35
it.After(func() {
36
mockCtrl.Finish()
37
})
38
39
when("ParseUserHistory()", func() {
40
const threadName = "threadName"
41
42
it("returns an error when store fails", func() {
43
mockHistoryStore.EXPECT().
44
ReadThread(threadName).
45
Return(nil, errors.New("store error")).
46
Times(1)
47
48
_, err := subject.ParseUserHistory(threadName)
49
Expect(err).To(MatchError("store error"))
50
})
51
52
it("returns only user messages", func() {
53
historyEntries := []history.History{
54
{Message: api.Message{Role: "user", Content: "hello"}},
55
{Message: api.Message{Role: "assistant", Content: "hi"}},
56
{Message: api.Message{Role: "user", Content: "how are you?"}},
57
{Message: api.Message{Role: "system", Content: "ignore this"}},
58
}
59
60
mockHistoryStore.EXPECT().
61
ReadThread(threadName).
62
Return(historyEntries, nil).
63
Times(1)
64
65
result, err := subject.ParseUserHistory(threadName)
66
Expect(err).NotTo(HaveOccurred())
67
Expect(result).To(Equal([]string{"hello", "how are you?"}))
68
})
69
70
it("returns an empty list when there are no user messages", func() {
71
historyEntries := []history.History{
72
{Message: api.Message{Role: "assistant", Content: "hi"}},
73
{Message: api.Message{Role: "system", Content: "setup"}},
74
}
75
76
mockHistoryStore.EXPECT().
77
ReadThread(threadName).
78
Return(historyEntries, nil).
79
Times(1)
80
81
result, err := subject.ParseUserHistory(threadName)
82
Expect(err).NotTo(HaveOccurred())
83
Expect(result).To(BeEmpty())
84
})
85
86
it("returns an empty list when the thread does not exist", func() {
87
// Simulate store returning a file-not-found error
88
mockHistoryStore.EXPECT().
89
ReadThread(threadName).
90
Return(nil, os.ErrNotExist).
91
Times(1)
92
93
result, err := subject.ParseUserHistory(threadName)
94
Expect(err).NotTo(HaveOccurred())
95
Expect(result).To(BeEmpty())
96
})
97
})
98
99
when("Print()", func() {
100
const threadName = "threadName"
101
102
it("throws an error when there is a problem talking to the store", func() {
103
mockHistoryStore.EXPECT().ReadThread(threadName).Return(nil, errors.New("nope")).Times(1)
104
105
_, err := subject.Print(threadName)
106
Expect(err).To(HaveOccurred())
107
})
108
109
it("concatenates multiple user messages", func() {
110
historyEntries := []history.History{
111
{
112
Message: api.Message{Role: "user", Content: "first message"},
113
},
114
{
115
Message: api.Message{Role: "user", Content: " second message"},
116
},
117
{
118
Message: api.Message{Role: "assistant", Content: "response"},
119
},
120
}
121
122
mockHistoryStore.EXPECT().ReadThread(threadName).Return(historyEntries, nil).Times(1)
123
124
result, err := subject.Print(threadName)
125
Expect(err).NotTo(HaveOccurred())
126
Expect(result).To(ContainSubstring("**USER** 👤:\nfirst message second message\n"))
127
Expect(result).To(ContainSubstring("**ASSISTANT** 🤖:\nresponse\n"))
128
})
129
130
it("prints all roles correctly", func() {
131
historyEntries := []history.History{
132
{
133
Message: api.Message{Role: "system", Content: "system message"},
134
},
135
{
136
Message: api.Message{Role: "function", Content: "function message"},
137
},
138
{
139
Message: api.Message{Role: "user", Content: "user message"},
140
},
141
{
142
Message: api.Message{Role: "assistant", Content: "assistant message"},
143
},
144
}
145
146
mockHistoryStore.EXPECT().ReadThread(threadName).Return(historyEntries, nil).Times(1)
147
148
result, err := subject.Print(threadName)
149
Expect(err).NotTo(HaveOccurred())
150
Expect(result).To(ContainSubstring("**SYSTEM** 💻:\nsystem message\n"))
151
Expect(result).To(ContainSubstring("\n---\n**FUNCTION** 🔌:\nfunction message\n"))
152
Expect(result).To(ContainSubstring("\n---\n**USER** 👤:\nuser message\n"))
153
Expect(result).To(ContainSubstring("**ASSISTANT** 🤖:\nassistant message\n"))
154
})
155
156
it("handles the final user message concatenation", func() {
157
historyEntries := []history.History{
158
{
159
Message: api.Message{Role: "user", Content: "first message"},
160
},
161
{
162
Message: api.Message{Role: "user", Content: " second message"},
163
},
164
}
165
166
mockHistoryStore.EXPECT().ReadThread(threadName).Return(historyEntries, nil).Times(1)
167
168
result, err := subject.Print(threadName)
169
Expect(err).NotTo(HaveOccurred())
170
Expect(result).To(ContainSubstring("**USER** 👤:\nfirst message second message\n"))
171
})
172
})
173
}
174
175