Files
term-tier/internal/model/model_test.go
T

151 lines
3.7 KiB
Go
Raw Normal View History

package model_test
import (
"bytes"
"testing"
"github.com/StevanFreeborn/term-tier/internal/core"
"github.com/StevanFreeborn/term-tier/internal/handlers"
"github.com/StevanFreeborn/term-tier/internal/model"
"github.com/StevanFreeborn/term-tier/internal/state"
"github.com/charmbracelet/bubbles/textinput"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/x/exp/teatest"
)
func TestModel_Update_DelegatesKeyMsg(t *testing.T) {
s := state.New(state.WithMode(state.NavigationMode))
mockHandler := &MockKeyHandler{shouldMatch: true}
m := model.New(s, model.WithKeyMsgHandlers([]handlers.KeyMsgHandler{mockHandler}))
tm := teatest.NewTestModel(t, m, teatest.WithInitialTermSize(300, 100))
tm.Send(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune("q")})
tm.WaitFinished(t)
if !mockHandler.called {
t.Error("Expected KeyMsgHandler to be called, but it was not")
}
}
func TestModel_Update_DelegatesWinSizeMsg(t *testing.T) {
s := state.New(state.WithWindowWidth(100))
mockHandler := &MockWinHandler{shouldMatch: true}
m := model.New(s, model.WithWinSizeMsgHandlers([]handlers.WinSizeMsgHandler{mockHandler}))
tm := teatest.NewTestModel(t, m, teatest.WithInitialTermSize(80, 24))
tm.Send(tea.WindowSizeMsg{Width: 120, Height: 80})
tm.WaitFinished(t)
if !mockHandler.called {
t.Error("Expected WinSizeMsgHandler to be called")
}
if s.WindowWidth() != 120 {
t.Errorf("Expected state to update WindowWidth to 120, got %d", s.WindowWidth())
}
}
func TestModel_View_NavMode(t *testing.T) {
s := state.New(
state.WithMode(state.NavigationMode),
state.WithTiers([]core.Tier{
{Name: "S Tier", Color: lipgloss.Color("#FFFFFF"), Items: []core.Item{"Go", "Rust"}},
}),
state.WithCursor(0, 0),
state.WithWindowWidth(100),
state.WithMode(state.NavigationMode),
)
m := model.New(s)
output := m.View()
if !bytes.Contains([]byte(output), []byte("S Tier")) {
t.Error("View output missing tier label 'S Tier'")
}
if !bytes.Contains([]byte(output), []byte("Go")) {
t.Error("View output missing item 'Go'")
}
if bytes.Contains([]byte(output), []byte("Enter to Confirm")) {
t.Error("View output contains Input Mode text while in Nav Mode")
}
}
func TestModel_View_InputMode(t *testing.T) {
ti := textinput.New()
ti.SetValue("Test Value")
s := state.New(
state.WithMode(state.InputMode),
state.WithInput(ti, "Create New Item"),
)
m := model.New(s)
output := m.View()
if !bytes.Contains([]byte(output), []byte("Create New Item")) {
t.Error("View output missing Input Title")
}
if !bytes.Contains([]byte(output), []byte("Test Value")) {
t.Error("View output missing input value")
}
if !bytes.Contains([]byte(output), []byte("Esc to Cancel")) {
t.Error("View output missing input help text")
}
}
func TestModel_Init(t *testing.T) {
s := state.New()
m := model.New(s)
cmd := m.Init()
if cmd == nil {
t.Error("Init should return a command (blink), got nil")
}
}
type MockKeyHandler struct {
called bool
shouldMatch bool
}
func (m *MockKeyHandler) KeysHandled() []string {
return []string{"q"}
}
func (m *MockKeyHandler) Description() string {
return "Mock Quit Handler"
}
func (m *MockKeyHandler) Match(s state.State, msg tea.KeyMsg) bool {
return m.shouldMatch
}
func (m *MockKeyHandler) Handle(s state.State, msg tea.KeyMsg) tea.Cmd {
m.called = true
return tea.Quit
}
type MockWinHandler struct {
called bool
shouldMatch bool
targetWidth int
}
func (m *MockWinHandler) Match(s state.State, msg tea.WindowSizeMsg) bool {
return m.shouldMatch
}
func (m *MockWinHandler) Handle(s state.State, msg tea.WindowSizeMsg) tea.Cmd {
m.called = true
s.SetWindowSize(msg.Width, msg.Height)
return tea.Quit
}