1package tui
2
3import (
4 "strings"
5 "testing"
6)
7
8func TestTerminalSyntaxPreservesPaletteSlots(t *testing.T) {
9 profile := TerminalProfile{Depth: ColorDepthIndexed256}
10 th := TerminalTheme(profile)
11 got := strings.Join(th.HighlightCode("func main() { return 1 }", "go"), "\n")
12 for _, sequence := range []string{"\x1b[94m", "\x1b[93m", "\x1b[39m"} {
13 if !strings.Contains(got, sequence) {
14 t.Fatalf("highlight output missing %q: %q", sequence, got)
15 }
16 }
17 if strings.Contains(got, "\x1b[38;5;196m") {
18 t.Fatalf("terminal formatter remapped ANSI slots through xterm cube: %q", got)
19 }
20}
21
22func TestTerminalSyntaxUsesReportedRGBPalette(t *testing.T) {
23 profile := terminalTestProfile(ColorDepthTrueColor)
24 th := TerminalTheme(profile)
25 got := strings.Join(th.HighlightCode("func main() {}", "go"), "\n")
26 if !strings.Contains(got, "\x1b[38;2;40;100;240m") {
27 t.Fatalf("highlight output did not use reported bright-blue palette: %q", got)
28 }
29}
30
31func TestTerminalSyntaxCacheIncludesSemanticRoles(t *testing.T) {
32 profile := TerminalProfile{Depth: ColorDepthTrueColor}
33 first := TerminalTheme(profile)
34 first.Accent = ColorRGB(1, 2, 3)
35 second := TerminalTheme(profile)
36 second.Accent = ColorRGB(4, 5, 6)
37
38 const source = "func terminalSyntaxCacheSentinel() {}"
39 if got := strings.Join(first.HighlightCode(source, "go"), "\n"); !strings.Contains(got, "\x1b[38;2;1;2;3m") {
40 t.Fatalf("first output = %q, want first accent", got)
41 }
42 if got := strings.Join(second.HighlightCode(source, "go"), "\n"); !strings.Contains(got, "\x1b[38;2;4;5;6m") {
43 t.Fatalf("second output reused first semantic color: %q", got)
44 }
45}
46
47func TestTerminalSyntaxHonorsCustomOverrides(t *testing.T) {
48 th := TerminalTheme(TerminalProfile{Depth: ColorDepthTrueColor})
49 th.Syntax.Keyword = "#112233 bold"
50 got := strings.Join(th.HighlightCode("func main() {}", "go"), "\n")
51 if !strings.Contains(got, "\x1b[38;2;17;34;51m\x1b[1mfunc") {
52 t.Fatalf("terminal formatter ignored custom keyword override: %q", got)
53 }
54}
55
56func TestTerminalSyntaxHonorsCustomBaseStyle(t *testing.T) {
57 th := TerminalTheme(TerminalProfile{Depth: ColorDepthTrueColor})
58 th.SyntaxBaseStyle = "monokai"
59 got := strings.Join(th.HighlightCode("func main() {}", "go"), "\n")
60 if !strings.Contains(got, "\x1b[38;2;102;217;239m") {
61 t.Fatalf("terminal formatter ignored custom syntax base style: %q", got)
62 }
63}
64
65func TestTerminalSyntaxBalancesMultilineTokens(t *testing.T) {
66 th := TerminalTheme(TerminalProfile{Depth: ColorDepthIndexed256})
67 lines := th.HighlightCode("/* first\nsecond */", "go")
68 if len(lines) != 2 {
69 t.Fatalf("line count = %d, want 2: %#v", len(lines), lines)
70 }
71 for _, line := range lines {
72 if !strings.HasSuffix(line, reset) {
73 t.Fatalf("line does not reset terminal style: %q", line)
74 }
75 }
76}