1package pgs
2
3import (
4	"bytes"
5	"fmt"
6	"io/ioutil"
7	"testing"
8
9	"errors"
10
11	"github.com/stretchr/testify/assert"
12)
13
14type mockLogger struct {
15	buf *bytes.Buffer
16}
17
18func newMockLogger() *mockLogger               { return &mockLogger{&bytes.Buffer{}} }
19func (l *mockLogger) Println(v ...interface{}) { fmt.Fprintln(l.buf, v...) }
20func (l *mockLogger) Printf(format string, v ...interface{}) {
21	fmt.Fprintln(l.buf, fmt.Sprintf(format, v...))
22}
23
24func TestRootDebugger_Log(t *testing.T) {
25	t.Parallel()
26
27	l := newMockLogger()
28	rd := rootDebugger{l: l}
29	rd.Log("foo", "bar")
30	assert.Equal(t, "foo bar\n", l.buf.String())
31}
32
33func TestRootDebugger_Logf(t *testing.T) {
34	t.Parallel()
35
36	l := newMockLogger()
37	rd := rootDebugger{l: l}
38	rd.Logf("foo%s", "bar")
39	assert.Equal(t, "foobar\n", l.buf.String())
40}
41
42func TestRootDebugger_Fail(t *testing.T) {
43	t.Parallel()
44
45	var failed bool
46
47	fail := func(msgs ...interface{}) {
48		assert.Equal(t, "foobar", msgs[0])
49		failed = true
50	}
51
52	rd := rootDebugger{l: newMockLogger(), fail: fail}
53	rd.Fail("foo", "bar")
54
55	assert.True(t, failed)
56}
57
58func TestRootDebugger_Failf(t *testing.T) {
59	t.Parallel()
60
61	var failed bool
62
63	fail := func(msgs ...interface{}) {
64		assert.Equal(t, "fizz buzz", msgs[0])
65		failed = true
66	}
67
68	rd := rootDebugger{l: newMockLogger(), fail: fail}
69	rd.Failf("fizz %s", "buzz")
70
71	assert.True(t, failed)
72}
73
74func TestRootDebugger_Debug(t *testing.T) {
75	t.Parallel()
76
77	l := newMockLogger()
78	rd := rootDebugger{l: l}
79
80	rd.Debug("foo")
81	assert.Empty(t, l.buf.String())
82
83	rd.logDebugs = true
84
85	rd.Debug("bar")
86	assert.Contains(t, l.buf.String(), "bar")
87}
88
89func TestRootDebugger_Debugf(t *testing.T) {
90	t.Parallel()
91
92	l := newMockLogger()
93	rd := rootDebugger{l: l}
94
95	rd.Debug("foo")
96	assert.Empty(t, l.buf.String())
97
98	rd.logDebugs = true
99
100	rd.Debug("bar")
101	assert.Contains(t, l.buf.String(), "bar")
102}
103
104func TestRootDebugger_CheckErr(t *testing.T) {
105	t.Parallel()
106
107	e := errors.New("bad error")
108	errd := false
109
110	errfn := func(err error, msg ...interface{}) {
111		assert.Equal(t, e, err)
112		assert.Equal(t, "foo", msg[0])
113		errd = true
114	}
115
116	rd := rootDebugger{err: errfn}
117	rd.CheckErr(nil, "fizz")
118	assert.False(t, errd)
119
120	rd.CheckErr(e, "foo")
121	assert.True(t, errd)
122}
123
124func TestRootDebugger_Assert(t *testing.T) {
125	t.Parallel()
126
127	failed := false
128
129	fail := func(msgs ...interface{}) {
130		assert.Equal(t, "foo", msgs[0])
131		failed = true
132	}
133
134	rd := rootDebugger{fail: fail}
135	rd.Assert(true, "fizz")
136	assert.False(t, failed)
137
138	rd.Assert(false, "foo")
139	assert.True(t, failed)
140}
141
142func TestRootDebugger_Exit(t *testing.T) {
143	t.Parallel()
144
145	var code int
146
147	rd := rootDebugger{exit: func(c int) { code = c }}
148	rd.Exit(123)
149	assert.Equal(t, 123, code)
150}
151
152func TestRootDebugger_Push(t *testing.T) {
153	t.Parallel()
154
155	rd := rootDebugger{}
156
157	d := rd.Push("foo")
158	assert.NotNil(t, d)
159	assert.NotEqual(t, rd, d)
160}
161
162func TestRootDebugger_Pop(t *testing.T) {
163	t.Parallel()
164
165	rd := rootDebugger{}
166	assert.Panics(t, func() { rd.Pop() })
167}
168
169func TestRootDebugger_DefaultErr(t *testing.T) {
170	t.Parallel()
171
172	exited := false
173	code := 0
174	l := newMockLogger()
175	rd := rootDebugger{
176		l: l,
177		exit: func(c int) {
178			code = c
179			exited = true
180		},
181	}
182
183	rd.defaultErr(nil, "nothing")
184
185	assert.False(t, exited)
186	assert.Empty(t, l.buf.String())
187
188	rd.defaultErr(errors.New("some error"), "something")
189	assert.True(t, exited)
190	assert.Equal(t, 1, code)
191	assert.Contains(t, l.buf.String(), "something")
192}
193
194func TestRootDebugger_DefaultFail(t *testing.T) {
195	t.Parallel()
196
197	exited := false
198	code := 0
199	l := newMockLogger()
200	rd := rootDebugger{
201		l: l,
202		exit: func(c int) {
203			code = c
204			exited = true
205		},
206	}
207
208	rd.defaultFail("something")
209	assert.True(t, exited)
210	assert.Equal(t, 1, code)
211	assert.Contains(t, l.buf.String(), "something")
212}
213
214func TestPrefixedDebugger_Log(t *testing.T) {
215	t.Parallel()
216
217	l := newMockLogger()
218	d := rootDebugger{l: l}.Push("FIZZ")
219	d.Log("foo", "bar")
220	assert.Contains(t, l.buf.String(), "FIZZ")
221	assert.Contains(t, l.buf.String(), "foo bar")
222}
223
224func TestPrefixedDebugger_Logf(t *testing.T) {
225	t.Parallel()
226
227	l := newMockLogger()
228	d := rootDebugger{l: l}.Push("FIZZ")
229	d.Logf("foo%s", "bar")
230	assert.Contains(t, l.buf.String(), "FIZZ")
231	assert.Contains(t, l.buf.String(), "foobar")
232}
233
234func TestPrefixedDebugger_Fail(t *testing.T) {
235	t.Parallel()
236
237	var failed bool
238
239	fail := func(msgs ...interface{}) {
240		assert.Contains(t, msgs[0], "FIZZ")
241		assert.Contains(t, msgs[0], "foobar")
242		failed = true
243	}
244
245	d := rootDebugger{l: newMockLogger(), fail: fail}.Push("FIZZ")
246	d.Fail("foo", "bar")
247
248	assert.True(t, failed)
249}
250
251func TestPrefixedDebugger_Failf(t *testing.T) {
252	t.Parallel()
253
254	var failed bool
255
256	fail := func(msgs ...interface{}) {
257		assert.Contains(t, msgs[0], "FIZZ")
258		assert.Contains(t, msgs[0], "foo bar")
259		failed = true
260	}
261
262	d := rootDebugger{l: newMockLogger(), fail: fail}.Push("FIZZ")
263	d.Failf("foo %s", "bar")
264
265	assert.True(t, failed)
266}
267
268func TestPrefixedDebugger_Debug(t *testing.T) {
269	t.Parallel()
270
271	l := newMockLogger()
272	rd := rootDebugger{l: l}
273	d := rd.Push("FIZZ")
274
275	d.Debug("foo")
276	assert.Empty(t, l.buf.String())
277
278	rd.logDebugs = true
279	d = rd.Push("FIZZ")
280
281	d.Debug("bar")
282	assert.Contains(t, l.buf.String(), "bar")
283	assert.Contains(t, l.buf.String(), "FIZZ")
284}
285
286func TestPrefixedDebugger_Debugf(t *testing.T) {
287	t.Parallel()
288
289	l := newMockLogger()
290	rd := rootDebugger{l: l}
291	d := rd.Push("FIZZ")
292
293	d.Debugf("foo%s", "bar")
294	assert.Empty(t, l.buf.String())
295
296	rd.logDebugs = true
297	d = rd.Push("FIZZ")
298
299	d.Debugf("foo%s", "bar")
300	assert.Contains(t, l.buf.String(), "foobar")
301	assert.Contains(t, l.buf.String(), "FIZZ")
302}
303
304func TestPrefixedDebugger_CheckErr(t *testing.T) {
305	t.Parallel()
306
307	e := errors.New("bad error")
308	errd := false
309
310	errfn := func(err error, msg ...interface{}) {
311		assert.Equal(t, e, err)
312		assert.Contains(t, msg[0], "foo")
313		assert.Contains(t, msg[0], "FIZZ")
314		errd = true
315	}
316
317	d := rootDebugger{err: errfn}.Push("FIZZ")
318	d.CheckErr(nil, "fizz")
319	assert.False(t, errd)
320
321	d.CheckErr(e, "foo")
322	assert.True(t, errd)
323}
324
325func TestPrefixedDebugger_Assert(t *testing.T) {
326	t.Parallel()
327
328	failed := false
329
330	fail := func(msgs ...interface{}) {
331		assert.Contains(t, msgs[0], "FIZZ")
332		assert.Contains(t, msgs[0], "foo")
333		failed = true
334	}
335
336	d := rootDebugger{fail: fail}.Push("FIZZ")
337	d.Assert(1 == 1, "fizz")
338	assert.False(t, failed)
339
340	d.Assert(1 == 0, "foo")
341	assert.True(t, failed)
342}
343
344func TestPrefixedDebugger_Pop(t *testing.T) {
345	t.Parallel()
346
347	rd := rootDebugger{}
348	d := rd.Push("FOO")
349	assert.Equal(t, rd, d.Pop())
350}
351
352func TestPrefixedDebugger_Push(t *testing.T) {
353	t.Parallel()
354
355	l := newMockLogger()
356	rd := rootDebugger{l: l}
357	d := rd.Push("FOO").Push("BAR")
358	d.Log("fizz")
359	assert.Contains(t, l.buf.String(), "FOO")
360	assert.Contains(t, l.buf.String(), "BAR")
361}
362
363func TestPrefixedDebugger_Push_Format(t *testing.T) {
364	t.Parallel()
365
366	l := newMockLogger()
367	d := rootDebugger{l: l}.Push("foo").Push("bar")
368	d.Logf("%s", "baz")
369
370	assert.Equal(t, "[foo][bar] baz\n", l.buf.String())
371}
372
373func TestPrefixedDebugger_Exit(t *testing.T) {
374	t.Parallel()
375
376	md := InitMockDebugger()
377	d := &prefixedDebugger{parent: md}
378	d.Exit(123)
379
380	assert.True(t, md.Exited())
381	assert.Equal(t, 123, md.ExitCode())
382}
383
384func TestInitDebugger(t *testing.T) {
385	t.Parallel()
386	d := initDebugger(true, nil)
387	assert.NotNil(t, d)
388}
389
390func TestMockDebugger_Output(t *testing.T) {
391	t.Parallel()
392
393	md := InitMockDebugger()
394	md.Log("foobar")
395	b, _ := ioutil.ReadAll(md.Output())
396	assert.Equal(t, "foobar\n", string(b))
397}
398