Some checks failed
gobuild / build (push) Failing after 3s
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.
93 lines
2.4 KiB
Go
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)
|
|
}
|
|
}
|
|
}
|
|
}
|