changelog generator & diff tool stormlightlabs.github.io/git-storm/
changelog changeset markdown golang git
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 312 lines 7.0 kB view raw
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}