On a light background (Catppuccin Latte in Ghostty on macOS) the panes kept palette color 0, a dark grey slab with white text. The probe now also asks for the text color (OSC 10). Light backgrounds are used as well, with text, borders and titles in the terminal's text color, input fields and buttons in a light shade of it, and the active tab drawn in it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019reK4DUGYqDUjniWYJvwUW
96 lines
4.0 KiB
Go
96 lines
4.0 KiB
Go
package ui
|
|
|
|
import (
|
|
"image/color"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/gdamore/tcell/v2"
|
|
"github.com/rivo/tview"
|
|
)
|
|
|
|
func TestParseTerminalAnswers(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
name string
|
|
got string
|
|
graphics bool
|
|
bg color.RGBA
|
|
hasBG bool
|
|
}{
|
|
{"ghostty", "\x1b_Gi=31;OK\x1b\\\x1b]11;rgb:1e1e/1e1e/2e2e\x1b\\\x1b[?62;22c", true, color.RGBA{30, 30, 46, 255}, true},
|
|
{"text color too", "\x1b]10;rgb:4c4c/4f4f/6969\x1b\\\x1b]11;rgb:efef/f1f1/f5f5\x1b\\\x1b[?62c", false, color.RGBA{239, 241, 245, 255}, true},
|
|
{"bel and two digits", "\x1b]11;rgb:ff/80/00\a\x1b[?1;2c", false, color.RGBA{255, 128, 0, 255}, true},
|
|
{"one digit", "\x1b]11;rgb:f/0/8\x1b\\\x1b[?6c", false, color.RGBA{255, 0, 136, 255}, true},
|
|
{"only device attributes", "\x1b[?1;2c", false, color.RGBA{}, false},
|
|
{"garbage", "\x1b]11;rgb:zz/00/00\x1b\\\x1b[?6c", false, color.RGBA{}, false},
|
|
{"nothing", "", false, color.RGBA{}, false},
|
|
} {
|
|
info := parseTerminalAnswers([]byte(tc.got))
|
|
if info.graphics != tc.graphics || info.hasBG != tc.hasBG || info.bg != tc.bg {
|
|
t.Errorf("%s: %+v", tc.name, info)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestUseTerminalBackground(t *testing.T) {
|
|
// tcell's terminal database also reads these from the real environment
|
|
// (and keeps what it added to an entry because of them, so the test uses
|
|
// a terminal nothing else looks up).
|
|
t.Setenv("COLORTERM", "")
|
|
t.Setenv("TCELL_TRUECOLOR", "")
|
|
defer func(old tview.Theme, tab string) { tview.Styles, activeTabTag = old, tab }(tview.Styles, activeTabTag)
|
|
env := func(m map[string]string) func(string) string { return func(k string) string { return m[k] } }
|
|
dark := terminalInfo{bg: color.RGBA{30, 30, 46, 255}, hasBG: true}
|
|
light := terminalInfo{bg: color.RGBA{239, 241, 245, 255}, hasBG: true, fg: color.RGBA{76, 79, 105, 255}, hasFG: true}
|
|
truecolor := env(map[string]string{"COLORTERM": "truecolor"})
|
|
|
|
for _, tc := range []struct {
|
|
name string
|
|
info terminalInfo
|
|
env func(string) string
|
|
want bool
|
|
}{
|
|
{"dark background, true color", dark, truecolor, true},
|
|
{"no true color", dark, env(map[string]string{"TERM": "vt100"}), false},
|
|
{"ghostty without COLORTERM", dark, env(map[string]string{"TERM": "xterm-ghostty"}), true},
|
|
{"true color disabled for tcell", dark, env(map[string]string{"TERM": "xterm-ghostty", "TCELL_TRUECOLOR": "disable"}), false},
|
|
{"light background", light, truecolor, true},
|
|
{"no answer", terminalInfo{}, truecolor, false},
|
|
} {
|
|
tview.Styles.PrimitiveBackgroundColor = tcell.ColorBlack
|
|
note := useTerminalBackground(tc.info, tc.env)
|
|
if got := strings.Contains(note, "own color"); got != tc.want {
|
|
t.Errorf("%s: %s", tc.name, note)
|
|
}
|
|
want := tcell.ColorBlack
|
|
if tc.want {
|
|
want = rgb(tc.info.bg)
|
|
}
|
|
if tview.Styles.PrimitiveBackgroundColor != want {
|
|
t.Errorf("%s: background %v", tc.name, tview.Styles.PrimitiveBackgroundColor)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestLightBackgroundUsesTheTextColor(t *testing.T) {
|
|
defer func(old tview.Theme, tab string) { tview.Styles, activeTabTag = old, tab }(tview.Styles, activeTabTag)
|
|
latte := terminalInfo{bg: color.RGBA{239, 241, 245, 255}, hasBG: true, fg: color.RGBA{76, 79, 105, 255}, hasFG: true}
|
|
useTerminalBackground(latte, func(k string) string { return map[string]string{"COLORTERM": "truecolor"}[k] })
|
|
st := tview.Styles
|
|
if st.PrimaryTextColor != tcell.NewRGBColor(76, 79, 105) || st.BorderColor != st.PrimaryTextColor {
|
|
t.Errorf("text %v, borders %v", st.PrimaryTextColor, st.BorderColor)
|
|
}
|
|
if st.ContrastBackgroundColor == tcell.ColorBlue {
|
|
t.Error("input fields should not stay palette blue on a light background")
|
|
}
|
|
if activeTabTag != "[#eff1f5:#4c4f69]" {
|
|
t.Errorf("active tab %s", activeTabTag)
|
|
}
|
|
// Without a text color answer the text is black.
|
|
tview.Styles = st
|
|
useTerminalBackground(terminalInfo{bg: latte.bg, hasBG: true}, func(k string) string { return map[string]string{"COLORTERM": "truecolor"}[k] })
|
|
if tview.Styles.PrimaryTextColor != tcell.NewRGBColor(0, 0, 0) {
|
|
t.Errorf("fallback text %v", tview.Styles.PrimitiveBackgroundColor)
|
|
}
|
|
}
|