package ui import ( "strings" "testing" ) func TestStatusBarDrawsItsHints(t *testing.T) { screen, root := newTestScreen(t, 40, 2) bar := NewStatusBar( StatusItem{Key: "F1", Label: "Help"}, StatusItem{Key: "F2", Label: "Save"}, ) bar.SetBounds(Rect{X: 0, Y: 1, W: 40, H: 1}) bar.Draw(root, testTheme(t)) screen.Show() got := screenLines(t, screen)[1] if !strings.Contains(got, "F1 Help") || !strings.Contains(got, "F2 Save") { t.Errorf("the status bar is %q, want both hints", got) } } func TestAMessageReplacesTheHints(t *testing.T) { screen, root := newTestScreen(t, 40, 2) bar := NewStatusBar(StatusItem{Key: "F2", Label: "Save"}) bar.SetBounds(Rect{X: 0, Y: 1, W: 40, H: 1}) bar.SetMessage("File saved") bar.Draw(root, testTheme(t)) screen.Show() got := screenLines(t, screen)[1] if !strings.Contains(got, "File saved") { t.Errorf("the status bar is %q, want the message", got) } if strings.Contains(got, "F2") { t.Errorf("the status bar is %q, want the hints hidden while a message shows", got) } if bar.Message() != "File saved" { t.Errorf("Message() = %q", bar.Message()) } bar.SetMessage("") bar.Draw(root, testTheme(t)) screen.Show() if !strings.Contains(screenLines(t, screen)[1], "F2") { t.Error("clearing the message did not bring the hints back") } } func TestExtraTextIsRightAligned(t *testing.T) { screen, root := newTestScreen(t, 40, 2) bar := NewStatusBar(StatusItem{Key: "F1", Label: "Help"}) bar.SetBounds(Rect{X: 0, Y: 1, W: 40, H: 1}) bar.SetExtra("12:5") bar.Draw(root, testTheme(t)) screen.Show() got := screenLines(t, screen)[1] if !strings.HasSuffix(strings.TrimRight(got, " "), "12:5") { t.Errorf("the status bar is %q, want the extra text at the right", got) } } func TestClickingAHintRunsItsAction(t *testing.T) { ran := "" bar := NewStatusBar( StatusItem{Key: "F1", Label: "Help", Action: func() { ran = "help" }}, StatusItem{Key: "F2", Label: "Save", Action: func() { ran = "save" }}, ) bar.SetBounds(Rect{X: 0, Y: 5, W: 40, H: 1}) // "F1 Help" occupies columns 1..8, so "F2 Save" starts at 10. bar.HandleMouse(clickEvent(11, 5)) if ran != "save" { t.Errorf("the action that ran was %q, want save", ran) } } func TestAClickOffTheStatusBarIsNotItsBusiness(t *testing.T) { bar := NewStatusBar(StatusItem{Key: "F1", Label: "Help", Action: func() {}}) bar.SetBounds(Rect{X: 0, Y: 5, W: 40, H: 1}) if bar.HandleMouse(clickEvent(3, 0)) { t.Error("the status bar claimed a click from another row") } } func TestClickingPastTheLastHintDoesNothing(t *testing.T) { ran := 0 bar := NewStatusBar(StatusItem{Key: "F1", Label: "Help", Action: func() { ran++ }}) bar.SetBounds(Rect{X: 0, Y: 5, W: 40, H: 1}) bar.HandleMouse(clickEvent(35, 5)) if ran != 0 { t.Error("a click on the empty part of the bar ran an action") } } func TestSetItemsReplacesTheHints(t *testing.T) { screen, root := newTestScreen(t, 40, 2) bar := NewStatusBar(StatusItem{Key: "F1", Label: "Help"}) bar.SetBounds(Rect{X: 0, Y: 1, W: 40, H: 1}) bar.SetItems(StatusItem{Key: "Esc", Label: "Cancel"}) bar.Draw(root, testTheme(t)) screen.Show() got := screenLines(t, screen)[1] if strings.Contains(got, "Help") || !strings.Contains(got, "Esc Cancel") { t.Errorf("the status bar is %q, want only the new hint", got) } }