122 lines
4.1 KiB
Go
122 lines
4.1 KiB
Go
package tui
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"ai-agent/internal/config"
|
|
)
|
|
|
|
func TestModelPicker_OpenClose(t *testing.T) {
|
|
t.Run("open_without_model_list_noop", func(t *testing.T) {
|
|
m := newTestModel(t)
|
|
m.openModelPicker()
|
|
if m.overlay == OverlayModelPicker {
|
|
t.Error("should not open picker without model list")
|
|
}
|
|
})
|
|
t.Run("open_with_model_list", func(t *testing.T) {
|
|
m := newTestModel(t)
|
|
m.modelList = []string{"qwen3.5:0.8b", "qwen3.5:2b", "qwen3.5:4b", "qwen3.5:9b"}
|
|
m.model = "qwen3.5:0.8b"
|
|
m.openModelPicker()
|
|
if m.overlay != OverlayModelPicker {
|
|
t.Errorf("expected OverlayModelPicker, got %d", m.overlay)
|
|
}
|
|
if m.modelPickerState == nil {
|
|
t.Fatal("modelPickerState should not be nil")
|
|
}
|
|
if len(m.modelPickerState.Models) == 0 {
|
|
t.Error("should have models in picker")
|
|
}
|
|
if m.modelPickerState.CurrentModel != "qwen3.5:0.8b" {
|
|
t.Errorf("expected current model 'qwen3.5:0.8b', got %q", m.modelPickerState.CurrentModel)
|
|
}
|
|
})
|
|
t.Run("close_resets_state", func(t *testing.T) {
|
|
m := newTestModel(t)
|
|
m.modelList = []string{"qwen3.5:0.8b", "qwen3.5:2b"}
|
|
m.model = "qwen3.5:0.8b"
|
|
m.openModelPicker()
|
|
m.closeModelPicker()
|
|
if m.modelPickerState != nil {
|
|
t.Error("modelPickerState should be nil after close")
|
|
}
|
|
if m.overlay != OverlayNone {
|
|
t.Errorf("overlay should be OverlayNone, got %d", m.overlay)
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestModelPicker_Navigation(t *testing.T) {
|
|
setup := func(t *testing.T) *Model {
|
|
t.Helper()
|
|
m := newTestModel(t)
|
|
m.modelList = []string{"qwen3.5:0.8b", "qwen3.5:2b", "qwen3.5:4b", "qwen3.5:9b"}
|
|
m.model = config.DefaultModels()[0].Name
|
|
m.openModelPicker()
|
|
return m
|
|
}
|
|
t.Run("down_moves_index", func(t *testing.T) {
|
|
m := setup(t)
|
|
updated, _ := m.Update(downKey())
|
|
m = updated.(*Model)
|
|
if m.modelPickerState.List.Index() != 1 {
|
|
t.Errorf("expected index 1, got %d", m.modelPickerState.List.Index())
|
|
}
|
|
})
|
|
t.Run("up_at_zero_stays", func(t *testing.T) {
|
|
m := setup(t)
|
|
updated, _ := m.Update(upKey())
|
|
m = updated.(*Model)
|
|
if m.modelPickerState.List.Index() != 0 {
|
|
t.Errorf("expected index 0, got %d", m.modelPickerState.List.Index())
|
|
}
|
|
})
|
|
t.Run("down_clamped_at_end", func(t *testing.T) {
|
|
m := setup(t)
|
|
lastIdx := len(m.modelPickerState.Models) - 1
|
|
m.modelPickerState.List.Select(lastIdx)
|
|
updated, _ := m.Update(downKey())
|
|
m = updated.(*Model)
|
|
if m.modelPickerState.List.Index() != lastIdx {
|
|
t.Errorf("expected index to stay at end, got %d", m.modelPickerState.List.Index())
|
|
}
|
|
})
|
|
t.Run("esc_closes", func(t *testing.T) {
|
|
m := setup(t)
|
|
updated, _ := m.Update(escKey())
|
|
m = updated.(*Model)
|
|
if m.modelPickerState != nil {
|
|
t.Error("ESC should close picker")
|
|
}
|
|
if m.overlay != OverlayNone {
|
|
t.Errorf("overlay should be OverlayNone, got %d", m.overlay)
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestModelPicker_CtrlM(t *testing.T) {
|
|
t.Run("opens_with_ctrl_m", func(t *testing.T) {
|
|
m := newTestModel(t)
|
|
m.modelList = []string{"qwen3.5:0.8b", "qwen3.5:2b"}
|
|
m.model = "qwen3.5:0.8b"
|
|
m.state = StateIdle
|
|
updated, _ := m.Update(ctrlKey('m'))
|
|
m = updated.(*Model)
|
|
if m.overlay != OverlayModelPicker {
|
|
t.Errorf("ctrl+m should open model picker, got overlay %d", m.overlay)
|
|
}
|
|
})
|
|
t.Run("no_open_when_streaming", func(t *testing.T) {
|
|
m := newTestModel(t)
|
|
m.modelList = []string{"qwen3.5:0.8b"}
|
|
m.model = "qwen3.5:0.8b"
|
|
m.state = StateStreaming
|
|
updated, _ := m.Update(ctrlKey('m'))
|
|
m = updated.(*Model)
|
|
if m.overlay == OverlayModelPicker {
|
|
t.Error("should not open picker when streaming")
|
|
}
|
|
})
|
|
}
|