changelog generator & diff tool
stormlightlabs.github.io/git-storm/
changelog
changeset
markdown
golang
git
1package ui
2
3import (
4 "testing"
5
6 tea "github.com/charmbracelet/bubbletea"
7 "github.com/stormlightlabs/git-storm/internal/changeset"
8)
9
10func TestEntryEditorModel_Init(t *testing.T) {
11 entry := changeset.EntryWithFile{
12 Entry: changeset.Entry{
13 Type: "added",
14 Scope: "cli",
15 Summary: "Test entry",
16 },
17 Filename: "test.md",
18 }
19
20 model := NewEntryEditorModel(entry)
21
22 cmd := model.Init()
23 if cmd == nil {
24 t.Error("Init() should return textinput.Blink command")
25 }
26}
27
28func TestEntryEditorModel_DefaultState(t *testing.T) {
29 entry := changeset.EntryWithFile{
30 Entry: changeset.Entry{
31 Type: "added",
32 Scope: "cli",
33 Summary: "Test entry",
34 },
35 Filename: "test.md",
36 }
37
38 model := NewEntryEditorModel(entry)
39
40 if model.confirmed {
41 t.Error("Model should not be confirmed initially")
42 }
43
44 if model.cancelled {
45 t.Error("Model should not be cancelled initially")
46 }
47
48 if model.focusIdx != 0 {
49 t.Errorf("Focus should be on first input, got %d", model.focusIdx)
50 }
51
52 if model.typeIdx != 0 {
53 t.Errorf("Type index should be 0 for 'added', got %d", model.typeIdx)
54 }
55}
56
57func TestEntryEditorModel_TypeCycling(t *testing.T) {
58 entry := changeset.EntryWithFile{
59 Entry: changeset.Entry{
60 Type: "added",
61 Scope: "cli",
62 Summary: "Test entry",
63 },
64 Filename: "test.md",
65 }
66
67 model := NewEntryEditorModel(entry)
68
69 initialType := model.typeIdx
70
71 updated, _ := model.Update(tea.KeyMsg{Type: tea.KeyCtrlT})
72 model = updated.(EntryEditorModel)
73
74 if model.typeIdx == initialType {
75 t.Error("Type should have cycled to next value")
76 }
77
78 expectedNext := (initialType + 1) % len(validTypes)
79 if model.typeIdx != expectedNext {
80 t.Errorf("Type index should be %d, got %d", expectedNext, model.typeIdx)
81 }
82}
83
84func TestEntryEditorModel_Confirm(t *testing.T) {
85 entry := changeset.EntryWithFile{
86 Entry: changeset.Entry{
87 Type: "added",
88 Scope: "cli",
89 Summary: "Test entry",
90 },
91 Filename: "test.md",
92 }
93
94 model := NewEntryEditorModel(entry)
95
96 updated, cmd := model.Update(tea.KeyMsg{Type: tea.KeyEnter})
97 model = updated.(EntryEditorModel)
98
99 if !model.confirmed {
100 t.Error("Model should be confirmed after pressing Enter")
101 }
102
103 if cmd == nil {
104 t.Error("Confirm should return tea.Quit command")
105 }
106}
107
108func TestEntryEditorModel_ConfirmWithCtrlS(t *testing.T) {
109 entry := changeset.EntryWithFile{
110 Entry: changeset.Entry{
111 Type: "added",
112 Scope: "cli",
113 Summary: "Test entry",
114 },
115 Filename: "test.md",
116 }
117
118 model := NewEntryEditorModel(entry)
119
120 updated, cmd := model.Update(tea.KeyMsg{Type: tea.KeyCtrlS})
121 model = updated.(EntryEditorModel)
122
123 if !model.confirmed {
124 t.Error("Model should be confirmed after pressing Ctrl+S")
125 }
126
127 if cmd == nil {
128 t.Error("Confirm should return tea.Quit command")
129 }
130}
131
132func TestEntryEditorModel_Cancel(t *testing.T) {
133 entry := changeset.EntryWithFile{
134 Entry: changeset.Entry{
135 Type: "added",
136 Scope: "cli",
137 Summary: "Test entry",
138 },
139 Filename: "test.md",
140 }
141
142 model := NewEntryEditorModel(entry)
143
144 updated, cmd := model.Update(tea.KeyMsg{Type: tea.KeyEsc})
145 model = updated.(EntryEditorModel)
146
147 if !model.cancelled {
148 t.Error("Model should be cancelled after pressing Esc")
149 }
150
151 if cmd == nil {
152 t.Error("Cancel should return tea.Quit command")
153 }
154}
155
156func TestEntryEditorModel_FieldNavigation(t *testing.T) {
157 entry := changeset.EntryWithFile{
158 Entry: changeset.Entry{
159 Type: "added",
160 Scope: "cli",
161 Summary: "Test entry",
162 },
163 Filename: "test.md",
164 }
165
166 model := NewEntryEditorModel(entry)
167
168 if model.focusIdx != 0 {
169 t.Fatalf("Initial focus should be on field 0, got %d", model.focusIdx)
170 }
171
172 updated, _ := model.Update(tea.KeyMsg{Type: tea.KeyTab})
173 model = updated.(EntryEditorModel)
174
175 if model.focusIdx != 1 {
176 t.Errorf("Focus should move to field 1 after Tab, got %d", model.focusIdx)
177 }
178
179 updated, _ = model.Update(tea.KeyMsg{Type: tea.KeyShiftTab})
180 model = updated.(EntryEditorModel)
181
182 if model.focusIdx != 0 {
183 t.Errorf("Focus should move back to field 0 after Shift+Tab, got %d", model.focusIdx)
184 }
185}
186
187func TestEntryEditorModel_GetEditedEntry(t *testing.T) {
188 entry := changeset.EntryWithFile{
189 Entry: changeset.Entry{
190 Type: "added",
191 Scope: "cli",
192 Summary: "Test entry",
193 Breaking: false,
194 CommitHash: "abc123",
195 DiffHash: "def456",
196 },
197 Filename: "test.md",
198 }
199
200 model := NewEntryEditorModel(entry)
201
202 model.typeIdx = 1
203
204 editedEntry := model.GetEditedEntry()
205
206 if editedEntry.Type != validTypes[1] {
207 t.Errorf("Expected type %s, got %s", validTypes[1], editedEntry.Type)
208 }
209
210 if editedEntry.CommitHash != entry.Entry.CommitHash {
211 t.Error("CommitHash should be preserved")
212 }
213
214 if editedEntry.DiffHash != entry.Entry.DiffHash {
215 t.Error("DiffHash should be preserved")
216 }
217}
218
219func TestEntryEditorModel_IsConfirmed(t *testing.T) {
220 entry := changeset.EntryWithFile{
221 Entry: changeset.Entry{Type: "added", Summary: "Test"},
222 Filename: "test.md",
223 }
224
225 model := NewEntryEditorModel(entry)
226
227 if model.IsConfirmed() {
228 t.Error("Model should not be confirmed initially")
229 }
230
231 updated, _ := model.Update(tea.KeyMsg{Type: tea.KeyEnter})
232 model = updated.(EntryEditorModel)
233
234 if !model.IsConfirmed() {
235 t.Error("Model should be confirmed after Enter key")
236 }
237}
238
239func TestEntryEditorModel_IsCancelled(t *testing.T) {
240 entry := changeset.EntryWithFile{
241 Entry: changeset.Entry{Type: "added", Summary: "Test"},
242 Filename: "test.md",
243 }
244
245 model := NewEntryEditorModel(entry)
246
247 if model.IsCancelled() {
248 t.Error("Model should not be cancelled initially")
249 }
250
251 updated, _ := model.Update(tea.KeyMsg{Type: tea.KeyEsc})
252 model = updated.(EntryEditorModel)
253
254 if !model.IsCancelled() {
255 t.Error("Model should be cancelled after Esc key")
256 }
257}
258
259func TestEntryEditorModel_WindowSize(t *testing.T) {
260 entry := changeset.EntryWithFile{
261 Entry: changeset.Entry{Type: "added", Summary: "Test"},
262 Filename: "test.md",
263 }
264
265 model := NewEntryEditorModel(entry)
266
267 if model.width != 0 || model.height != 0 {
268 t.Error("Initial window size should be 0")
269 }
270
271 updated, _ := model.Update(tea.WindowSizeMsg{Width: 100, Height: 30})
272 model = updated.(EntryEditorModel)
273
274 if model.width != 100 {
275 t.Errorf("Width should be 100, got %d", model.width)
276 }
277
278 if model.height != 30 {
279 t.Errorf("Height should be 30, got %d", model.height)
280 }
281}
282
283func TestEntryEditorModel_TypeIndexForDifferentTypes(t *testing.T) {
284 tests := []struct {
285 entryType string
286 expectedIndex int
287 }{
288 {"added", 0},
289 {"changed", 1},
290 {"fixed", 2},
291 {"removed", 3},
292 {"security", 4},
293 }
294
295 for _, tt := range tests {
296 t.Run(tt.entryType, func(t *testing.T) {
297 entry := changeset.EntryWithFile{
298 Entry: changeset.Entry{
299 Type: tt.entryType,
300 Summary: "Test entry",
301 },
302 Filename: "test.md",
303 }
304
305 model := NewEntryEditorModel(entry)
306
307 if model.typeIdx != tt.expectedIndex {
308 t.Errorf("Type index for %s should be %d, got %d", tt.entryType, tt.expectedIndex, model.typeIdx)
309 }
310 })
311 }
312}