Files
Archduino/internal/tui/dashboard/model_test.go

79 lines
2.6 KiB
Go

package dashboard
import (
"errors"
"strings"
"testing"
"gitlab.hive-brain.de/MDietermann/Archduino/internal/engine"
"gitlab.hive-brain.de/MDietermann/Archduino/internal/tui"
)
func TestProgressUpdatesRow(t *testing.T) {
m := NewModel([]string{"a"}, map[string]string{"a": "Alpha"})
m.Update(tui.ProgressMsg{ModuleID: "a", Current: 3, Total: 10, Message: "doing"})
if r := m.rowIndex["a"]; r.Current != 3 || r.Total != 10 || r.LastMsg != "doing" {
t.Fatalf("row state wrong: %+v", r)
}
}
func TestLogAppendedBounded(t *testing.T) {
m := NewModel([]string{"a"}, nil)
for i := 0; i < 300; i++ {
m.Update(tui.LogMsg{ModuleID: "a", Line: "x"})
}
if got := len(m.rowIndex["a"].LogTail); got != 200 {
t.Fatalf("log tail = %d, want 200", got)
}
}
func TestDoneMsgFlipsIcons(t *testing.T) {
m := NewModel([]string{"ok", "bad", "skip"}, nil)
m.Update(DoneMsg{Summary: engine.Summary{Results: []engine.ModuleResult{
{ID: "ok", Status: engine.StatusSucceeded},
{ID: "bad", Status: engine.StatusFailed, Err: errors.New("boom")},
{ID: "skip", Status: engine.StatusSkipped},
}}})
if m.rowIndex["ok"].StatusIcon != "✓" {
t.Errorf("ok icon = %q", m.rowIndex["ok"].StatusIcon)
}
if m.rowIndex["bad"].StatusIcon != "✗" {
t.Errorf("bad icon = %q", m.rowIndex["bad"].StatusIcon)
}
if m.rowIndex["skip"].StatusIcon != "⊘" {
t.Errorf("skip icon = %q", m.rowIndex["skip"].StatusIcon)
}
}
func TestProgressAfterDoneDoesNotRevertIcon(t *testing.T) {
m := NewModel([]string{"a"}, nil)
m.Update(DoneMsg{Summary: engine.Summary{Results: []engine.ModuleResult{
{ID: "a", Status: engine.StatusSucceeded},
}}})
if got := m.rowIndex["a"].StatusIcon; got != "✓" {
t.Fatalf("after Done icon = %q, want ✓", got)
}
// Late Progress event — tea.Program.Send has no ordering guarantee across goroutines.
m.Update(tui.ProgressMsg{ModuleID: "a", Current: 9, Total: 10, Message: "late"})
if got := m.rowIndex["a"].StatusIcon; got != "✓" {
t.Fatalf("late Progress reverted icon to %q", got)
}
// Late Log event must also be dropped — it would otherwise pollute the
// log tail of a completed row.
before := len(m.rowIndex["a"].LogTail)
m.Update(tui.LogMsg{ModuleID: "a", Line: "late log"})
if after := len(m.rowIndex["a"].LogTail); after != before {
t.Fatalf("late Log appended to tail: before=%d after=%d", before, after)
}
}
func TestViewMentionsModules(t *testing.T) {
m := NewModel([]string{"alpha", "bravo"}, nil)
out := m.View()
for _, want := range []string{"alpha", "bravo", "archduino install"} {
if !strings.Contains(out, want) {
t.Errorf("view missing %q:\n%s", want, out)
}
}
}