theme_test.go

  1package theme
  2
  3import (
  4	"image/color"
  5	"testing"
  6)
  7
  8func TestNewDark(t *testing.T) {
  9	s := New(true)
 10
 11	if !s.Dark {
 12		t.Error("New(true).Dark = false, want true")
 13	}
 14}
 15
 16func TestNewLight(t *testing.T) {
 17	s := New(false)
 18
 19	if s.Dark {
 20		t.Error("New(false).Dark = true, want false")
 21	}
 22}
 23
 24func TestSemanticColoursNotNil(t *testing.T) {
 25	t.Parallel()
 26
 27	for _, isDark := range []bool{true, false} {
 28		name := "dark"
 29		if !isDark {
 30			name = "light"
 31		}
 32
 33		t.Run(name, func(t *testing.T) {
 34			t.Parallel()
 35
 36			s := New(isDark)
 37			colours := map[string]color.Color{
 38				"Accent":    s.Accent,
 39				"Secondary": s.Secondary,
 40				"Warning":   s.Warning,
 41				"Confirm":   s.Confirm,
 42			}
 43			for label, c := range colours {
 44				if c == nil {
 45					t.Errorf("%s is nil", label)
 46				}
 47			}
 48		})
 49	}
 50}
 51
 52func TestHuhThemeReturnsBothPalettes(t *testing.T) {
 53	t.Parallel()
 54
 55	for _, isDark := range []bool{true, false} {
 56		name := "dark"
 57		if !isDark {
 58			name = "light"
 59		}
 60		t.Run(name, func(t *testing.T) {
 61			t.Parallel()
 62
 63			s := New(isDark)
 64			// The ThemeFunc is called with an arbitrary bool; it
 65			// should always use the isDark captured at build time.
 66			styles := s.Huh.Theme(isDark)
 67			if styles == nil {
 68				t.Fatal("Theme() returned nil Styles")
 69			}
 70		})
 71	}
 72}
 73
 74func TestHuhThemeIgnoresCallbackParameter(t *testing.T) {
 75	t.Parallel()
 76
 77	// Build a dark theme, then call the ThemeFunc with isDark=false.
 78	// The returned styles should still reflect the dark palette
 79	// because the callback parameter is intentionally ignored.
 80	dark := New(true)
 81	light := New(false)
 82
 83	fromDark := dark.Huh.Theme(false)  // pass false, should still get dark
 84	fromLight := light.Huh.Theme(true) // pass true, should still get light
 85
 86	if fromDark == nil {
 87		t.Fatal("Theme(false) on dark Styles returned nil")
 88	}
 89	if fromLight == nil {
 90		t.Fatal("Theme(true) on light Styles returned nil")
 91	}
 92
 93	// Verify the title colour matches the expected palette accent,
 94	// not the opposite palette. We compare the rendered output of
 95	// the title style — if huh's isDark parameter were used instead
 96	// of ours, the foreground colour would differ.
 97	//
 98	// Skip when lipgloss strips ANSI (e.g. TERM=dumb, NO_COLOR),
 99	// because both renders would collapse to plain "x".
100	darkTitle := fromDark.Focused.Title.Render("x")
101	lightTitle := fromLight.Focused.Title.Render("x")
102	if darkTitle == "x" && lightTitle == "x" {
103		t.Skip("colour output unavailable; cannot compare palette rendering")
104	}
105	if darkTitle == lightTitle {
106		t.Error("dark and light huh themes produced identical title rendering; isDark parameter may not be ignored")
107	}
108}
109
110func TestPickerStylesEmptyDirectoryMessage(t *testing.T) {
111	t.Parallel()
112
113	s := New(true)
114	got := s.Picker.EmptyDirectory.Value()
115	want := "No files in this directory."
116	if got != want {
117		t.Errorf("EmptyDirectory string = %q, want %q", got, want)
118	}
119}
120
121func TestHelpStylesNoDimText(t *testing.T) {
122	t.Parallel()
123
124	s := New(true)
125
126	// ShortDesc and FullDesc should have no foreground set (they
127	// inherit the terminal default). We verify by checking that the
128	// style renders without injecting a colour sequence.
129	plain := "test"
130	if got := s.Help.ShortDesc.Render(plain); got != plain {
131		t.Errorf("ShortDesc styled unexpectedly: got %q, want %q", got, plain)
132	}
133	if got := s.Help.FullDesc.Render(plain); got != plain {
134		t.Errorf("FullDesc styled unexpectedly: got %q, want %q", got, plain)
135	}
136}
137
138func TestCursorConstant(t *testing.T) {
139	t.Parallel()
140
141	if Cursor != "▸ " {
142		t.Errorf("Cursor = %q, want %q", Cursor, "▸ ")
143	}
144}