aboutsummaryrefslogtreecommitdiffstats
path: root/tui/tui_test.go
diff options
context:
space:
mode:
authorAdam Mathes <adam@adammathes.com>2026-02-12 20:57:12 -0800
committerAdam Mathes <adam@adammathes.com>2026-02-12 20:57:12 -0800
commitcfd583e9166330f053fa7cc28258b4467c48459c (patch)
treebdea6e91c25e04b6e483a58040d386876593a457 /tui/tui_test.go
parentfa037e748bb2ba65f75ba104e18d460a8fbcd49b (diff)
downloadneko-cfd583e9166330f053fa7cc28258b4467c48459c.tar.gz
neko-cfd583e9166330f053fa7cc28258b4467c48459c.tar.bz2
neko-cfd583e9166330f053fa7cc28258b4467c48459c.zip
Fix nil-pointer panics in TUI and add unit tests
- Initialized list models in NewModel to prevent panic on WindowSizeMsg - Added nil check for selectedFeed in itemsMsg handler - Created tui/tui_test.go with unit tests for state transitions and resizing - Verified all tests pass
Diffstat (limited to 'tui/tui_test.go')
-rw-r--r--tui/tui_test.go58
1 files changed, 58 insertions, 0 deletions
diff --git a/tui/tui_test.go b/tui/tui_test.go
new file mode 100644
index 0000000..6ae8d73
--- /dev/null
+++ b/tui/tui_test.go
@@ -0,0 +1,58 @@
+package tui
+
+import (
+ "testing"
+
+ "adammathes.com/neko/models/feed"
+ "adammathes.com/neko/models/item"
+ tea "github.com/charmbracelet/bubbletea"
+)
+
+func TestNewModel(t *testing.T) {
+ m := NewModel()
+ if m.state != viewFeeds {
+ t.Errorf("Expected initial state viewFeeds, got %v", m.state)
+ }
+}
+
+func TestUpdateWindowSizeNoPanic(t *testing.T) {
+ m := NewModel()
+ // This should not panic even if lists are empty
+ msg := tea.WindowSizeMsg{Width: 80, Height: 24}
+ newModel, _ := m.Update(msg)
+ tm := newModel.(Model)
+ if tm.width != 80 || tm.height != 24 {
+ t.Errorf("Expected size 80x24, got %dx%d", tm.width, tm.height)
+ }
+}
+
+func TestStateTransitions(t *testing.T) {
+ m := NewModel()
+
+ // Feed loaded
+ feeds := []*feed.Feed{{Id: 1, Title: "Test Feed"}}
+ m2, _ := m.Update(feedsMsg(feeds))
+ tm2 := m2.(Model)
+ if len(tm2.feeds) != 1 {
+ t.Fatal("Expected 1 feed")
+ }
+
+ // Items loaded
+ items := []*item.Item{{Id: 1, Title: "Test Item", Description: "Desc"}}
+ tm2.selectedFeed = feeds[0] // Simulate selection
+ m3, _ := tm2.Update(itemsMsg(items))
+ tm3 := m3.(Model)
+ if tm3.state != viewItems {
+ t.Errorf("Expected state viewItems, got %v", tm3.state)
+ }
+ if len(tm3.items) != 1 {
+ t.Fatal("Expected 1 item")
+ }
+
+ // Back to feeds
+ m4, _ := tm3.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune("q")})
+ tm4 := m4.(Model)
+ if tm4.state != viewFeeds {
+ t.Errorf("Expected back to viewFeeds, got %v", tm4.state)
+ }
+}