gostations/internal/ui/ui_test.go
Greg Gauthier 3924aae93b
Some checks failed
gobuild / build (push) Failing after 3s
feat(ui): custom substring/AND filter for station list
Replace default fuzzy filter with substring matching where multi-word
queries require all words to appear. Fix auto-filter typing to properly
batch returned commands instead of discarding them. Update tests to
drive command loops and verify exact substring matches.
2026-06-05 21:46:04 +01:00

93 lines
2.4 KiB
Go

package ui
import (
"testing"
tea "github.com/charmbracelet/bubbletea"
"github.com/gmgauthier/gostations/internal/radio"
)
func TestApp_BasicKeyHandling(t *testing.T) {
app := NewApp([]radio.Station{
{Name: "Test1", Url: "http://a", Codec: "MP3", Bitrate: "128"},
})
// Send q
model, cmd := app.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'q'}})
if !model.(*App).quitting {
t.Error("q did not set quitting")
}
_ = cmd
// Send window size
model, _ = app.Update(tea.WindowSizeMsg{Width: 80, Height: 24})
a := model.(*App)
if a.list.Width() == 0 {
t.Log("list size not updated (may be ok in test)")
}
}
func TestApp_AutoFilterOnTyping(t *testing.T) {
app := NewApp([]radio.Station{
{Name: "WFMT 98.7", Url: "http://wfmt", Codec: "MP3", Bitrate: "128", Tags: "chicago,classical"},
{Name: "Other Station", Url: "http://other", Codec: "AAC", Bitrate: "64", Tags: "news"},
})
// Simulate typing 'W' (auto enter filter). Drive any returned cmds.
model, cmd := app.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'W'}})
a := model.(*App)
for cmd != nil {
msg := cmd()
if msg == nil {
break
}
model, cmd = a.Update(msg.(tea.Msg))
a = model.(*App)
}
fv := a.list.FilterValue()
if fv != "W" {
t.Errorf("expected filter value 'W' after typing W, got %q", fv)
}
visible := a.list.VisibleItems()
if len(visible) == 0 {
t.Error("expected some visible items after filter 'W'")
}
// Now type the rest of "WFMT", driving cmds each time
for _, r := range "FMT" {
model, cmd = a.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{r}})
a = model.(*App)
for cmd != nil {
msg := cmd()
if msg == nil {
break
}
model, cmd = a.Update(msg.(tea.Msg))
a = model.(*App)
}
}
fv = a.list.FilterValue()
if fv != "WFMT" {
t.Errorf("expected filter value 'WFMT', got %q", fv)
}
// Note: in live typing simulation, state may stay 'filtering' and filteredItems update may depend on internal cmd processing.
// For verifying the custom substring filter logic itself, use SetFilterText which synchronously applies.
a.list.SetFilterText("WFMT")
visible = a.list.VisibleItems()
if len(visible) != 1 {
t.Errorf("expected exactly 1 item for 'WFMT' substring filter, got %d", len(visible))
}
if len(visible) > 0 {
if it, ok := visible[0].(item); ok {
if it.station.Name != "WFMT 98.7" {
t.Errorf("expected 'WFMT 98.7' to be the match, got %q", it.station.Name)
}
}
}
}