▍ humdrum codex / glint v1.1.2
license AGPL-3.0
2.9 KB raw
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
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)
	}
}