package editor import ( "strings" "testing" "glint/internal/theme" "github.com/charmbracelet/lipgloss" ) // tkBadges returns the set of span texts rendered with the TK badge background // (theme.TK). A badge span carries theme.TK as its background color. func tkBadges(e *Editor) map[string]bool { tk := e.theme.TK got := map[string]bool{} for _, vr := range e.buildVisual() { for _, sp := range vr.spans { if bg, ok := sp.Style.GetBackground().(lipgloss.Color); ok && bg == tk { got[sp.Text] = true } } } return got } func tkEditor(t *testing.T, content string) *Editor { t.Helper() e := New() e.SetTheme(theme.FlexokiDark()) e.SetContent([]byte(content)) return e } func TestTKHighlightsWholeWordMarkers(t *testing.T) { e := tkEditor(t, "Interview TK people about the $TK budget. Deadline TKTK.") badges := tkBadges(e) for _, want := range []string{"TK", "TKTK"} { if !badges[want] { t.Errorf("expected %q rendered as a TK badge; got badges %v", want, badges) } } } func TestTKCaseInsensitive(t *testing.T) { e := tkEditor(t, "fill in tk here and Tk there") badges := tkBadges(e) if !badges["tk"] || !badges["Tk"] { t.Errorf("expected lowercase tk and Tk badged; got %v", badges) } } func TestTKNotInsideRealWords(t *testing.T) { e := tkEditor(t, "The catkin on the network near Atkins and outkast") if badges := tkBadges(e); len(badges) != 0 { t.Errorf("no whole-word TK here; expected no badges, got %v", badges) } } func TestTKSkipsCodeFiles(t *testing.T) { e := tkEditor(t, "TK placeholder") e.SetLanguage("main.go") // code file: TK highlighting off, like spellcheck if badges := tkBadges(e); len(badges) != 0 { t.Errorf("TK should not render in code files; got %v", badges) } } func TestTKSkipsFrontmatter(t *testing.T) { e := tkEditor(t, "---\ntitle: TK\n---\nBody TK here") badges := tkBadges(e) if badges["title: TK"] || countTKBadges(e, 1) > 1 { t.Errorf("frontmatter TK should not badge; got %v", badges) } if !badges["TK"] { t.Errorf("body TK should still badge; got %v", badges) } } // countTKBadges counts badge spans whose text is exactly "TK". func countTKBadges(e *Editor, _ int) int { tk := e.theme.TK n := 0 for _, vr := range e.buildVisual() { for _, sp := range vr.spans { if bg, ok := sp.Style.GetBackground().(lipgloss.Color); ok && bg == tk && sp.Text == "TK" { n++ } } } return n } // TestTKPreservesLineText guards the markup-visible invariant: badging TK must not // add or drop any characters, so the concatenated span text equals the raw line. func TestTKPreservesLineText(t *testing.T) { const line = "Interview TK people; page TK; TKTK." e := tkEditor(t, line) var b strings.Builder for _, vr := range e.buildVisual() { for _, sp := range vr.spans { b.WriteString(sp.Text) } } if got := b.String(); got != line { t.Errorf("span text concatenation = %q, want %q", got, line) } }