@@ -0,0 +1,147 @@
1+package core_test
2+
3+import (
4+ "fmt"
5+ "image/color"
6+ "testing"
7+
8+ "github.com/charmbracelet/crush/internal/tui/components/core"
9+ "github.com/charmbracelet/x/exp/golden"
10+)
11+
12+func TestStatus(t *testing.T) {
13+ t.Parallel()
14+
15+ tests := []struct {
16+ name string
17+ opts core.StatusOpts
18+ width int
19+ }{
20+ {
21+ name: "Default",
22+ opts: core.StatusOpts{
23+ Title: "Status",
24+ Description: "Everything is working fine",
25+ },
26+ width: 80,
27+ },
28+ {
29+ name: "WithCustomIcon",
30+ opts: core.StatusOpts{
31+ Icon: "✓",
32+ Title: "Success",
33+ Description: "Operation completed successfully",
34+ },
35+ width: 80,
36+ },
37+ {
38+ name: "NoIcon",
39+ opts: core.StatusOpts{
40+ NoIcon: true,
41+ Title: "Info",
42+ Description: "This status has no icon",
43+ },
44+ width: 80,
45+ },
46+ {
47+ name: "WithColors",
48+ opts: core.StatusOpts{
49+ Icon: "⚠",
50+ IconColor: color.RGBA{255, 165, 0, 255}, // Orange
51+ Title: "Warning",
52+ TitleColor: color.RGBA{255, 255, 0, 255}, // Yellow
53+ Description: "This is a warning message",
54+ DescriptionColor: color.RGBA{255, 0, 0, 255}, // Red
55+ },
56+ width: 80,
57+ },
58+ {
59+ name: "WithExtraContent",
60+ opts: core.StatusOpts{
61+ Title: "Build",
62+ Description: "Building project",
63+ ExtraContent: "[2/5]",
64+ },
65+ width: 80,
66+ },
67+ {
68+ name: "LongDescription",
69+ opts: core.StatusOpts{
70+ Title: "Processing",
71+ Description: "This is a very long description that should be truncated when the width is too small to display it completely without wrapping",
72+ },
73+ width: 60,
74+ },
75+ {
76+ name: "NarrowWidth",
77+ opts: core.StatusOpts{
78+ Icon: "●",
79+ Title: "Status",
80+ Description: "Short message",
81+ },
82+ width: 30,
83+ },
84+ {
85+ name: "VeryNarrowWidth",
86+ opts: core.StatusOpts{
87+ Icon: "●",
88+ Title: "Test",
89+ Description: "This will be truncated",
90+ },
91+ width: 20,
92+ },
93+ {
94+ name: "EmptyDescription",
95+ opts: core.StatusOpts{
96+ Icon: "●",
97+ Title: "Title Only",
98+ },
99+ width: 80,
100+ },
101+ {
102+ name: "AllFieldsWithExtraContent",
103+ opts: core.StatusOpts{
104+ Icon: "🚀",
105+ IconColor: color.RGBA{0, 255, 0, 255}, // Green
106+ Title: "Deployment",
107+ TitleColor: color.RGBA{0, 0, 255, 255}, // Blue
108+ Description: "Deploying to production environment",
109+ DescriptionColor: color.RGBA{128, 128, 128, 255}, // Gray
110+ ExtraContent: "v1.2.3",
111+ },
112+ width: 80,
113+ },
114+ }
115+
116+ for _, tt := range tests {
117+ t.Run(tt.name, func(t *testing.T) {
118+ t.Parallel()
119+
120+ output := core.Status(tt.opts, tt.width)
121+ golden.RequireEqual(t, []byte(output))
122+ })
123+ }
124+}
125+
126+func TestStatusTruncation(t *testing.T) {
127+ t.Parallel()
128+
129+ opts := core.StatusOpts{
130+ Icon: "●",
131+ Title: "Very Long Title",
132+ Description: "This is an extremely long description that definitely needs to be truncated",
133+ ExtraContent: "[extra]",
134+ }
135+
136+ // Test different widths to ensure truncation works correctly
137+ widths := []int{20, 30, 40, 50, 60}
138+
139+ for _, width := range widths {
140+ t.Run(fmt.Sprintf("Width%d", width), func(t *testing.T) {
141+ t.Parallel()
142+
143+ output := core.Status(opts, width)
144+ golden.RequireEqual(t, []byte(output))
145+ })
146+ }
147+}