package main // The frame is the one place where an off-by-one becomes a broken screen, so it // is checked rather than eyeballed: every rendered line must be exactly the // width asked for, at every size, with and without tabs. import ( "strings" "testing" "github.com/charmbracelet/lipgloss" ) func lines(s string) []string { return strings.Split(s, "\n") } func TestFrameEveryLineIsExactWidth(t *testing.T) { for w := 10; w <= 90; w++ { for h := 3; h <= 20; h++ { for _, tabs := range [][]string{nil, {"one", "two"}, {"a"}} { for _, focused := range []bool{false, true} { p := panel{title: "tasks", tabs: tabs, width: w, height: h, focused: focused} out := p.render([]string{"first", "second"}) got := lines(out) if len(got) != h { t.Fatalf("width %d height %d: got %d lines, want %d", w, h, len(got), h) } for i, ln := range got { if lipgloss.Width(ln) != w { t.Fatalf("width %d height %d tab=%v focus=%v line %d: width %d (%q)", w, h, tabs, focused, i, lipgloss.Width(ln), ln) } } } } } } } func TestFrameBodyIsClippedNotWrapped(t *testing.T) { p := panel{title: "t", width: 20, height: 4} out := p.render([]string{"a line that is much too long for the frame"}) for i, ln := range lines(out) { if lipgloss.Width(ln) != 20 { t.Fatalf("line %d is %d wide, want 20: %q", i, lipgloss.Width(ln), ln) } } } func TestTruncateVisibleKeepsStylingAndWidth(t *testing.T) { styled := lipgloss.NewStyle().Bold(true).Render("abcdefghij") got := truncateVisible(styled, 5) if lipgloss.Width(got) > 5 { t.Fatalf("truncated width %d, want at most 5: %q", lipgloss.Width(got), got) } if !strings.Contains(got, "…") { t.Fatalf("truncation should say it truncated: %q", got) } }