1package color
2
3import (
4	"bytes"
5	"fmt"
6	"os"
7	"testing"
8
9	"github.com/mattn/go-colorable"
10)
11
12// Testing colors is kinda different. First we test for given colors and their
13// escaped formatted results. Next we create some visual tests to be tested.
14// Each visual test includes the color name to be compared.
15func TestColor(t *testing.T) {
16	rb := new(bytes.Buffer)
17	Output = rb
18
19	NoColor = false
20
21	testColors := []struct {
22		text string
23		code Attribute
24	}{
25		{text: "black", code: FgBlack},
26		{text: "red", code: FgRed},
27		{text: "green", code: FgGreen},
28		{text: "yellow", code: FgYellow},
29		{text: "blue", code: FgBlue},
30		{text: "magent", code: FgMagenta},
31		{text: "cyan", code: FgCyan},
32		{text: "white", code: FgWhite},
33		{text: "hblack", code: FgHiBlack},
34		{text: "hred", code: FgHiRed},
35		{text: "hgreen", code: FgHiGreen},
36		{text: "hyellow", code: FgHiYellow},
37		{text: "hblue", code: FgHiBlue},
38		{text: "hmagent", code: FgHiMagenta},
39		{text: "hcyan", code: FgHiCyan},
40		{text: "hwhite", code: FgHiWhite},
41	}
42
43	for _, c := range testColors {
44		New(c.code).Print(c.text)
45
46		line, _ := rb.ReadString('\n')
47		scannedLine := fmt.Sprintf("%q", line)
48		colored := fmt.Sprintf("\x1b[%dm%s\x1b[0m", c.code, c.text)
49		escapedForm := fmt.Sprintf("%q", colored)
50
51		fmt.Printf("%s\t: %s\n", c.text, line)
52
53		if scannedLine != escapedForm {
54			t.Errorf("Expecting %s, got '%s'\n", escapedForm, scannedLine)
55		}
56	}
57
58	for _, c := range testColors {
59		line := New(c.code).Sprintf("%s", c.text)
60		scannedLine := fmt.Sprintf("%q", line)
61		colored := fmt.Sprintf("\x1b[%dm%s\x1b[0m", c.code, c.text)
62		escapedForm := fmt.Sprintf("%q", colored)
63
64		fmt.Printf("%s\t: %s\n", c.text, line)
65
66		if scannedLine != escapedForm {
67			t.Errorf("Expecting %s, got '%s'\n", escapedForm, scannedLine)
68		}
69	}
70}
71
72func TestColorEquals(t *testing.T) {
73	fgblack1 := New(FgBlack)
74	fgblack2 := New(FgBlack)
75	bgblack := New(BgBlack)
76	fgbgblack := New(FgBlack, BgBlack)
77	fgblackbgred := New(FgBlack, BgRed)
78	fgred := New(FgRed)
79	bgred := New(BgRed)
80
81	if !fgblack1.Equals(fgblack2) {
82		t.Error("Two black colors are not equal")
83	}
84
85	if fgblack1.Equals(bgblack) {
86		t.Error("Fg and bg black colors are equal")
87	}
88
89	if fgblack1.Equals(fgbgblack) {
90		t.Error("Fg black equals fg/bg black color")
91	}
92
93	if fgblack1.Equals(fgred) {
94		t.Error("Fg black equals Fg red")
95	}
96
97	if fgblack1.Equals(bgred) {
98		t.Error("Fg black equals Bg red")
99	}
100
101	if fgblack1.Equals(fgblackbgred) {
102		t.Error("Fg black equals fg black bg red")
103	}
104}
105
106func TestNoColor(t *testing.T) {
107	rb := new(bytes.Buffer)
108	Output = rb
109
110	testColors := []struct {
111		text string
112		code Attribute
113	}{
114		{text: "black", code: FgBlack},
115		{text: "red", code: FgRed},
116		{text: "green", code: FgGreen},
117		{text: "yellow", code: FgYellow},
118		{text: "blue", code: FgBlue},
119		{text: "magent", code: FgMagenta},
120		{text: "cyan", code: FgCyan},
121		{text: "white", code: FgWhite},
122		{text: "hblack", code: FgHiBlack},
123		{text: "hred", code: FgHiRed},
124		{text: "hgreen", code: FgHiGreen},
125		{text: "hyellow", code: FgHiYellow},
126		{text: "hblue", code: FgHiBlue},
127		{text: "hmagent", code: FgHiMagenta},
128		{text: "hcyan", code: FgHiCyan},
129		{text: "hwhite", code: FgHiWhite},
130	}
131
132	for _, c := range testColors {
133		p := New(c.code)
134		p.DisableColor()
135		p.Print(c.text)
136
137		line, _ := rb.ReadString('\n')
138		if line != c.text {
139			t.Errorf("Expecting %s, got '%s'\n", c.text, line)
140		}
141	}
142
143	// global check
144	NoColor = true
145	t.Cleanup(func() {
146		NoColor = false
147	})
148
149	for _, c := range testColors {
150		p := New(c.code)
151		p.Print(c.text)
152
153		line, _ := rb.ReadString('\n')
154		if line != c.text {
155			t.Errorf("Expecting %s, got '%s'\n", c.text, line)
156		}
157	}
158}
159
160func TestNoColor_Env(t *testing.T) {
161	rb := new(bytes.Buffer)
162	Output = rb
163
164	testColors := []struct {
165		text string
166		code Attribute
167	}{
168		{text: "black", code: FgBlack},
169		{text: "red", code: FgRed},
170		{text: "green", code: FgGreen},
171		{text: "yellow", code: FgYellow},
172		{text: "blue", code: FgBlue},
173		{text: "magent", code: FgMagenta},
174		{text: "cyan", code: FgCyan},
175		{text: "white", code: FgWhite},
176		{text: "hblack", code: FgHiBlack},
177		{text: "hred", code: FgHiRed},
178		{text: "hgreen", code: FgHiGreen},
179		{text: "hyellow", code: FgHiYellow},
180		{text: "hblue", code: FgHiBlue},
181		{text: "hmagent", code: FgHiMagenta},
182		{text: "hcyan", code: FgHiCyan},
183		{text: "hwhite", code: FgHiWhite},
184	}
185
186	os.Setenv("NO_COLOR", "")
187	t.Cleanup(func() {
188		os.Unsetenv("NO_COLOR")
189	})
190
191	for _, c := range testColors {
192		p := New(c.code)
193		p.Print(c.text)
194
195		line, _ := rb.ReadString('\n')
196		if line != c.text {
197			t.Errorf("Expecting %s, got '%s'\n", c.text, line)
198		}
199	}
200
201}
202
203func TestColorVisual(t *testing.T) {
204	// First Visual Test
205	Output = colorable.NewColorableStdout()
206
207	New(FgRed).Printf("red\t")
208	New(BgRed).Print("         ")
209	New(FgRed, Bold).Println(" red")
210
211	New(FgGreen).Printf("green\t")
212	New(BgGreen).Print("         ")
213	New(FgGreen, Bold).Println(" green")
214
215	New(FgYellow).Printf("yellow\t")
216	New(BgYellow).Print("         ")
217	New(FgYellow, Bold).Println(" yellow")
218
219	New(FgBlue).Printf("blue\t")
220	New(BgBlue).Print("         ")
221	New(FgBlue, Bold).Println(" blue")
222
223	New(FgMagenta).Printf("magenta\t")
224	New(BgMagenta).Print("         ")
225	New(FgMagenta, Bold).Println(" magenta")
226
227	New(FgCyan).Printf("cyan\t")
228	New(BgCyan).Print("         ")
229	New(FgCyan, Bold).Println(" cyan")
230
231	New(FgWhite).Printf("white\t")
232	New(BgWhite).Print("         ")
233	New(FgWhite, Bold).Println(" white")
234	fmt.Println("")
235
236	// Second Visual test
237	Black("black")
238	Red("red")
239	Green("green")
240	Yellow("yellow")
241	Blue("blue")
242	Magenta("magenta")
243	Cyan("cyan")
244	White("white")
245	HiBlack("hblack")
246	HiRed("hred")
247	HiGreen("hgreen")
248	HiYellow("hyellow")
249	HiBlue("hblue")
250	HiMagenta("hmagenta")
251	HiCyan("hcyan")
252	HiWhite("hwhite")
253
254	// Third visual test
255	fmt.Println()
256	Set(FgBlue)
257	fmt.Println("is this blue?")
258	Unset()
259
260	Set(FgMagenta)
261	fmt.Println("and this magenta?")
262	Unset()
263
264	// Fourth Visual test
265	fmt.Println()
266	blue := New(FgBlue).PrintlnFunc()
267	blue("blue text with custom print func")
268
269	red := New(FgRed).PrintfFunc()
270	red("red text with a printf func: %d\n", 123)
271
272	put := New(FgYellow).SprintFunc()
273	warn := New(FgRed).SprintFunc()
274
275	fmt.Fprintf(Output, "this is a %s and this is %s.\n", put("warning"), warn("error"))
276
277	info := New(FgWhite, BgGreen).SprintFunc()
278	fmt.Fprintf(Output, "this %s rocks!\n", info("package"))
279
280	notice := New(FgBlue).FprintFunc()
281	notice(os.Stderr, "just a blue notice to stderr")
282
283	// Fifth Visual Test
284	fmt.Println()
285
286	fmt.Fprintln(Output, BlackString("black"))
287	fmt.Fprintln(Output, RedString("red"))
288	fmt.Fprintln(Output, GreenString("green"))
289	fmt.Fprintln(Output, YellowString("yellow"))
290	fmt.Fprintln(Output, BlueString("blue"))
291	fmt.Fprintln(Output, MagentaString("magenta"))
292	fmt.Fprintln(Output, CyanString("cyan"))
293	fmt.Fprintln(Output, WhiteString("white"))
294	fmt.Fprintln(Output, HiBlackString("hblack"))
295	fmt.Fprintln(Output, HiRedString("hred"))
296	fmt.Fprintln(Output, HiGreenString("hgreen"))
297	fmt.Fprintln(Output, HiYellowString("hyellow"))
298	fmt.Fprintln(Output, HiBlueString("hblue"))
299	fmt.Fprintln(Output, HiMagentaString("hmagenta"))
300	fmt.Fprintln(Output, HiCyanString("hcyan"))
301	fmt.Fprintln(Output, HiWhiteString("hwhite"))
302}
303
304func TestNoFormat(t *testing.T) {
305	fmt.Printf("%s   %%s = ", BlackString("Black"))
306	Black("%s")
307
308	fmt.Printf("%s     %%s = ", RedString("Red"))
309	Red("%s")
310
311	fmt.Printf("%s   %%s = ", GreenString("Green"))
312	Green("%s")
313
314	fmt.Printf("%s  %%s = ", YellowString("Yellow"))
315	Yellow("%s")
316
317	fmt.Printf("%s    %%s = ", BlueString("Blue"))
318	Blue("%s")
319
320	fmt.Printf("%s %%s = ", MagentaString("Magenta"))
321	Magenta("%s")
322
323	fmt.Printf("%s    %%s = ", CyanString("Cyan"))
324	Cyan("%s")
325
326	fmt.Printf("%s   %%s = ", WhiteString("White"))
327	White("%s")
328
329	fmt.Printf("%s   %%s = ", HiBlackString("HiBlack"))
330	HiBlack("%s")
331
332	fmt.Printf("%s     %%s = ", HiRedString("HiRed"))
333	HiRed("%s")
334
335	fmt.Printf("%s   %%s = ", HiGreenString("HiGreen"))
336	HiGreen("%s")
337
338	fmt.Printf("%s  %%s = ", HiYellowString("HiYellow"))
339	HiYellow("%s")
340
341	fmt.Printf("%s    %%s = ", HiBlueString("HiBlue"))
342	HiBlue("%s")
343
344	fmt.Printf("%s %%s = ", HiMagentaString("HiMagenta"))
345	HiMagenta("%s")
346
347	fmt.Printf("%s    %%s = ", HiCyanString("HiCyan"))
348	HiCyan("%s")
349
350	fmt.Printf("%s   %%s = ", HiWhiteString("HiWhite"))
351	HiWhite("%s")
352}
353
354func TestNoFormatString(t *testing.T) {
355	tests := []struct {
356		f      func(string, ...interface{}) string
357		format string
358		args   []interface{}
359		want   string
360	}{
361		{BlackString, "%s", nil, "\x1b[30m%s\x1b[0m"},
362		{RedString, "%s", nil, "\x1b[31m%s\x1b[0m"},
363		{GreenString, "%s", nil, "\x1b[32m%s\x1b[0m"},
364		{YellowString, "%s", nil, "\x1b[33m%s\x1b[0m"},
365		{BlueString, "%s", nil, "\x1b[34m%s\x1b[0m"},
366		{MagentaString, "%s", nil, "\x1b[35m%s\x1b[0m"},
367		{CyanString, "%s", nil, "\x1b[36m%s\x1b[0m"},
368		{WhiteString, "%s", nil, "\x1b[37m%s\x1b[0m"},
369		{HiBlackString, "%s", nil, "\x1b[90m%s\x1b[0m"},
370		{HiRedString, "%s", nil, "\x1b[91m%s\x1b[0m"},
371		{HiGreenString, "%s", nil, "\x1b[92m%s\x1b[0m"},
372		{HiYellowString, "%s", nil, "\x1b[93m%s\x1b[0m"},
373		{HiBlueString, "%s", nil, "\x1b[94m%s\x1b[0m"},
374		{HiMagentaString, "%s", nil, "\x1b[95m%s\x1b[0m"},
375		{HiCyanString, "%s", nil, "\x1b[96m%s\x1b[0m"},
376		{HiWhiteString, "%s", nil, "\x1b[97m%s\x1b[0m"},
377	}
378
379	for i, test := range tests {
380		s := fmt.Sprintf("%s", test.f(test.format, test.args...))
381		if s != test.want {
382			t.Errorf("[%d] want: %q, got: %q", i, test.want, s)
383		}
384	}
385}
386