99 lines
2.9 KiB
Go
99 lines
2.9 KiB
Go
package model
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
|
|
"charm.land/lipgloss/v2"
|
|
|
|
"github.com/bjarneo/cliamp/playlist"
|
|
"github.com/bjarneo/cliamp/ui"
|
|
)
|
|
|
|
// newInlineOverlayModel builds a Model with a real player/playlist/visualizer
|
|
// for exercising the inline overlay render path.
|
|
func newInlineOverlayModel(t *testing.T, w, h int) Model {
|
|
t.Helper()
|
|
sharedPlayer.Stop()
|
|
|
|
pl := playlist.New()
|
|
for i := range 8 {
|
|
pl.Add(playlist.Track{
|
|
Path: fmt.Sprintf("/tmp/track-%d.mp3", i),
|
|
Title: fmt.Sprintf("Track %d", i+1),
|
|
})
|
|
}
|
|
|
|
m := Model{
|
|
player: sharedPlayer,
|
|
playlist: pl,
|
|
vis: ui.NewVisualizer(float64(sharedPlayer.SampleRate())),
|
|
width: w,
|
|
height: h,
|
|
focus: focusPlaylist,
|
|
plVisible: 6,
|
|
}
|
|
m.vis.Mode = ui.VisNone
|
|
m.refreshChrome()
|
|
m.applyHeightMode()
|
|
return m
|
|
}
|
|
|
|
// TestInlineOverlaysFitTerminal opens each overlay inline and asserts the framed
|
|
// view never overflows the terminal height or width. Overlays render in the
|
|
// playlist region beneath the live now-playing/visualizer/controls chrome, so
|
|
// the total frame must still fit.
|
|
func TestInlineOverlaysFitTerminal(t *testing.T) {
|
|
if sharedPlayer == nil {
|
|
t.Skip("audio hardware unavailable")
|
|
}
|
|
|
|
sizes := []struct{ w, h int }{
|
|
{80, 24},
|
|
{80, 20},
|
|
{100, 30},
|
|
}
|
|
|
|
overlays := []struct {
|
|
name string
|
|
set func(m *Model)
|
|
}{
|
|
{"themePicker", func(m *Model) { m.themePicker.visible = true }},
|
|
{"devicePicker", func(m *Model) { m.devicePicker.visible = true }},
|
|
{"queue", func(m *Model) { m.queue.visible = true }},
|
|
{"info", func(m *Model) { m.showInfo = true }},
|
|
{"search", func(m *Model) { m.search.active = true }},
|
|
{"keymap", func(m *Model) { m.keymap.visible = true; m.keymap.entries = m.buildKeymapEntries() }},
|
|
{"netSearch", func(m *Model) { m.netSearch.active = true }},
|
|
{"urlInput", func(m *Model) { m.urlInputting = true }},
|
|
{"lyrics", func(m *Model) { m.lyrics.visible = true }},
|
|
{"jump", func(m *Model) { m.jumping = true }},
|
|
{"spotSearch", func(m *Model) { m.spotSearch.visible = true }},
|
|
{"navBrowser", func(m *Model) { m.navBrowser.visible = true; m.navBrowser.mode = navBrowseModeMenu }},
|
|
{"playlistManager", func(m *Model) { m.plManager.visible = true; m.plManager.screen = plMgrScreenList }},
|
|
{"fileBrowser", func(m *Model) { m.fileBrowser.visible = true }},
|
|
{"visPicker", func(m *Model) { m.openVisPicker() }},
|
|
}
|
|
|
|
for _, sz := range sizes {
|
|
for _, ov := range overlays {
|
|
t.Run(fmt.Sprintf("%s_%dx%d", ov.name, sz.w, sz.h), func(t *testing.T) {
|
|
withFrameWidth(t, sz.w)
|
|
m := newInlineOverlayModel(t, sz.w, sz.h)
|
|
ov.set(&m)
|
|
|
|
out := m.View().Content
|
|
if got := lipgloss.Height(out); got > sz.h {
|
|
t.Fatalf("%s view height = %d, want <= %d", ov.name, got, sz.h)
|
|
}
|
|
for _, line := range strings.Split(out, "\n") {
|
|
if got := lipgloss.Width(line); got > sz.w {
|
|
t.Fatalf("%s view line width = %d, want <= %d: %q", ov.name, got, sz.w, line)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|