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	defer func() {
146		NoColor = false
147	}()
148	for _, c := range testColors {
149		p := New(c.code)
150		p.Print(c.text)
151
152		line, _ := rb.ReadString('\n')
153		if line != c.text {
154			t.Errorf("Expecting %s, got '%s'\n", c.text, line)
155		}
156	}
157
158}
159
160func TestColorVisual(t *testing.T) {
161	// First Visual Test
162	Output = colorable.NewColorableStdout()
163
164	New(FgRed).Printf("red\t")
165	New(BgRed).Print("         ")
166	New(FgRed, Bold).Println(" red")
167
168	New(FgGreen).Printf("green\t")
169	New(BgGreen).Print("         ")
170	New(FgGreen, Bold).Println(" green")
171
172	New(FgYellow).Printf("yellow\t")
173	New(BgYellow).Print("         ")
174	New(FgYellow, Bold).Println(" yellow")
175
176	New(FgBlue).Printf("blue\t")
177	New(BgBlue).Print("         ")
178	New(FgBlue, Bold).Println(" blue")
179
180	New(FgMagenta).Printf("magenta\t")
181	New(BgMagenta).Print("         ")
182	New(FgMagenta, Bold).Println(" magenta")
183
184	New(FgCyan).Printf("cyan\t")
185	New(BgCyan).Print("         ")
186	New(FgCyan, Bold).Println(" cyan")
187
188	New(FgWhite).Printf("white\t")
189	New(BgWhite).Print("         ")
190	New(FgWhite, Bold).Println(" white")
191	fmt.Println("")
192
193	// Second Visual test
194	Black("black")
195	Red("red")
196	Green("green")
197	Yellow("yellow")
198	Blue("blue")
199	Magenta("magenta")
200	Cyan("cyan")
201	White("white")
202	HiBlack("hblack")
203	HiRed("hred")
204	HiGreen("hgreen")
205	HiYellow("hyellow")
206	HiBlue("hblue")
207	HiMagenta("hmagenta")
208	HiCyan("hcyan")
209	HiWhite("hwhite")
210
211	// Third visual test
212	fmt.Println()
213	Set(FgBlue)
214	fmt.Println("is this blue?")
215	Unset()
216
217	Set(FgMagenta)
218	fmt.Println("and this magenta?")
219	Unset()
220
221	// Fourth Visual test
222	fmt.Println()
223	blue := New(FgBlue).PrintlnFunc()
224	blue("blue text with custom print func")
225
226	red := New(FgRed).PrintfFunc()
227	red("red text with a printf func: %d\n", 123)
228
229	put := New(FgYellow).SprintFunc()
230	warn := New(FgRed).SprintFunc()
231
232	fmt.Fprintf(Output, "this is a %s and this is %s.\n", put("warning"), warn("error"))
233
234	info := New(FgWhite, BgGreen).SprintFunc()
235	fmt.Fprintf(Output, "this %s rocks!\n", info("package"))
236
237	notice := New(FgBlue).FprintFunc()
238	notice(os.Stderr, "just a blue notice to stderr")
239
240	// Fifth Visual Test
241	fmt.Println()
242
243	fmt.Fprintln(Output, BlackString("black"))
244	fmt.Fprintln(Output, RedString("red"))
245	fmt.Fprintln(Output, GreenString("green"))
246	fmt.Fprintln(Output, YellowString("yellow"))
247	fmt.Fprintln(Output, BlueString("blue"))
248	fmt.Fprintln(Output, MagentaString("magenta"))
249	fmt.Fprintln(Output, CyanString("cyan"))
250	fmt.Fprintln(Output, WhiteString("white"))
251	fmt.Fprintln(Output, HiBlackString("hblack"))
252	fmt.Fprintln(Output, HiRedString("hred"))
253	fmt.Fprintln(Output, HiGreenString("hgreen"))
254	fmt.Fprintln(Output, HiYellowString("hyellow"))
255	fmt.Fprintln(Output, HiBlueString("hblue"))
256	fmt.Fprintln(Output, HiMagentaString("hmagenta"))
257	fmt.Fprintln(Output, HiCyanString("hcyan"))
258	fmt.Fprintln(Output, HiWhiteString("hwhite"))
259}
260
261func TestNoFormat(t *testing.T) {
262	fmt.Printf("%s   %%s = ", BlackString("Black"))
263	Black("%s")
264
265	fmt.Printf("%s     %%s = ", RedString("Red"))
266	Red("%s")
267
268	fmt.Printf("%s   %%s = ", GreenString("Green"))
269	Green("%s")
270
271	fmt.Printf("%s  %%s = ", YellowString("Yellow"))
272	Yellow("%s")
273
274	fmt.Printf("%s    %%s = ", BlueString("Blue"))
275	Blue("%s")
276
277	fmt.Printf("%s %%s = ", MagentaString("Magenta"))
278	Magenta("%s")
279
280	fmt.Printf("%s    %%s = ", CyanString("Cyan"))
281	Cyan("%s")
282
283	fmt.Printf("%s   %%s = ", WhiteString("White"))
284	White("%s")
285
286	fmt.Printf("%s   %%s = ", HiBlackString("HiBlack"))
287	HiBlack("%s")
288
289	fmt.Printf("%s     %%s = ", HiRedString("HiRed"))
290	HiRed("%s")
291
292	fmt.Printf("%s   %%s = ", HiGreenString("HiGreen"))
293	HiGreen("%s")
294
295	fmt.Printf("%s  %%s = ", HiYellowString("HiYellow"))
296	HiYellow("%s")
297
298	fmt.Printf("%s    %%s = ", HiBlueString("HiBlue"))
299	HiBlue("%s")
300
301	fmt.Printf("%s %%s = ", HiMagentaString("HiMagenta"))
302	HiMagenta("%s")
303
304	fmt.Printf("%s    %%s = ", HiCyanString("HiCyan"))
305	HiCyan("%s")
306
307	fmt.Printf("%s   %%s = ", HiWhiteString("HiWhite"))
308	HiWhite("%s")
309}
310
311func TestNoFormatString(t *testing.T) {
312	tests := []struct {
313		f      func(string, ...interface{}) string
314		format string
315		args   []interface{}
316		want   string
317	}{
318		{BlackString, "%s", nil, "\x1b[30m%s\x1b[0m"},
319		{RedString, "%s", nil, "\x1b[31m%s\x1b[0m"},
320		{GreenString, "%s", nil, "\x1b[32m%s\x1b[0m"},
321		{YellowString, "%s", nil, "\x1b[33m%s\x1b[0m"},
322		{BlueString, "%s", nil, "\x1b[34m%s\x1b[0m"},
323		{MagentaString, "%s", nil, "\x1b[35m%s\x1b[0m"},
324		{CyanString, "%s", nil, "\x1b[36m%s\x1b[0m"},
325		{WhiteString, "%s", nil, "\x1b[37m%s\x1b[0m"},
326		{HiBlackString, "%s", nil, "\x1b[90m%s\x1b[0m"},
327		{HiRedString, "%s", nil, "\x1b[91m%s\x1b[0m"},
328		{HiGreenString, "%s", nil, "\x1b[92m%s\x1b[0m"},
329		{HiYellowString, "%s", nil, "\x1b[93m%s\x1b[0m"},
330		{HiBlueString, "%s", nil, "\x1b[94m%s\x1b[0m"},
331		{HiMagentaString, "%s", nil, "\x1b[95m%s\x1b[0m"},
332		{HiCyanString, "%s", nil, "\x1b[96m%s\x1b[0m"},
333		{HiWhiteString, "%s", nil, "\x1b[97m%s\x1b[0m"},
334	}
335
336	for i, test := range tests {
337		s := fmt.Sprintf("%s", test.f(test.format, test.args...))
338		if s != test.want {
339			t.Errorf("[%d] want: %q, got: %q", i, test.want, s)
340		}
341	}
342}
343