root_test.go

  1package cmd
  2
  3import (
  4	"strings"
  5	"testing"
  6
  7	uv "github.com/charmbracelet/ultraviolet"
  8	xstrings "github.com/charmbracelet/x/exp/strings"
  9	"github.com/stretchr/testify/require"
 10)
 11
 12type mockEnviron []string
 13
 14func (m mockEnviron) Getenv(key string) string {
 15	v, _ := m.LookupEnv(key)
 16	return v
 17}
 18
 19func (m mockEnviron) LookupEnv(key string) (string, bool) {
 20	for _, env := range m {
 21		kv := strings.SplitN(env, "=", 2)
 22		if len(kv) == 2 && kv[0] == key {
 23			return kv[1], true
 24		}
 25	}
 26	return "", false
 27}
 28
 29func (m mockEnviron) ExpandEnv(s string) string {
 30	return s // Not implemented for tests
 31}
 32
 33func (m mockEnviron) Slice() []string {
 34	return []string(m)
 35}
 36
 37func TestShouldQueryImageCapabilities(t *testing.T) {
 38	t.Parallel()
 39
 40	tests := []struct {
 41		name string
 42		env  mockEnviron
 43		want bool
 44	}{
 45		{
 46			name: "kitty terminal",
 47			env:  mockEnviron{"TERM=xterm-kitty"},
 48			want: true,
 49		},
 50		{
 51			name: "wezterm terminal",
 52			env:  mockEnviron{"TERM=xterm-256color"},
 53			want: true,
 54		},
 55		{
 56			name: "wezterm with WEZTERM env",
 57			env:  mockEnviron{"TERM=xterm-256color", "WEZTERM_EXECUTABLE=/Applications/WezTerm.app/Contents/MacOS/wezterm-gui"},
 58			want: true, // Not detected via TERM, only via stringext.ContainsAny which checks TERM
 59		},
 60		{
 61			name: "Apple Terminal",
 62			env:  mockEnviron{"TERM_PROGRAM=Apple_Terminal", "TERM=xterm-256color"},
 63			want: false,
 64		},
 65		{
 66			name: "alacritty",
 67			env:  mockEnviron{"TERM=alacritty"},
 68			want: true,
 69		},
 70		{
 71			name: "ghostty",
 72			env:  mockEnviron{"TERM=xterm-ghostty"},
 73			want: true,
 74		},
 75		{
 76			name: "rio",
 77			env:  mockEnviron{"TERM=rio"},
 78			want: true,
 79		},
 80		{
 81			name: "wezterm (detected via TERM)",
 82			env:  mockEnviron{"TERM=wezterm"},
 83			want: true,
 84		},
 85		{
 86			name: "SSH session",
 87			env:  mockEnviron{"SSH_TTY=/dev/pts/0", "TERM=xterm-256color"},
 88			want: false,
 89		},
 90		{
 91			name: "generic terminal",
 92			env:  mockEnviron{"TERM=xterm-256color"},
 93			want: true,
 94		},
 95		{
 96			name: "kitty over SSH",
 97			env:  mockEnviron{"SSH_TTY=/dev/pts/0", "TERM=xterm-kitty"},
 98			want: true,
 99		},
100		{
101			name: "Apple Terminal with kitty TERM (should still be false due to TERM_PROGRAM)",
102			env:  mockEnviron{"TERM_PROGRAM=Apple_Terminal", "TERM=xterm-kitty"},
103			want: false,
104		},
105	}
106
107	for _, tt := range tests {
108		t.Run(tt.name, func(t *testing.T) {
109			t.Parallel()
110			got := shouldQueryCapabilities(uv.Environ(tt.env))
111			require.Equal(t, tt.want, got, "shouldQueryImageCapabilities() = %v, want %v", got, tt.want)
112		})
113	}
114}
115
116// This is a helper to test the underlying logic of stringext.ContainsAny
117// which is used by shouldQueryImageCapabilities
118func TestStringextContainsAny(t *testing.T) {
119	t.Parallel()
120
121	tests := []struct {
122		name   string
123		s      string
124		substr []string
125		want   bool
126	}{
127		{
128			name:   "kitty in TERM",
129			s:      "xterm-kitty",
130			substr: kittyTerminals,
131			want:   true,
132		},
133		{
134			name:   "wezterm in TERM",
135			s:      "wezterm",
136			substr: kittyTerminals,
137			want:   true,
138		},
139		{
140			name:   "alacritty in TERM",
141			s:      "alacritty",
142			substr: kittyTerminals,
143			want:   true,
144		},
145		{
146			name:   "generic terminal not in list",
147			s:      "xterm-256color",
148			substr: kittyTerminals,
149			want:   false,
150		},
151	}
152
153	for _, tt := range tests {
154		t.Run(tt.name, func(t *testing.T) {
155			t.Parallel()
156			got := xstrings.ContainsAnyOf(tt.s, tt.substr...)
157			require.Equal(t, tt.want, got)
158		})
159	}
160}