feat(cli): default to bubbles TUI, add find/play subcmds + JSON favorites
- implement internal/ui with bubbles list + ★ fav markers, filter, enter stub
- add data/favorites (JSON roundtrip, Add/Remove, XDG), config tests
- wire subcommands: `find -j`, `play [url|search]`
- gate legacy wmenu behind --legacy; keep old flags for seeding
- fix inverted -short guards, format string, go.mod deps
- add unit tests for radio prune, player IsInstalled, ui keys, etc.
2026-06-05 20:23:11 +00:00
|
|
|
package player
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"testing"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func TestIsInstalled(t *testing.T) {
|
|
|
|
|
// These should almost always exist in a reasonable env
|
|
|
|
|
if !IsInstalled("sh") && !IsInstalled("bash") && !IsInstalled("ls") {
|
|
|
|
|
t.Log("warning: no common shell util found; IsInstalled may be too strict in this env")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if IsInstalled("definitely-not-a-real-command-xyz123") {
|
|
|
|
|
t.Error("nonexistent command reported as installed")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestLegacyPlayer_BadCommand(t *testing.T) {
|
|
|
|
|
p := NewLegacy("definitely-not-a-real-command-xyz123")
|
|
|
|
|
err := p.Play("http://example.com")
|
|
|
|
|
if err != nil {
|
|
|
|
|
// Current legacy impl swallows and prints; we accept nil or err
|
|
|
|
|
t.Logf("play bad cmd returned err (ok): %v", err)
|
|
|
|
|
}
|
|
|
|
|
_ = p.Stop()
|
|
|
|
|
}
|
2026-06-05 22:13:01 +00:00
|
|
|
|
|
|
|
|
func TestMpvInterfaceAndControls(t *testing.T) {
|
|
|
|
|
p := NewMpv("echo") // won't really play, but exercises creation + interface
|
|
|
|
|
_ = p.Play("http://example.com/stream")
|
|
|
|
|
_ = p.Pause()
|
|
|
|
|
_ = p.Resume()
|
|
|
|
|
_ = p.Mute()
|
|
|
|
|
_ = p.Unmute()
|
|
|
|
|
_ = p.Next()
|
|
|
|
|
_ = p.Prev()
|
|
|
|
|
_ = p.VolumeUp()
|
|
|
|
|
_ = p.VolumeDown()
|
|
|
|
|
if p.Metadata() != "" {
|
|
|
|
|
t.Log("mpv metadata (may be empty for echo stub)")
|
|
|
|
|
}
|
|
|
|
|
_ = p.Stop()
|
|
|
|
|
// must satisfy Player fully
|
|
|
|
|
var _ Player = p
|
|
|
|
|
}
|