package grid import ( "testing" "github.com/charmbracelet/lipgloss" "github.com/mattn/go-runewidth" ) // A calendar label carries a double-width emoji (🧠 = 2 cells). trunc and // padCell must reason in display cells, not runes, or the cell overflows its // column and the terminal wraps it — the alignment bug this guards against. func TestTruncMeasuresDisplayWidthNotRunes(t *testing.T) { // "🧠 Focus time" is 12 runes but 13 display cells (emoji counts as 2). s := "🧠 Focus time" if got := runewidth.StringWidth(s); got != 13 { t.Fatalf("precondition: want display width 13, got %d", got) } // Truncating to 10 cells must yield a result that fits in 10 cells. out := trunc(s, 10) if w := runewidth.StringWidth(out); w > 10 { t.Fatalf("trunc(%q,10) display width = %d, want <= 10 (got %q)", s, w, out) } // A string already within width is returned untouched. if out := trunc(s, 20); out != s { t.Fatalf("trunc of in-width string changed it: %q", out) } } func TestPadCellPadsToDisplayWidth(t *testing.T) { // Emoji cell: 3 runes / 4 display cells; padding to actWidth must land on // exactly actWidth *cells*, not actWidth runes (which would over-pad and // push the divider right). out := padCell("🧠 x", actWidth) if w := runewidth.StringWidth(out); w != actWidth { t.Fatalf("padCell display width = %d, want %d (got %q)", w, actWidth, out) } } func TestRenderActCellCalendarKeepsColumnWidth(t *testing.T) { // The rendered lane cell (before ANSI styling widths are irrelevant to the // terminal) must occupy exactly actWidth display cells regardless of emoji. for _, tc := range []struct { name string cell Cell }{ {"calendar+emoji", Cell{Kind: CellLabel, Act: ActCalendar, Text: "▪ 🧠 Focus time"}}, {"plain active", Cell{Kind: CellLabel, Act: ActActive, Text: "organize"}}, {"idle", Cell{Kind: CellLabel, Act: ActIdle, Text: "(idle)"}}, {"continuation", Cell{Kind: CellCont, Act: ActCalendar}}, {"long title truncates", Cell{Kind: CellLabel, Act: ActActive, Text: "Investigate story structure and the whole backlog pile"}}, } { out := renderActCell(tc.cell) if w := lipgloss.Width(out); w != actWidth { t.Errorf("%s: rendered width = %d, want %d (got %q)", tc.name, w, actWidth, out) } } }