1
2
3
4
5
6
7 package assert
8
9 import (
10 "bufio"
11 "bytes"
12 "errors"
13 "fmt"
14 "math"
15 "reflect"
16 "runtime"
17 "strings"
18 "testing"
19 "time"
20 )
21
22
23 type AssertionTesterInterface interface {
24 TestMethod()
25 }
26
27
28 type AssertionTesterConformingObject struct {
29 }
30
31 func (a *AssertionTesterConformingObject) TestMethod() {
32 }
33
34
35 type AssertionTesterNonConformingObject struct {
36 }
37
38 func TestObjectsAreEqual(t *testing.T) {
39 cases := []struct {
40 expected interface{}
41 actual interface{}
42 result bool
43 }{
44
45 {"Hello World", "Hello World", true},
46 {123, 123, true},
47 {123.5, 123.5, true},
48 {[]byte("Hello World"), []byte("Hello World"), true},
49 {nil, nil, true},
50
51
52 {map[int]int{5: 10}, map[int]int{10: 20}, false},
53 {'x', "x", false},
54 {"x", 'x', false},
55 {0, 0.1, false},
56 {0.1, 0, false},
57 {time.Now, time.Now, false},
58 {func() {}, func() {}, false},
59 {uint32(10), int32(10), false},
60 }
61
62 for _, c := range cases {
63 t.Run(fmt.Sprintf("ObjectsAreEqual(%#v, %#v)", c.expected, c.actual), func(t *testing.T) {
64 res := ObjectsAreEqual(c.expected, c.actual)
65
66 if res != c.result {
67 t.Errorf("ObjectsAreEqual(%#v, %#v) should return %#v", c.expected, c.actual, c.result)
68 }
69
70 })
71 }
72
73
74 if !ObjectsAreEqualValues(uint32(10), int32(10)) {
75 t.Error("ObjectsAreEqualValues should return true")
76 }
77 if ObjectsAreEqualValues(0, nil) {
78 t.Fail()
79 }
80 if ObjectsAreEqualValues(nil, 0) {
81 t.Fail()
82 }
83
84 }
85
86 func TestIsType(t *testing.T) {
87
88 mockT := new(testing.T)
89
90 if !IsType(mockT, new(AssertionTesterConformingObject), new(AssertionTesterConformingObject)) {
91 t.Error("IsType should return true: AssertionTesterConformingObject is the same type as AssertionTesterConformingObject")
92 }
93 if IsType(mockT, new(AssertionTesterConformingObject), new(AssertionTesterNonConformingObject)) {
94 t.Error("IsType should return false: AssertionTesterConformingObject is not the same type as AssertionTesterNonConformingObject")
95 }
96
97 }
98
99 func TestEqual(t *testing.T) {
100 type myType string
101
102 mockT := new(testing.T)
103 var m map[string]interface{}
104
105 cases := []struct {
106 expected interface{}
107 actual interface{}
108 result bool
109 remark string
110 }{
111 {"Hello World", "Hello World", true, ""},
112 {123, 123, true, ""},
113 {123.5, 123.5, true, ""},
114 {[]byte("Hello World"), []byte("Hello World"), true, ""},
115 {nil, nil, true, ""},
116 {int32(123), int32(123), true, ""},
117 {uint64(123), uint64(123), true, ""},
118 {myType("1"), myType("1"), true, ""},
119 {&struct{}{}, &struct{}{}, true, "pointer equality is based on equality of underlying value"},
120
121
122 {m["bar"], "something", false, ""},
123 {myType("1"), myType("2"), false, ""},
124
125
126 {10, uint(10), false, ""},
127 }
128
129 for _, c := range cases {
130 t.Run(fmt.Sprintf("Equal(%#v, %#v)", c.expected, c.actual), func(t *testing.T) {
131 res := Equal(mockT, c.expected, c.actual)
132
133 if res != c.result {
134 t.Errorf("Equal(%#v, %#v) should return %#v: %s", c.expected, c.actual, c.result, c.remark)
135 }
136 })
137 }
138 }
139
140
141
142 type bufferT struct {
143 buf bytes.Buffer
144 }
145
146 func (t *bufferT) Errorf(format string, args ...interface{}) {
147
148 decorate := func(s string) string {
149 _, file, line, ok := runtime.Caller(3)
150 if ok {
151
152 if index := strings.LastIndex(file, "/"); index >= 0 {
153 file = file[index+1:]
154 } else if index = strings.LastIndex(file, "\\"); index >= 0 {
155 file = file[index+1:]
156 }
157 } else {
158 file = "???"
159 line = 1
160 }
161 buf := new(bytes.Buffer)
162
163 buf.WriteByte('\t')
164 fmt.Fprintf(buf, "%s:%d: ", file, line)
165 lines := strings.Split(s, "\n")
166 if l := len(lines); l > 1 && lines[l-1] == "" {
167 lines = lines[:l-1]
168 }
169 for i, line := range lines {
170 if i > 0 {
171
172 buf.WriteString("\n\t\t")
173 }
174 buf.WriteString(line)
175 }
176 buf.WriteByte('\n')
177 return buf.String()
178 }
179 t.buf.WriteString(decorate(fmt.Sprintf(format, args...)))
180 }
181
182 func TestStringEqual(_ *testing.T) {
183 for _, currCase := range []struct {
184 equalWant string
185 equalGot string
186 msgAndArgs []interface{}
187 want string
188 }{
189 {equalWant: "hi, \nmy name is", equalGot: "what,\nmy name is", want: "\tassertions.go:\\d+: \n\t+Error Trace:\t\n\t+Error:\\s+Not equal:\\s+\n\\s+expected: \"hi, \\\\nmy name is\"\n\\s+actual\\s+: \"what,\\\\nmy name is\"\n\\s+Diff:\n\\s+-+ Expected\n\\s+\\++ Actual\n\\s+@@ -1,2 \\+1,2 @@\n\\s+-hi, \n\\s+\\+what,\n\\s+my name is"},
190 } {
191 mockT := &bufferT{}
192 Equal(mockT, currCase.equalWant, currCase.equalGot, currCase.msgAndArgs...)
193 }
194 }
195
196 func TestEqualFormatting(_ *testing.T) {
197 for _, currCase := range []struct {
198 equalWant string
199 equalGot string
200 msgAndArgs []interface{}
201 want string
202 }{
203 {equalWant: "want", equalGot: "got", want: "\tassertions.go:\\d+: \n\t+Error Trace:\t\n\t+Error:\\s+Not equal:\\s+\n\\s+expected: \"want\"\n\\s+actual\\s+: \"got\"\n\\s+Diff:\n\\s+-+ Expected\n\\s+\\++ Actual\n\\s+@@ -1 \\+1 @@\n\\s+-want\n\\s+\\+got\n"},
204 {equalWant: "want", equalGot: "got", msgAndArgs: []interface{}{"hello, %v!", "world"}, want: "\tassertions.go:[0-9]+: \n\t+Error Trace:\t\n\t+Error:\\s+Not equal:\\s+\n\\s+expected: \"want\"\n\\s+actual\\s+: \"got\"\n\\s+Diff:\n\\s+-+ Expected\n\\s+\\++ Actual\n\\s+@@ -1 \\+1 @@\n\\s+-want\n\\s+\\+got\n\\s+Messages:\\s+hello, world!\n"},
205 {equalWant: "want", equalGot: "got", msgAndArgs: []interface{}{123}, want: "\tassertions.go:[0-9]+: \n\t+Error Trace:\t\n\t+Error:\\s+Not equal:\\s+\n\\s+expected: \"want\"\n\\s+actual\\s+: \"got\"\n\\s+Diff:\n\\s+-+ Expected\n\\s+\\++ Actual\n\\s+@@ -1 \\+1 @@\n\\s+-want\n\\s+\\+got\n\\s+Messages:\\s+123\n"},
206 {equalWant: "want", equalGot: "got", msgAndArgs: []interface{}{struct{ a string }{"hello"}}, want: "\tassertions.go:[0-9]+: \n\t+Error Trace:\t\n\t+Error:\\s+Not equal:\\s+\n\\s+expected: \"want\"\n\\s+actual\\s+: \"got\"\n\\s+Diff:\n\\s+-+ Expected\n\\s+\\++ Actual\n\\s+@@ -1 \\+1 @@\n\\s+-want\n\\s+\\+got\n\\s+Messages:\\s+{a:hello}\n"},
207 } {
208 mockT := &bufferT{}
209 Equal(mockT, currCase.equalWant, currCase.equalGot, currCase.msgAndArgs...)
210 }
211 }
212
213 func TestFormatUnequalValues(t *testing.T) {
214 expected, actual := formatUnequalValues("foo", "bar")
215 Equal(t, `"foo"`, expected, "value should not include type")
216 Equal(t, `"bar"`, actual, "value should not include type")
217
218 expected, actual = formatUnequalValues(123, 123)
219 Equal(t, `123`, expected, "value should not include type")
220 Equal(t, `123`, actual, "value should not include type")
221
222 expected, actual = formatUnequalValues(int64(123), int32(123))
223 Equal(t, `int64(123)`, expected, "value should include type")
224 Equal(t, `int32(123)`, actual, "value should include type")
225
226 expected, actual = formatUnequalValues(int64(123), nil)
227 Equal(t, `int64(123)`, expected, "value should include type")
228 Equal(t, `<nil>(<nil>)`, actual, "value should include type")
229
230 type testStructType struct {
231 Val string
232 }
233
234 expected, actual = formatUnequalValues(&testStructType{Val: "test"}, &testStructType{Val: "test"})
235 Equal(t, `&assert.testStructType{Val:"test"}`, expected, "value should not include type annotation")
236 Equal(t, `&assert.testStructType{Val:"test"}`, actual, "value should not include type annotation")
237 }
238
239 func TestNotNil(t *testing.T) {
240
241 mockT := new(testing.T)
242
243 if !NotNil(mockT, new(AssertionTesterConformingObject)) {
244 t.Error("NotNil should return true: object is not nil")
245 }
246 if NotNil(mockT, nil) {
247 t.Error("NotNil should return false: object is nil")
248 }
249 if NotNil(mockT, (*struct{})(nil)) {
250 t.Error("NotNil should return false: object is (*struct{})(nil)")
251 }
252
253 }
254
255 func TestNil(t *testing.T) {
256
257 mockT := new(testing.T)
258
259 if !Nil(mockT, nil) {
260 t.Error("Nil should return true: object is nil")
261 }
262 if !Nil(mockT, (*struct{})(nil)) {
263 t.Error("Nil should return true: object is (*struct{})(nil)")
264 }
265 if Nil(mockT, new(AssertionTesterConformingObject)) {
266 t.Error("Nil should return false: object is not nil")
267 }
268
269 }
270
271 func TestTrue(t *testing.T) {
272
273 mockT := new(testing.T)
274
275 if !True(mockT, true) {
276 t.Error("True should return true")
277 }
278 if True(mockT, false) {
279 t.Error("True should return false")
280 }
281
282 }
283
284 func TestFalse(t *testing.T) {
285
286 mockT := new(testing.T)
287
288 if !False(mockT, false) {
289 t.Error("False should return true")
290 }
291 if False(mockT, true) {
292 t.Error("False should return false")
293 }
294
295 }
296
297 func TestNotEqual(t *testing.T) {
298
299 mockT := new(testing.T)
300
301 cases := []struct {
302 expected interface{}
303 actual interface{}
304 result bool
305 }{
306
307 {"Hello World", "Hello World!", true},
308 {123, 1234, true},
309 {123.5, 123.55, true},
310 {[]byte("Hello World"), []byte("Hello World!"), true},
311 {nil, new(AssertionTesterConformingObject), true},
312
313
314 {nil, nil, false},
315 {"Hello World", "Hello World", false},
316 {123, 123, false},
317 {123.5, 123.5, false},
318 {[]byte("Hello World"), []byte("Hello World"), false},
319 {new(AssertionTesterConformingObject), new(AssertionTesterConformingObject), false},
320 {&struct{}{}, &struct{}{}, false},
321 {func() int { return 23 }, func() int { return 24 }, false},
322
323 {int(10), uint(10), true},
324 }
325
326 for _, c := range cases {
327 t.Run(fmt.Sprintf("NotEqual(%#v, %#v)", c.expected, c.actual), func(t *testing.T) {
328 res := NotEqual(mockT, c.expected, c.actual)
329
330 if res != c.result {
331 t.Errorf("NotEqual(%#v, %#v) should return %#v", c.expected, c.actual, c.result)
332 }
333 })
334 }
335 }
336
337 func TestNotEqualValues(t *testing.T) {
338 mockT := new(testing.T)
339
340 cases := []struct {
341 expected interface{}
342 actual interface{}
343 result bool
344 }{
345
346 {"Hello World", "Hello World!", true},
347 {123, 1234, true},
348 {123.5, 123.55, true},
349 {[]byte("Hello World"), []byte("Hello World!"), true},
350 {nil, new(AssertionTesterConformingObject), true},
351
352
353 {nil, nil, false},
354 {"Hello World", "Hello World", false},
355 {123, 123, false},
356 {123.5, 123.5, false},
357 {[]byte("Hello World"), []byte("Hello World"), false},
358 {new(AssertionTesterConformingObject), new(AssertionTesterConformingObject), false},
359 {&struct{}{}, &struct{}{}, false},
360
361
362 {func() int { return 23 }, func() int { return 24 }, true},
363 {int(10), int(11), true},
364 {int(10), uint(10), false},
365
366 {struct{}{}, struct{}{}, false},
367 }
368
369 for _, c := range cases {
370 t.Run(fmt.Sprintf("NotEqualValues(%#v, %#v)", c.expected, c.actual), func(t *testing.T) {
371 res := NotEqualValues(mockT, c.expected, c.actual)
372
373 if res != c.result {
374 t.Errorf("NotEqualValues(%#v, %#v) should return %#v", c.expected, c.actual, c.result)
375 }
376 })
377 }
378 }
379
380 func TestContainsNotContains(t *testing.T) {
381
382 type A struct {
383 Name, Value string
384 }
385 list := []string{"Foo", "Bar"}
386
387 complexList := []*A{
388 {"b", "c"},
389 {"d", "e"},
390 {"g", "h"},
391 {"j", "k"},
392 }
393 simpleMap := map[interface{}]interface{}{"Foo": "Bar"}
394 var zeroMap map[interface{}]interface{}
395
396 cases := []struct {
397 expected interface{}
398 actual interface{}
399 result bool
400 }{
401 {"Hello World", "Hello", true},
402 {"Hello World", "Salut", false},
403 {list, "Bar", true},
404 {list, "Salut", false},
405 {complexList, &A{"g", "h"}, true},
406 {complexList, &A{"g", "e"}, false},
407 {simpleMap, "Foo", true},
408 {simpleMap, "Bar", false},
409 {zeroMap, "Bar", false},
410 }
411
412 for _, c := range cases {
413 t.Run(fmt.Sprintf("Contains(%#v, %#v)", c.expected, c.actual), func(t *testing.T) {
414 mockT := new(testing.T)
415 res := Contains(mockT, c.expected, c.actual)
416
417 if res != c.result {
418 if res {
419 t.Errorf("Contains(%#v, %#v) should return true:\n\t%#v contains %#v", c.expected, c.actual, c.expected, c.actual)
420 } else {
421 t.Errorf("Contains(%#v, %#v) should return false:\n\t%#v does not contain %#v", c.expected, c.actual, c.expected, c.actual)
422 }
423 }
424 })
425 }
426
427 for _, c := range cases {
428 t.Run(fmt.Sprintf("NotContains(%#v, %#v)", c.expected, c.actual), func(t *testing.T) {
429 mockT := new(testing.T)
430 res := NotContains(mockT, c.expected, c.actual)
431
432
433 if res == Contains(mockT, c.expected, c.actual) {
434 if res {
435 t.Errorf("NotContains(%#v, %#v) should return true:\n\t%#v does not contains %#v", c.expected, c.actual, c.expected, c.actual)
436 } else {
437 t.Errorf("NotContains(%#v, %#v) should return false:\n\t%#v contains %#v", c.expected, c.actual, c.expected, c.actual)
438 }
439 }
440 })
441 }
442 }
443
444 func TestContainsFailMessage(t *testing.T) {
445
446 mockT := new(mockTestingT)
447
448 Contains(mockT, "Hello World", errors.New("Hello"))
449 expectedFail := "\"Hello World\" does not contain &errors.errorString{s:\"Hello\"}"
450 actualFail := mockT.errorString()
451 if !strings.Contains(actualFail, expectedFail) {
452 t.Errorf("Contains failure should include %q but was %q", expectedFail, actualFail)
453 }
454 }
455
456 func TestContainsNotContainsOnNilValue(t *testing.T) {
457 mockT := new(mockTestingT)
458
459 Contains(mockT, nil, "key")
460 expectedFail := "<nil> could not be applied builtin len()"
461 actualFail := mockT.errorString()
462 if !strings.Contains(actualFail, expectedFail) {
463 t.Errorf("Contains failure should include %q but was %q", expectedFail, actualFail)
464 }
465
466 NotContains(mockT, nil, "key")
467 if !strings.Contains(actualFail, expectedFail) {
468 t.Errorf("Contains failure should include %q but was %q", expectedFail, actualFail)
469 }
470 }
471
472 func Test_containsElement(t *testing.T) {
473
474 list1 := []string{"Foo", "Bar"}
475 list2 := []int{1, 2}
476 simpleMap := map[interface{}]interface{}{"Foo": "Bar"}
477
478 ok, found := containsElement("Hello World", "World")
479 True(t, ok)
480 True(t, found)
481
482 ok, found = containsElement(list1, "Foo")
483 True(t, ok)
484 True(t, found)
485
486 ok, found = containsElement(list1, "Bar")
487 True(t, ok)
488 True(t, found)
489
490 ok, found = containsElement(list2, 1)
491 True(t, ok)
492 True(t, found)
493
494 ok, found = containsElement(list2, 2)
495 True(t, ok)
496 True(t, found)
497
498 ok, found = containsElement(list1, "Foo!")
499 True(t, ok)
500 False(t, found)
501
502 ok, found = containsElement(list2, 3)
503 True(t, ok)
504 False(t, found)
505
506 ok, found = containsElement(list2, "1")
507 True(t, ok)
508 False(t, found)
509
510 ok, found = containsElement(simpleMap, "Foo")
511 True(t, ok)
512 True(t, found)
513
514 ok, found = containsElement(simpleMap, "Bar")
515 True(t, ok)
516 False(t, found)
517
518 ok, found = containsElement(1433, "1")
519 False(t, ok)
520 False(t, found)
521 }
522
523 func TestElementsMatch(t *testing.T) {
524 mockT := new(testing.T)
525
526 cases := []struct {
527 expected interface{}
528 actual interface{}
529 result bool
530 }{
531
532 {nil, nil, true},
533
534 {nil, nil, true},
535 {[]int{}, []int{}, true},
536 {[]int{1}, []int{1}, true},
537 {[]int{1, 1}, []int{1, 1}, true},
538 {[]int{1, 2}, []int{1, 2}, true},
539 {[]int{1, 2}, []int{2, 1}, true},
540 {[2]int{1, 2}, [2]int{2, 1}, true},
541 {[]string{"hello", "world"}, []string{"world", "hello"}, true},
542 {[]string{"hello", "hello"}, []string{"hello", "hello"}, true},
543 {[]string{"hello", "hello", "world"}, []string{"hello", "world", "hello"}, true},
544 {[3]string{"hello", "hello", "world"}, [3]string{"hello", "world", "hello"}, true},
545 {[]int{}, nil, true},
546
547
548 {[]int{1}, []int{1, 1}, false},
549 {[]int{1, 2}, []int{2, 2}, false},
550 {[]string{"hello", "hello"}, []string{"hello"}, false},
551 }
552
553 for _, c := range cases {
554 t.Run(fmt.Sprintf("ElementsMatch(%#v, %#v)", c.expected, c.actual), func(t *testing.T) {
555 res := ElementsMatch(mockT, c.actual, c.expected)
556
557 if res != c.result {
558 t.Errorf("ElementsMatch(%#v, %#v) should return %v", c.actual, c.expected, c.result)
559 }
560 })
561 }
562 }
563
564 func TestDiffLists(t *testing.T) {
565 tests := []struct {
566 name string
567 listA interface{}
568 listB interface{}
569 extraA []interface{}
570 extraB []interface{}
571 }{
572 {
573 name: "equal empty",
574 listA: []string{},
575 listB: []string{},
576 extraA: nil,
577 extraB: nil,
578 },
579 {
580 name: "equal same order",
581 listA: []string{"hello", "world"},
582 listB: []string{"hello", "world"},
583 extraA: nil,
584 extraB: nil,
585 },
586 {
587 name: "equal different order",
588 listA: []string{"hello", "world"},
589 listB: []string{"world", "hello"},
590 extraA: nil,
591 extraB: nil,
592 },
593 {
594 name: "extra A",
595 listA: []string{"hello", "hello", "world"},
596 listB: []string{"hello", "world"},
597 extraA: []interface{}{"hello"},
598 extraB: nil,
599 },
600 {
601 name: "extra A twice",
602 listA: []string{"hello", "hello", "hello", "world"},
603 listB: []string{"hello", "world"},
604 extraA: []interface{}{"hello", "hello"},
605 extraB: nil,
606 },
607 {
608 name: "extra B",
609 listA: []string{"hello", "world"},
610 listB: []string{"hello", "hello", "world"},
611 extraA: nil,
612 extraB: []interface{}{"hello"},
613 },
614 {
615 name: "extra B twice",
616 listA: []string{"hello", "world"},
617 listB: []string{"hello", "hello", "world", "hello"},
618 extraA: nil,
619 extraB: []interface{}{"hello", "hello"},
620 },
621 {
622 name: "integers 1",
623 listA: []int{1, 2, 3, 4, 5},
624 listB: []int{5, 4, 3, 2, 1},
625 extraA: nil,
626 extraB: nil,
627 },
628 {
629 name: "integers 2",
630 listA: []int{1, 2, 1, 2, 1},
631 listB: []int{2, 1, 2, 1, 2},
632 extraA: []interface{}{1},
633 extraB: []interface{}{2},
634 },
635 }
636 for _, test := range tests {
637 test := test
638 t.Run(test.name, func(t *testing.T) {
639 actualExtraA, actualExtraB := diffLists(test.listA, test.listB)
640 Equal(t, test.extraA, actualExtraA, "extra A does not match for listA=%v listB=%v",
641 test.listA, test.listB)
642 Equal(t, test.extraB, actualExtraB, "extra B does not match for listA=%v listB=%v",
643 test.listA, test.listB)
644 })
645 }
646 }
647
648 func TestNoError(t *testing.T) {
649
650 mockT := new(testing.T)
651
652
653 var err error
654
655 True(t, NoError(mockT, err), "NoError should return True for nil arg")
656
657
658 err = errors.New("some error")
659
660 False(t, NoError(mockT, err), "NoError with error should return False")
661
662
663 err = func() error {
664 var err *customError
665 return err
666 }()
667
668 if err == nil {
669 t.Errorf("Error should be nil due to empty interface: %s", err)
670 }
671
672 False(t, NoError(mockT, err), "NoError should fail with empty error interface")
673 }
674
675 type customError struct{}
676
677 func (*customError) Error() string { return "fail" }
678
679 func TestError(t *testing.T) {
680
681 mockT := new(testing.T)
682
683
684 var err error
685
686 False(t, Error(mockT, err), "Error should return False for nil arg")
687
688
689 err = errors.New("some error")
690
691 True(t, Error(mockT, err), "Error with error should return True")
692
693
694 True(t, Errorf(mockT, err, "example with %s", "formatted message"), "Errorf with error should return True")
695
696
697 err = func() error {
698 var err *customError
699 return err
700 }()
701
702 if err == nil {
703 t.Errorf("Error should be nil due to empty interface: %s", err)
704 }
705
706 True(t, Error(mockT, err), "Error should pass with empty error interface")
707 }
708
709 func TestEqualError(t *testing.T) {
710 mockT := new(testing.T)
711
712
713 var err error
714 False(t, EqualError(mockT, err, ""),
715 "EqualError should return false for nil arg")
716
717
718 err = errors.New("some error")
719 False(t, EqualError(mockT, err, "Not some error"),
720 "EqualError should return false for different error string")
721 True(t, EqualError(mockT, err, "some error"),
722 "EqualError should return true")
723 }
724
725 func TestErrorContains(t *testing.T) {
726 mockT := new(testing.T)
727
728
729 var err error
730 False(t, ErrorContains(mockT, err, ""),
731 "ErrorContains should return false for nil arg")
732
733
734 err = errors.New("some error: another error")
735 False(t, ErrorContains(mockT, err, "bad error"),
736 "ErrorContains should return false for different error string")
737 True(t, ErrorContains(mockT, err, "some error"),
738 "ErrorContains should return true")
739 True(t, ErrorContains(mockT, err, "another error"),
740 "ErrorContains should return true")
741 }
742
743 func Test_isEmpty(t *testing.T) {
744
745 chWithValue := make(chan struct{}, 1)
746 chWithValue <- struct{}{}
747
748 True(t, isEmpty(""))
749 True(t, isEmpty(nil))
750 True(t, isEmpty([]string{}))
751 True(t, isEmpty(0))
752 True(t, isEmpty(int32(0)))
753 True(t, isEmpty(int64(0)))
754 True(t, isEmpty(false))
755 True(t, isEmpty(map[string]string{}))
756 True(t, isEmpty(new(time.Time)))
757 True(t, isEmpty(time.Time{}))
758 True(t, isEmpty(make(chan struct{})))
759 True(t, isEmpty([1]int{}))
760 False(t, isEmpty("something"))
761 False(t, isEmpty(errors.New("something")))
762 False(t, isEmpty([]string{"something"}))
763 False(t, isEmpty(1))
764 False(t, isEmpty(true))
765 False(t, isEmpty(map[string]string{"Hello": "World"}))
766 False(t, isEmpty(chWithValue))
767 False(t, isEmpty([1]int{42}))
768 }
769
770 func Test_getLen(t *testing.T) {
771 falseCases := []interface{}{
772 nil,
773 0,
774 true,
775 false,
776 'A',
777 struct{}{},
778 }
779 for _, v := range falseCases {
780 ok, l := getLen(v)
781 False(t, ok, "Expected getLen fail to get length of %#v", v)
782 Equal(t, 0, l, "getLen should return 0 for %#v", v)
783 }
784
785 ch := make(chan int, 5)
786 ch <- 1
787 ch <- 2
788 ch <- 3
789 trueCases := []struct {
790 v interface{}
791 l int
792 }{
793 {[]int{1, 2, 3}, 3},
794 {[...]int{1, 2, 3}, 3},
795 {"ABC", 3},
796 {map[int]int{1: 2, 2: 4, 3: 6}, 3},
797 {ch, 3},
798
799 {[]int{}, 0},
800 {map[int]int{}, 0},
801 {make(chan int), 0},
802
803 {[]int(nil), 0},
804 {map[int]int(nil), 0},
805 {(chan int)(nil), 0},
806 }
807
808 for _, c := range trueCases {
809 ok, l := getLen(c.v)
810 True(t, ok, "Expected getLen success to get length of %#v", c.v)
811 Equal(t, c.l, l)
812 }
813 }
814
815 func TestLen(t *testing.T) {
816 mockT := new(testing.T)
817
818 False(t, Len(mockT, nil, 0), "nil does not have length")
819 False(t, Len(mockT, 0, 0), "int does not have length")
820 False(t, Len(mockT, true, 0), "true does not have length")
821 False(t, Len(mockT, false, 0), "false does not have length")
822 False(t, Len(mockT, 'A', 0), "Rune does not have length")
823 False(t, Len(mockT, struct{}{}, 0), "Struct does not have length")
824
825 ch := make(chan int, 5)
826 ch <- 1
827 ch <- 2
828 ch <- 3
829
830 cases := []struct {
831 v interface{}
832 l int
833 }{
834 {[]int{1, 2, 3}, 3},
835 {[...]int{1, 2, 3}, 3},
836 {"ABC", 3},
837 {map[int]int{1: 2, 2: 4, 3: 6}, 3},
838 {ch, 3},
839
840 {[]int{}, 0},
841 {map[int]int{}, 0},
842 {make(chan int), 0},
843
844 {[]int(nil), 0},
845 {map[int]int(nil), 0},
846 {(chan int)(nil), 0},
847 }
848
849 for _, c := range cases {
850 True(t, Len(mockT, c.v, c.l), "%#v have %d items", c.v, c.l)
851 }
852
853 cases = []struct {
854 v interface{}
855 l int
856 }{
857 {[]int{1, 2, 3}, 4},
858 {[...]int{1, 2, 3}, 2},
859 {"ABC", 2},
860 {map[int]int{1: 2, 2: 4, 3: 6}, 4},
861 {ch, 2},
862
863 {[]int{}, 1},
864 {map[int]int{}, 1},
865 {make(chan int), 1},
866
867 {[]int(nil), 1},
868 {map[int]int(nil), 1},
869 {(chan int)(nil), 1},
870 }
871
872 for _, c := range cases {
873 False(t, Len(mockT, c.v, c.l), "%#v have %d items", c.v, c.l)
874 }
875 }
876
877 func TestWithinDuration(t *testing.T) {
878
879 mockT := new(testing.T)
880 a := time.Now()
881 b := a.Add(10 * time.Second)
882
883 True(t, WithinDuration(mockT, a, b, 10*time.Second), "A 10s difference is within a 10s time difference")
884 True(t, WithinDuration(mockT, b, a, 10*time.Second), "A 10s difference is within a 10s time difference")
885
886 False(t, WithinDuration(mockT, a, b, 9*time.Second), "A 10s difference is not within a 9s time difference")
887 False(t, WithinDuration(mockT, b, a, 9*time.Second), "A 10s difference is not within a 9s time difference")
888
889 False(t, WithinDuration(mockT, a, b, -9*time.Second), "A 10s difference is not within a 9s time difference")
890 False(t, WithinDuration(mockT, b, a, -9*time.Second), "A 10s difference is not within a 9s time difference")
891
892 False(t, WithinDuration(mockT, a, b, -11*time.Second), "A 10s difference is not within a 9s time difference")
893 False(t, WithinDuration(mockT, b, a, -11*time.Second), "A 10s difference is not within a 9s time difference")
894 }
895
896 func TestInDelta(t *testing.T) {
897 mockT := new(testing.T)
898
899 True(t, InDelta(mockT, 1.001, 1, 0.01), "|1.001 - 1| <= 0.01")
900 True(t, InDelta(mockT, 1, 1.001, 0.01), "|1 - 1.001| <= 0.01")
901 True(t, InDelta(mockT, 1, 2, 1), "|1 - 2| <= 1")
902 False(t, InDelta(mockT, 1, 2, 0.5), "Expected |1 - 2| <= 0.5 to fail")
903 False(t, InDelta(mockT, 2, 1, 0.5), "Expected |2 - 1| <= 0.5 to fail")
904 False(t, InDelta(mockT, "", nil, 1), "Expected non numerals to fail")
905 False(t, InDelta(mockT, 42, math.NaN(), 0.01), "Expected NaN for actual to fail")
906 False(t, InDelta(mockT, math.NaN(), 42, 0.01), "Expected NaN for expected to fail")
907 True(t, InDelta(mockT, math.NaN(), math.NaN(), 0.01), "Expected NaN for both to pass")
908
909 cases := []struct {
910 a, b interface{}
911 delta float64
912 }{
913 {uint(2), uint(1), 1},
914 {uint8(2), uint8(1), 1},
915 {uint16(2), uint16(1), 1},
916 {uint32(2), uint32(1), 1},
917 {uint64(2), uint64(1), 1},
918
919 {int(2), int(1), 1},
920 {int8(2), int8(1), 1},
921 {int16(2), int16(1), 1},
922 {int32(2), int32(1), 1},
923 {int64(2), int64(1), 1},
924
925 {float32(2), float32(1), 1},
926 {float64(2), float64(1), 1},
927 }
928
929 for _, tc := range cases {
930 True(t, InDelta(mockT, tc.a, tc.b, tc.delta), "Expected |%V - %V| <= %v", tc.a, tc.b, tc.delta)
931 }
932 }
933
934 type diffTestingStruct struct {
935 A string
936 B int
937 }
938
939 func (d *diffTestingStruct) String() string {
940 return d.A
941 }
942
943 func TestDiff(t *testing.T) {
944 expected := `
945
946 Diff:
947 --- Expected
948 +++ Actual
949 @@ -1,3 +1,3 @@
950 (struct { foo string }) {
951 - foo: (string) (len=5) "hello"
952 + foo: (string) (len=3) "bar"
953 }
954 `
955 actual := diff(
956 struct{ foo string }{"hello"},
957 struct{ foo string }{"bar"},
958 )
959 Equal(t, expected, actual)
960
961 expected = `
962
963 Diff:
964 --- Expected
965 +++ Actual
966 @@ -2,5 +2,5 @@
967 (int) 1,
968 - (int) 2,
969 (int) 3,
970 - (int) 4
971 + (int) 5,
972 + (int) 7
973 }
974 `
975 actual = diff(
976 []int{1, 2, 3, 4},
977 []int{1, 3, 5, 7},
978 )
979 Equal(t, expected, actual)
980
981 expected = `
982
983 Diff:
984 --- Expected
985 +++ Actual
986 @@ -2,4 +2,4 @@
987 (int) 1,
988 - (int) 2,
989 - (int) 3
990 + (int) 3,
991 + (int) 5
992 }
993 `
994 actual = diff(
995 []int{1, 2, 3, 4}[0:3],
996 []int{1, 3, 5, 7}[0:3],
997 )
998 Equal(t, expected, actual)
999
1000 expected = `
1001
1002 Diff:
1003 --- Expected
1004 +++ Actual
1005 @@ -1,6 +1,6 @@
1006 (map[string]int) (len=4) {
1007 - (string) (len=4) "four": (int) 4,
1008 + (string) (len=4) "five": (int) 5,
1009 (string) (len=3) "one": (int) 1,
1010 - (string) (len=5) "three": (int) 3,
1011 - (string) (len=3) "two": (int) 2
1012 + (string) (len=5) "seven": (int) 7,
1013 + (string) (len=5) "three": (int) 3
1014 }
1015 `
1016
1017 actual = diff(
1018 map[string]int{"one": 1, "two": 2, "three": 3, "four": 4},
1019 map[string]int{"one": 1, "three": 3, "five": 5, "seven": 7},
1020 )
1021 Equal(t, expected, actual)
1022
1023 expected = `
1024
1025 Diff:
1026 --- Expected
1027 +++ Actual
1028 @@ -1,3 +1,3 @@
1029 (*errors.errorString)({
1030 - s: (string) (len=19) "some expected error"
1031 + s: (string) (len=12) "actual error"
1032 })
1033 `
1034
1035 actual = diff(
1036 errors.New("some expected error"),
1037 errors.New("actual error"),
1038 )
1039 Equal(t, expected, actual)
1040
1041 expected = `
1042
1043 Diff:
1044 --- Expected
1045 +++ Actual
1046 @@ -2,3 +2,3 @@
1047 A: (string) (len=11) "some string",
1048 - B: (int) 10
1049 + B: (int) 15
1050 }
1051 `
1052
1053 actual = diff(
1054 diffTestingStruct{A: "some string", B: 10},
1055 diffTestingStruct{A: "some string", B: 15},
1056 )
1057 Equal(t, expected, actual)
1058
1059 expected = `
1060
1061 Diff:
1062 --- Expected
1063 +++ Actual
1064 @@ -1,2 +1,2 @@
1065 -(time.Time) 2020-09-24 00:00:00 +0000 UTC
1066 +(time.Time) 2020-09-25 00:00:00 +0000 UTC
1067
1068 `
1069
1070 actual = diff(
1071 time.Date(2020, 9, 24, 0, 0, 0, 0, time.UTC),
1072 time.Date(2020, 9, 25, 0, 0, 0, 0, time.UTC),
1073 )
1074 Equal(t, expected, actual)
1075 }
1076
1077 func TestTimeEqualityErrorFormatting(_ *testing.T) {
1078 mockT := new(mockTestingT)
1079
1080 Equal(mockT, time.Second*2, time.Millisecond)
1081 }
1082
1083 func TestDiffEmptyCases(t *testing.T) {
1084 Equal(t, "", diff(nil, nil))
1085 Equal(t, "", diff(struct{ foo string }{}, nil))
1086 Equal(t, "", diff(nil, struct{ foo string }{}))
1087 Equal(t, "", diff(1, 2))
1088 Equal(t, "", diff(1, 2))
1089 Equal(t, "", diff([]int{1}, []bool{true}))
1090 }
1091
1092
1093 func TestDiffRace(t *testing.T) {
1094 t.Parallel()
1095
1096 expected := map[string]string{
1097 "a": "A",
1098 "b": "B",
1099 "c": "C",
1100 }
1101
1102 actual := map[string]string{
1103 "d": "D",
1104 "e": "E",
1105 "f": "F",
1106 }
1107
1108
1109 numRoutines := 10
1110 rChans := make([]chan string, numRoutines)
1111 for idx := range rChans {
1112 rChans[idx] = make(chan string)
1113 go func(ch chan string) {
1114 defer close(ch)
1115 ch <- diff(expected, actual)
1116 }(rChans[idx])
1117 }
1118
1119 for _, ch := range rChans {
1120 for msg := range ch {
1121 NotEqual(t, msg, "")
1122 }
1123 }
1124 }
1125
1126 type mockTestingT struct {
1127 errorFmt string
1128 args []interface{}
1129 }
1130
1131 func (m *mockTestingT) errorString() string {
1132 return fmt.Sprintf(m.errorFmt, m.args...)
1133 }
1134
1135 func (m *mockTestingT) Errorf(format string, args ...interface{}) {
1136 m.errorFmt = format
1137 m.args = args
1138 }
1139
1140 type mockFailNowTestingT struct {
1141 }
1142
1143 func (m *mockFailNowTestingT) Errorf(string, ...interface{}) {}
1144
1145 func (m *mockFailNowTestingT) FailNow() {}
1146
1147 func TestBytesEqual(t *testing.T) {
1148 var cases = []struct {
1149 a, b []byte
1150 }{
1151 {make([]byte, 2), make([]byte, 2)},
1152 {make([]byte, 2), make([]byte, 2, 3)},
1153 {nil, make([]byte, 0)},
1154 }
1155 for i, c := range cases {
1156 Equal(t, reflect.DeepEqual(c.a, c.b), ObjectsAreEqual(c.a, c.b), "case %d failed", i+1)
1157 }
1158 }
1159
1160 func BenchmarkBytesEqual(b *testing.B) {
1161 const size = 1024 * 8
1162 s := make([]byte, size)
1163 for i := range s {
1164 s[i] = byte(i % 255)
1165 }
1166 s2 := make([]byte, size)
1167 copy(s2, s)
1168
1169 mockT := &mockFailNowTestingT{}
1170 b.ResetTimer()
1171 for i := 0; i < b.N; i++ {
1172 Equal(mockT, s, s2)
1173 }
1174 }
1175
1176 func BenchmarkNotNil(b *testing.B) {
1177 for i := 0; i < b.N; i++ {
1178 NotNil(b, b)
1179 }
1180 }
1181
1182 func TestEventuallyFalse(t *testing.T) {
1183 mockT := new(testing.T)
1184
1185 condition := func() bool {
1186 return false
1187 }
1188
1189 False(t, Eventually(mockT, condition, 100*time.Millisecond, 20*time.Millisecond))
1190 }
1191
1192 func TestEventuallyTrue(t *testing.T) {
1193 state := 0
1194 condition := func() bool {
1195 defer func() {
1196 state++
1197 }()
1198 return state == 2
1199 }
1200
1201 True(t, Eventually(t, condition, 100*time.Millisecond, 20*time.Millisecond))
1202 }
1203
1204 func Test_validateEqualArgs(t *testing.T) {
1205 if validateEqualArgs(func() {}, func() {}) == nil {
1206 t.Error("non-nil functions should error")
1207 }
1208
1209 if validateEqualArgs(func() {}, func() {}) == nil {
1210 t.Error("non-nil functions should error")
1211 }
1212
1213 if validateEqualArgs(nil, nil) != nil {
1214 t.Error("nil functions are equal")
1215 }
1216 }
1217
1218 func Test_truncatingFormat(t *testing.T) {
1219
1220 original := strings.Repeat("a", bufio.MaxScanTokenSize-102)
1221 result := truncatingFormat(original)
1222 Equal(t, fmt.Sprintf("%#v", original), result, "string should not be truncated")
1223
1224 original = original + "x"
1225 result = truncatingFormat(original)
1226 NotEqual(t, fmt.Sprintf("%#v", original), result, "string should have been truncated.")
1227
1228 if !strings.HasSuffix(result, "<... truncated>") {
1229 t.Error("truncated string should have <... truncated> suffix")
1230 }
1231 }
1232
View as plain text