1 package deep_test
2
3 import (
4 "errors"
5 "fmt"
6 "reflect"
7 "sort"
8 "testing"
9 "time"
10 "unsafe"
11
12 "github.com/go-test/deep"
13 v1 "github.com/go-test/deep/test/v1"
14 v2 "github.com/go-test/deep/test/v2"
15 )
16
17 func TestString(t *testing.T) {
18 diff := deep.Equal("foo", "foo")
19 if len(diff) > 0 {
20 t.Error("should be equal:", diff)
21 }
22
23 diff = deep.Equal("foo", "bar")
24 if diff == nil {
25 t.Fatal("no diff")
26 }
27 if len(diff) != 1 {
28 t.Error("too many diff:", diff)
29 }
30 if diff[0] != "foo != bar" {
31 t.Error("wrong diff:", diff[0])
32 }
33 }
34
35 func TestFloat(t *testing.T) {
36 diff := deep.Equal(1.1, 1.1)
37 if len(diff) > 0 {
38 t.Error("should be equal:", diff)
39 }
40
41 diff = deep.Equal(1.1234561, 1.1234562)
42 if diff == nil {
43 t.Error("no diff")
44 }
45
46 defaultFloatPrecision := deep.FloatPrecision
47 deep.FloatPrecision = 6
48 defer func() { deep.FloatPrecision = defaultFloatPrecision }()
49
50 diff = deep.Equal(1.1234561, 1.1234562)
51 if len(diff) > 0 {
52 t.Error("should be equal:", diff)
53 }
54
55 diff = deep.Equal(1.123456, 1.123457)
56 if diff == nil {
57 t.Fatal("no diff")
58 }
59 if len(diff) != 1 {
60 t.Error("too many diff:", diff)
61 }
62 if diff[0] != "1.123456 != 1.123457" {
63 t.Error("wrong diff:", diff[0])
64 }
65
66 }
67
68 func TestInt(t *testing.T) {
69 diff := deep.Equal(1, 1)
70 if len(diff) > 0 {
71 t.Error("should be equal:", diff)
72 }
73
74 diff = deep.Equal(1, 2)
75 if diff == nil {
76 t.Fatal("no diff")
77 }
78 if len(diff) != 1 {
79 t.Error("too many diff:", diff)
80 }
81 if diff[0] != "1 != 2" {
82 t.Error("wrong diff:", diff[0])
83 }
84 }
85
86 func TestUint(t *testing.T) {
87 diff := deep.Equal(uint(2), uint(2))
88 if len(diff) > 0 {
89 t.Error("should be equal:", diff)
90 }
91
92 diff = deep.Equal(uint(2), uint(3))
93 if diff == nil {
94 t.Fatal("no diff")
95 }
96 if len(diff) != 1 {
97 t.Error("too many diff:", diff)
98 }
99 if diff[0] != "2 != 3" {
100 t.Error("wrong diff:", diff[0])
101 }
102 }
103
104 func TestBool(t *testing.T) {
105 diff := deep.Equal(true, true)
106 if len(diff) > 0 {
107 t.Error("should be equal:", diff)
108 }
109
110 diff = deep.Equal(false, false)
111 if len(diff) > 0 {
112 t.Error("should be equal:", diff)
113 }
114
115 diff = deep.Equal(true, false)
116 if diff == nil {
117 t.Fatal("no diff")
118 }
119 if len(diff) != 1 {
120 t.Error("too many diff:", diff)
121 }
122 if diff[0] != "true != false" {
123 t.Error("wrong diff:", diff[0])
124 }
125 }
126
127 func TestTypeMismatch(t *testing.T) {
128 type T1 int
129 type T2 int
130 var t1 T1 = 1
131 var t2 T2 = 1
132 diff := deep.Equal(t1, t2)
133 if diff == nil {
134 t.Fatal("no diff")
135 }
136 if len(diff) != 1 {
137 t.Error("too many diff:", diff)
138 }
139 if diff[0] != "deep_test.T1 != deep_test.T2" {
140 t.Error("wrong diff:", diff[0])
141 }
142
143
144
145 err1 := v1.Error{}
146 err2 := v2.Error{}
147 diff = deep.Equal(err1, err2)
148 if diff == nil {
149 t.Fatal("no diff")
150 }
151 if len(diff) != 1 {
152 t.Error("too many diff:", diff)
153 }
154 if diff[0] != "github.com/go-test/deep/test/v1.Error != github.com/go-test/deep/test/v2.Error" {
155 t.Error("wrong diff:", diff[0])
156 }
157 }
158
159 func TestKindMismatch(t *testing.T) {
160 deep.LogErrors = true
161
162 var x int = 100
163 var y float64 = 100
164 diff := deep.Equal(x, y)
165 if diff == nil {
166 t.Fatal("no diff")
167 }
168 if len(diff) != 1 {
169 t.Error("too many diff:", diff)
170 }
171 if diff[0] != "int != float64" {
172 t.Error("wrong diff:", diff[0])
173 }
174
175 deep.LogErrors = false
176 }
177
178 func TestDeepRecursion(t *testing.T) {
179 deep.MaxDepth = 2
180 defer func() { deep.MaxDepth = 10 }()
181
182 type s3 struct {
183 S int
184 }
185 type s2 struct {
186 S s3
187 }
188 type s1 struct {
189 S s2
190 }
191 foo := map[string]s1{
192 "foo": {
193 S: s2{
194 S: s3{
195 S: 42,
196 },
197 },
198 },
199 }
200 bar := map[string]s1{
201 "foo": {
202 S: s2{
203 S: s3{
204 S: 100,
205 },
206 },
207 },
208 }
209
210 diff := deep.Equal(foo, bar)
211 if diff != nil {
212 t.Errorf("got %d diffs, expected none: %v", len(diff), diff)
213 }
214
215 defaultMaxDepth := deep.MaxDepth
216 deep.MaxDepth = 4
217 defer func() { deep.MaxDepth = defaultMaxDepth }()
218
219 diff = deep.Equal(foo, bar)
220 if diff == nil {
221 t.Fatal("no diff")
222 }
223 if len(diff) != 1 {
224 t.Error("too many diff:", diff)
225 }
226 if diff[0] != "map[foo].S.S.S: 42 != 100" {
227 t.Error("wrong diff:", diff[0])
228 }
229 }
230
231 func TestMaxDiff(t *testing.T) {
232 a := []int{1, 2, 3, 4, 5, 6, 7}
233 b := []int{0, 0, 0, 0, 0, 0, 0}
234
235 defaultMaxDiff := deep.MaxDiff
236 deep.MaxDiff = 3
237 defer func() { deep.MaxDiff = defaultMaxDiff }()
238
239 diff := deep.Equal(a, b)
240 if diff == nil {
241 t.Fatal("no diffs")
242 }
243 if len(diff) != deep.MaxDiff {
244 t.Errorf("got %d diffs, expected %d", len(diff), deep.MaxDiff)
245 }
246
247 defaultCompareUnexportedFields := deep.CompareUnexportedFields
248 deep.CompareUnexportedFields = true
249 defer func() { deep.CompareUnexportedFields = defaultCompareUnexportedFields }()
250 type fiveFields struct {
251 a int
252 b int
253 c int
254 d int
255 e int
256 }
257 t1 := fiveFields{1, 2, 3, 4, 5}
258 t2 := fiveFields{0, 0, 0, 0, 0}
259 diff = deep.Equal(t1, t2)
260 if diff == nil {
261 t.Fatal("no diffs")
262 }
263 if len(diff) != deep.MaxDiff {
264 t.Errorf("got %d diffs, expected %d", len(diff), deep.MaxDiff)
265 }
266
267
268 m1 := map[int]int{
269 1: 1,
270 2: 2,
271 3: 3,
272 4: 4,
273 5: 5,
274 }
275 m2 := map[int]int{
276 1: 0,
277 2: 0,
278 3: 0,
279 4: 0,
280 5: 0,
281 }
282 diff = deep.Equal(m1, m2)
283 if diff == nil {
284 t.Fatal("no diffs")
285 }
286 if len(diff) != deep.MaxDiff {
287 t.Log(diff)
288 t.Errorf("got %d diffs, expected %d", len(diff), deep.MaxDiff)
289 }
290
291
292 m1 = map[int]int{
293 1: 1,
294 2: 2,
295 }
296 m2 = map[int]int{
297 1: 1,
298 2: 2,
299 3: 0,
300 4: 0,
301 5: 0,
302 6: 0,
303 7: 0,
304 }
305 diff = deep.Equal(m1, m2)
306 if diff == nil {
307 t.Fatal("no diffs")
308 }
309 if len(diff) != deep.MaxDiff {
310 t.Log(diff)
311 t.Errorf("got %d diffs, expected %d", len(diff), deep.MaxDiff)
312 }
313 }
314
315 func TestNotHandled(t *testing.T) {
316
317 v := []int{1}
318 a := unsafe.Pointer(&v)
319 b := unsafe.Pointer(&v)
320
321
322
323
324 diff := deep.Equal(a, b)
325 if len(diff) > 0 {
326 t.Error("got diffs:", diff)
327 }
328 }
329
330 func TestStruct(t *testing.T) {
331 type s1 struct {
332 id int
333 Name string
334 Number int
335 }
336 sa := s1{
337 id: 1,
338 Name: "foo",
339 Number: 2,
340 }
341 sb := sa
342 diff := deep.Equal(sa, sb)
343 if len(diff) > 0 {
344 t.Error("should be equal:", diff)
345 }
346
347 sb.Name = "bar"
348 diff = deep.Equal(sa, sb)
349 if diff == nil {
350 t.Fatal("no diff")
351 }
352 if len(diff) != 1 {
353 t.Error("too many diff:", diff)
354 }
355 if diff[0] != "Name: foo != bar" {
356 t.Error("wrong diff:", diff[0])
357 }
358
359 sb.Number = 22
360 diff = deep.Equal(sa, sb)
361 if diff == nil {
362 t.Fatal("no diff")
363 }
364 if len(diff) != 2 {
365 t.Error("too many diff:", diff)
366 }
367 if diff[0] != "Name: foo != bar" {
368 t.Error("wrong diff:", diff[0])
369 }
370 if diff[1] != "Number: 2 != 22" {
371 t.Error("wrong diff:", diff[1])
372 }
373
374 sb.id = 11
375 diff = deep.Equal(sa, sb)
376 if diff == nil {
377 t.Fatal("no diff")
378 }
379 if len(diff) != 2 {
380 t.Error("too many diff:", diff)
381 }
382 if diff[0] != "Name: foo != bar" {
383 t.Error("wrong diff:", diff[0])
384 }
385 if diff[1] != "Number: 2 != 22" {
386 t.Error("wrong diff:", diff[1])
387 }
388 }
389
390 func TestStructWithTags(t *testing.T) {
391 type s1 struct {
392 same int
393 modified int
394 sameIgnored int `deep:"-"`
395 modifiedIgnored int `deep:"-"`
396 ExportedSame int
397 ExportedModified int
398 ExportedSameIgnored int `deep:"-"`
399 ExportedModifiedIgnored int `deep:"-"`
400 }
401 type s2 struct {
402 s1
403 same int
404 modified int
405 sameIgnored int `deep:"-"`
406 modifiedIgnored int `deep:"-"`
407 ExportedSame int
408 ExportedModified int
409 ExportedSameIgnored int `deep:"-"`
410 ExportedModifiedIgnored int `deep:"-"`
411 recurseInline s1
412 recursePtr *s2
413 }
414 sa := s2{
415 s1: s1{
416 same: 0,
417 modified: 1,
418 sameIgnored: 2,
419 modifiedIgnored: 3,
420 ExportedSame: 4,
421 ExportedModified: 5,
422 ExportedSameIgnored: 6,
423 ExportedModifiedIgnored: 7,
424 },
425 same: 0,
426 modified: 1,
427 sameIgnored: 2,
428 modifiedIgnored: 3,
429 ExportedSame: 4,
430 ExportedModified: 5,
431 ExportedSameIgnored: 6,
432 ExportedModifiedIgnored: 7,
433 recurseInline: s1{
434 same: 0,
435 modified: 1,
436 sameIgnored: 2,
437 modifiedIgnored: 3,
438 ExportedSame: 4,
439 ExportedModified: 5,
440 ExportedSameIgnored: 6,
441 ExportedModifiedIgnored: 7,
442 },
443 recursePtr: &s2{
444 same: 0,
445 modified: 1,
446 sameIgnored: 2,
447 modifiedIgnored: 3,
448 ExportedSame: 4,
449 ExportedModified: 5,
450 ExportedSameIgnored: 6,
451 ExportedModifiedIgnored: 7,
452 },
453 }
454 sb := s2{
455 s1: s1{
456 same: 0,
457 modified: 10,
458 sameIgnored: 2,
459 modifiedIgnored: 30,
460 ExportedSame: 4,
461 ExportedModified: 50,
462 ExportedSameIgnored: 6,
463 ExportedModifiedIgnored: 70,
464 },
465 same: 0,
466 modified: 10,
467 sameIgnored: 2,
468 modifiedIgnored: 30,
469 ExportedSame: 4,
470 ExportedModified: 50,
471 ExportedSameIgnored: 6,
472 ExportedModifiedIgnored: 70,
473 recurseInline: s1{
474 same: 0,
475 modified: 10,
476 sameIgnored: 2,
477 modifiedIgnored: 30,
478 ExportedSame: 4,
479 ExportedModified: 50,
480 ExportedSameIgnored: 6,
481 ExportedModifiedIgnored: 70,
482 },
483 recursePtr: &s2{
484 same: 0,
485 modified: 10,
486 sameIgnored: 2,
487 modifiedIgnored: 30,
488 ExportedSame: 4,
489 ExportedModified: 50,
490 ExportedSameIgnored: 6,
491 ExportedModifiedIgnored: 70,
492 },
493 }
494
495 orig := deep.CompareUnexportedFields
496 deep.CompareUnexportedFields = true
497 diff := deep.Equal(sa, sb)
498 deep.CompareUnexportedFields = orig
499
500 want := []string{
501 "s1.modified: 1 != 10",
502 "s1.ExportedModified: 5 != 50",
503 "modified: 1 != 10",
504 "ExportedModified: 5 != 50",
505 "recurseInline.modified: 1 != 10",
506 "recurseInline.ExportedModified: 5 != 50",
507 "recursePtr.modified: 1 != 10",
508 "recursePtr.ExportedModified: 5 != 50",
509 }
510 if !reflect.DeepEqual(want, diff) {
511 t.Errorf("got %v, want %v", diff, want)
512 }
513 }
514
515 func TestNestedStruct(t *testing.T) {
516 type s2 struct {
517 Nickname string
518 }
519 type s1 struct {
520 Name string
521 Alias s2
522 }
523 sa := s1{
524 Name: "Robert",
525 Alias: s2{Nickname: "Bob"},
526 }
527 sb := sa
528 diff := deep.Equal(sa, sb)
529 if len(diff) > 0 {
530 t.Error("should be equal:", diff)
531 }
532
533 sb.Alias.Nickname = "Bobby"
534 diff = deep.Equal(sa, sb)
535 if diff == nil {
536 t.Fatal("no diff")
537 }
538 if len(diff) != 1 {
539 t.Error("too many diff:", diff)
540 }
541 if diff[0] != "Alias.Nickname: Bob != Bobby" {
542 t.Error("wrong diff:", diff[0])
543 }
544 }
545
546 func TestMap(t *testing.T) {
547 ma := map[string]int{
548 "foo": 1,
549 "bar": 2,
550 }
551 mb := map[string]int{
552 "foo": 1,
553 "bar": 2,
554 }
555 diff := deep.Equal(ma, mb)
556 if len(diff) > 0 {
557 t.Error("should be equal:", diff)
558 }
559
560 diff = deep.Equal(ma, ma)
561 if len(diff) > 0 {
562 t.Error("should be equal:", diff)
563 }
564
565 mb["foo"] = 111
566 diff = deep.Equal(ma, mb)
567 if diff == nil {
568 t.Fatal("no diff")
569 }
570 if len(diff) != 1 {
571 t.Error("too many diff:", diff)
572 }
573 if diff[0] != "map[foo]: 1 != 111" {
574 t.Error("wrong diff:", diff[0])
575 }
576
577 delete(mb, "foo")
578 diff = deep.Equal(ma, mb)
579 if diff == nil {
580 t.Fatal("no diff")
581 }
582 if len(diff) != 1 {
583 t.Error("too many diff:", diff)
584 }
585 if diff[0] != "map[foo]: 1 != <does not have key>" {
586 t.Error("wrong diff:", diff[0])
587 }
588
589 diff = deep.Equal(mb, ma)
590 if diff == nil {
591 t.Fatal("no diff")
592 }
593 if len(diff) != 1 {
594 t.Error("too many diff:", diff)
595 }
596 if diff[0] != "map[foo]: <does not have key> != 1" {
597 t.Error("wrong diff:", diff[0])
598 }
599
600 var mc map[string]int
601 diff = deep.Equal(ma, mc)
602 if diff == nil {
603 t.Fatal("no diff")
604 }
605 if len(diff) != 1 {
606 t.Error("too many diff:", diff)
607 }
608
609 if diff[0] != "map[foo:1 bar:2] != <nil map>" && diff[0] != "map[bar:2 foo:1] != <nil map>" {
610 t.Error("wrong diff:", diff[0])
611 }
612
613 diff = deep.Equal(mc, ma)
614 if diff == nil {
615 t.Fatal("no diff")
616 }
617 if len(diff) != 1 {
618 t.Error("too many diff:", diff)
619 }
620 if diff[0] != "<nil map> != map[foo:1 bar:2]" && diff[0] != "<nil map> != map[bar:2 foo:1]" {
621 t.Error("wrong diff:", diff[0])
622 }
623 }
624
625 func TestArray(t *testing.T) {
626 a := [3]int{1, 2, 3}
627 b := [3]int{1, 2, 3}
628
629 diff := deep.Equal(a, b)
630 if len(diff) > 0 {
631 t.Error("should be equal:", diff)
632 }
633
634 diff = deep.Equal(a, a)
635 if len(diff) > 0 {
636 t.Error("should be equal:", diff)
637 }
638
639 b[2] = 333
640 diff = deep.Equal(a, b)
641 if diff == nil {
642 t.Fatal("no diff")
643 }
644 if len(diff) != 1 {
645 t.Error("too many diff:", diff)
646 }
647 if diff[0] != "array[2]: 3 != 333" {
648 t.Error("wrong diff:", diff[0])
649 }
650
651 c := [3]int{1, 2, 2}
652 diff = deep.Equal(a, c)
653 if diff == nil {
654 t.Fatal("no diff")
655 }
656 if len(diff) != 1 {
657 t.Error("too many diff:", diff)
658 }
659 if diff[0] != "array[2]: 3 != 2" {
660 t.Error("wrong diff:", diff[0])
661 }
662
663 var d [2]int
664 diff = deep.Equal(a, d)
665 if diff == nil {
666 t.Fatal("no diff")
667 }
668 if len(diff) != 1 {
669 t.Error("too many diff:", diff)
670 }
671 if diff[0] != "[3]int != [2]int" {
672 t.Error("wrong diff:", diff[0])
673 }
674
675 e := [12]int{}
676 f := [12]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
677 diff = deep.Equal(e, f)
678 if diff == nil {
679 t.Fatal("no diff")
680 }
681 if len(diff) != deep.MaxDiff {
682 t.Error("not enough diffs:", diff)
683 }
684 for i := 0; i < deep.MaxDiff; i++ {
685 if diff[i] != fmt.Sprintf("array[%d]: 0 != %d", i+1, i+1) {
686 t.Error("wrong diff:", diff[i])
687 }
688 }
689 }
690
691 func TestSlice(t *testing.T) {
692 a := []int{1, 2, 3}
693 b := []int{1, 2, 3}
694
695 diff := deep.Equal(a, b)
696 if len(diff) > 0 {
697 t.Error("should be equal:", diff)
698 }
699
700 diff = deep.Equal(a, a)
701 if len(diff) > 0 {
702 t.Error("should be equal:", diff)
703 }
704
705 b[2] = 333
706 diff = deep.Equal(a, b)
707 if diff == nil {
708 t.Fatal("no diff")
709 }
710 if len(diff) != 1 {
711 t.Error("too many diff:", diff)
712 }
713 if diff[0] != "slice[2]: 3 != 333" {
714 t.Error("wrong diff:", diff[0])
715 }
716
717 b = b[0:2]
718 diff = deep.Equal(a, b)
719 if diff == nil {
720 t.Fatal("no diff")
721 }
722 if len(diff) != 1 {
723 t.Error("too many diff:", diff)
724 }
725 if diff[0] != "slice[2]: 3 != <no value>" {
726 t.Error("wrong diff:", diff[0])
727 }
728
729 diff = deep.Equal(b, a)
730 if diff == nil {
731 t.Fatal("no diff")
732 }
733 if len(diff) != 1 {
734 t.Error("too many diff:", diff)
735 }
736 if diff[0] != "slice[2]: <no value> != 3" {
737 t.Error("wrong diff:", diff[0])
738 }
739
740 var c []int
741 diff = deep.Equal(a, c)
742 if diff == nil {
743 t.Fatal("no diff")
744 }
745 if len(diff) != 1 {
746 t.Error("too many diff:", diff)
747 }
748 if diff[0] != "[1 2 3] != <nil slice>" {
749 t.Error("wrong diff:", diff[0])
750 }
751
752 diff = deep.Equal(c, a)
753 if diff == nil {
754 t.Fatal("no diff")
755 }
756 if len(diff) != 1 {
757 t.Error("too many diff:", diff)
758 }
759 if diff[0] != "<nil slice> != [1 2 3]" {
760 t.Error("wrong diff:", diff[0])
761 }
762 }
763
764 func TestSiblingSlices(t *testing.T) {
765 father := []int{1, 2, 3, 4}
766 a := father[0:3]
767 b := father[0:3]
768
769 diff := deep.Equal(a, b)
770 if len(diff) > 0 {
771 t.Error("should be equal:", diff)
772 }
773 diff = deep.Equal(b, a)
774 if len(diff) > 0 {
775 t.Error("should be equal:", diff)
776 }
777
778 a = father[0:3]
779 b = father[0:2]
780 diff = deep.Equal(a, b)
781 if diff == nil {
782 t.Fatal("no diff")
783 }
784 if len(diff) != 1 {
785 t.Error("too many diff:", diff)
786 }
787 if diff[0] != "slice[2]: 3 != <no value>" {
788 t.Error("wrong diff:", diff[0])
789 }
790
791 a = father[0:2]
792 b = father[0:3]
793
794 diff = deep.Equal(a, b)
795 if diff == nil {
796 t.Fatal("no diff")
797 }
798 if len(diff) != 1 {
799 t.Error("too many diff:", diff)
800 }
801 if diff[0] != "slice[2]: <no value> != 3" {
802 t.Error("wrong diff:", diff[0])
803 }
804
805 a = father[0:2]
806 b = father[2:4]
807
808 diff = deep.Equal(a, b)
809 if diff == nil {
810 t.Fatal("no diff")
811 }
812 if len(diff) != 2 {
813 t.Error("too many diff:", diff)
814 }
815 if diff[0] != "slice[0]: 1 != 3" {
816 t.Error("wrong diff:", diff[0])
817 }
818 if diff[1] != "slice[1]: 2 != 4" {
819 t.Error("wrong diff:", diff[1])
820 }
821
822 a = father[0:0]
823 b = father[1:1]
824
825 diff = deep.Equal(a, b)
826 if len(diff) > 0 {
827 t.Error("should be equal:", diff)
828 }
829 diff = deep.Equal(b, a)
830 if len(diff) > 0 {
831 t.Error("should be equal:", diff)
832 }
833 }
834
835 func TestEmptySlice(t *testing.T) {
836 a := []int{1}
837 b := []int{}
838 var c []int
839
840
841 diff := deep.Equal(a, b)
842 if diff == nil {
843 t.Fatal("no diff")
844 }
845 if len(diff) != 1 {
846 t.Error("too many diff:", diff)
847 }
848 if diff[0] != "slice[0]: 1 != <no value>" {
849 t.Error("wrong diff:", diff[0])
850 }
851
852
853 diff = deep.Equal(b, a)
854 if diff == nil {
855 t.Fatal("no diff")
856 }
857 if len(diff) != 1 {
858 t.Error("too many diff:", diff)
859 }
860 if diff[0] != "slice[0]: <no value> != 1" {
861 t.Error("wrong diff:", diff[0])
862 }
863
864
865 diff = deep.Equal(b, c)
866 if diff == nil {
867 t.Fatal("no diff")
868 }
869 if len(diff) != 1 {
870 t.Error("too many diff:", diff)
871 }
872 if diff[0] != "[] != <nil slice>" {
873 t.Error("wrong diff:", diff[0])
874 }
875
876
877 diff = deep.Equal(c, b)
878 if diff == nil {
879 t.Fatal("no diff")
880 }
881 if len(diff) != 1 {
882 t.Error("too many diff:", diff)
883 }
884 if diff[0] != "<nil slice> != []" {
885 t.Error("wrong diff:", diff[0])
886 }
887 }
888
889 func TestNilSlicesAreEmpty(t *testing.T) {
890 defaultNilSlicesAreEmpty := deep.NilSlicesAreEmpty
891 deep.NilSlicesAreEmpty = true
892 defer func() { deep.NilSlicesAreEmpty = defaultNilSlicesAreEmpty }()
893
894 a := []int{1}
895 b := []int{}
896 var c []int
897
898
899 diff := deep.Equal(b, c)
900 if len(diff) > 0 {
901 t.Error("should be equal:", diff)
902 }
903
904
905 diff = deep.Equal(c, b)
906 if len(diff) > 0 {
907 t.Error("should be equal:", diff)
908 }
909
910
911 diff = deep.Equal(a, c)
912 if diff == nil {
913 t.Fatal("no diff")
914 }
915 if len(diff) != 1 {
916 t.Error("too many diff:", diff)
917 }
918 if diff[0] != "[1] != <nil slice>" {
919 t.Error("wrong diff:", diff[0])
920 }
921
922
923 diff = deep.Equal(c, a)
924 if diff == nil {
925 t.Fatal("no diff")
926 }
927 if len(diff) != 1 {
928 t.Error("too many diff:", diff)
929 }
930 if diff[0] != "<nil slice> != [1]" {
931 t.Error("wrong diff:", diff[0])
932 }
933
934
935 diff = deep.Equal(a, b)
936 if diff == nil {
937 t.Fatal("no diff")
938 }
939 if len(diff) != 1 {
940 t.Error("too many diff:", diff)
941 }
942 if diff[0] != "slice[0]: 1 != <no value>" {
943 t.Error("wrong diff:", diff[0])
944 }
945
946
947 diff = deep.Equal(b, a)
948 if diff == nil {
949 t.Fatal("no diff")
950 }
951 if len(diff) != 1 {
952 t.Error("too many diff:", diff)
953 }
954 if diff[0] != "slice[0]: <no value> != 1" {
955 t.Error("wrong diff:", diff[0])
956 }
957 }
958
959 func TestNilMapsAreEmpty(t *testing.T) {
960 defaultNilMapsAreEmpty := deep.NilSlicesAreEmpty
961 deep.NilMapsAreEmpty = true
962 defer func() { deep.NilSlicesAreEmpty = defaultNilMapsAreEmpty }()
963
964 a := map[int]int{1: 1}
965 b := map[int]int{}
966 var c map[int]int
967
968
969 diff := deep.Equal(b, c)
970 if len(diff) > 0 {
971 t.Error("should be equal:", diff)
972 }
973
974
975 diff = deep.Equal(c, b)
976 if len(diff) > 0 {
977 t.Error("should be equal:", diff)
978 }
979
980
981 diff = deep.Equal(a, c)
982 if diff == nil {
983 t.Fatal("no diff")
984 }
985 if len(diff) != 1 {
986 t.Error("too many diff:", diff)
987 }
988 if diff[0] != "map[1:1] != <nil map>" {
989 t.Error("wrong diff:", diff[0])
990 }
991
992
993 diff = deep.Equal(c, a)
994 if diff == nil {
995 t.Fatal("no diff")
996 }
997 if len(diff) != 1 {
998 t.Error("too many diff:", diff)
999 }
1000 if diff[0] != "<nil map> != map[1:1]" {
1001 t.Error("wrong diff:", diff[0])
1002 }
1003
1004
1005 diff = deep.Equal(a, b)
1006 if diff == nil {
1007 t.Fatal("no diff")
1008 }
1009 if len(diff) != 1 {
1010 t.Error("too many diff:", diff)
1011 }
1012 if diff[0] != "map[1]: 1 != <does not have key>" {
1013 t.Error("wrong diff:", diff[0])
1014 }
1015
1016
1017 diff = deep.Equal(b, a)
1018 if diff == nil {
1019 t.Fatal("no diff")
1020 }
1021 if len(diff) != 1 {
1022 t.Error("too many diff:", diff)
1023 }
1024 if diff[0] != "map[1]: <does not have key> != 1" {
1025 t.Error("wrong diff:", diff[0])
1026 }
1027 }
1028
1029 func TestNilInterface(t *testing.T) {
1030 type T struct{ i int }
1031
1032 a := &T{i: 1}
1033 diff := deep.Equal(nil, a)
1034 if diff == nil {
1035 t.Fatal("no diff")
1036 }
1037 if len(diff) != 1 {
1038 t.Error("too many diff:", diff)
1039 }
1040 if diff[0] != "<nil pointer> != &{1}" {
1041 t.Error("wrong diff:", diff[0])
1042 }
1043
1044 diff = deep.Equal(a, nil)
1045 if diff == nil {
1046 t.Fatal("no diff")
1047 }
1048 if len(diff) != 1 {
1049 t.Error("too many diff:", diff)
1050 }
1051 if diff[0] != "&{1} != <nil pointer>" {
1052 t.Error("wrong diff:", diff[0])
1053 }
1054
1055 diff = deep.Equal(nil, nil)
1056 if len(diff) > 0 {
1057 t.Error("should be equal:", diff)
1058 }
1059 }
1060
1061 func TestPointer(t *testing.T) {
1062 type T struct{ i int }
1063
1064 a, b := &T{i: 1}, &T{i: 1}
1065 diff := deep.Equal(a, b)
1066 if len(diff) > 0 {
1067 t.Error("should be equal:", diff)
1068 }
1069
1070 a, b = nil, &T{}
1071 diff = deep.Equal(a, b)
1072 if diff == nil {
1073 t.Fatal("no diff")
1074 }
1075 if len(diff) != 1 {
1076 t.Error("too many diff:", diff)
1077 }
1078 if diff[0] != "<nil pointer> != deep_test.T" {
1079 t.Error("wrong diff:", diff[0])
1080 }
1081
1082 a, b = &T{}, nil
1083 diff = deep.Equal(a, b)
1084 if diff == nil {
1085 t.Fatal("no diff")
1086 }
1087 if len(diff) != 1 {
1088 t.Error("too many diff:", diff)
1089 }
1090 if diff[0] != "deep_test.T != <nil pointer>" {
1091 t.Error("wrong diff:", diff[0])
1092 }
1093
1094 a, b = nil, nil
1095 diff = deep.Equal(a, b)
1096 if len(diff) > 0 {
1097 t.Error("should be equal:", diff)
1098 }
1099 }
1100
1101 func TestTime(t *testing.T) {
1102
1103 type sTime struct {
1104 T time.Time
1105 }
1106 now := time.Now()
1107 got := sTime{T: now}
1108 expect := sTime{T: now.Add(1 * time.Second)}
1109 diff := deep.Equal(got, expect)
1110 if len(diff) != 1 {
1111 t.Error("expected 1 diff:", diff)
1112 }
1113
1114
1115 a := now
1116 b := now
1117 diff = deep.Equal(a, b)
1118 if len(diff) > 0 {
1119 t.Error("should be equal:", diff)
1120 }
1121
1122
1123 type Time15 struct {
1124 time.Time
1125 }
1126 a15 := Time15{now}
1127 b15 := Time15{now}
1128 diff = deep.Equal(a15, b15)
1129 if len(diff) > 0 {
1130 t.Error("should be equal:", diff)
1131 }
1132
1133 later := now.Add(1 * time.Second)
1134 b15 = Time15{later}
1135 diff = deep.Equal(a15, b15)
1136 if len(diff) != 1 {
1137 t.Errorf("got %d diffs, expected 1: %s", len(diff), diff)
1138 }
1139
1140
1141 type Time17 struct {
1142 time.Time
1143 Foo int
1144 }
1145 a17 := Time17{Time: now, Foo: 1}
1146 b17 := Time17{Time: now, Foo: 2}
1147 diff = deep.Equal(a17, b17)
1148 if len(diff) != 1 {
1149 t.Errorf("got %d diffs, expected 1: %s", len(diff), diff)
1150 }
1151 }
1152
1153 func TestTimeUnexported(t *testing.T) {
1154
1155
1156 defaultCompareUnexportedFields := deep.CompareUnexportedFields
1157 deep.CompareUnexportedFields = true
1158 defer func() { deep.CompareUnexportedFields = defaultCompareUnexportedFields }()
1159
1160 now := time.Now()
1161 type hiddenTime struct {
1162 t time.Time
1163 }
1164 htA := &hiddenTime{t: now}
1165 htB := &hiddenTime{t: now}
1166 diff := deep.Equal(htA, htB)
1167 if len(diff) > 0 {
1168 t.Error("should be equal:", diff)
1169 }
1170
1171
1172
1173
1174 later := now.Add(1 * time.Second)
1175 htC := &hiddenTime{t: later}
1176 diff = deep.Equal(htA, htC)
1177
1178 expected := 1
1179 if _, ok := reflect.TypeOf(htA.t).FieldByName("ext"); ok {
1180 expected = 2
1181 }
1182 if len(diff) != expected {
1183 t.Errorf("got %d diffs, expected %d: %s", len(diff), expected, diff)
1184 }
1185 }
1186
1187 func TestInterface(t *testing.T) {
1188 a := map[string]interface{}{
1189 "foo": map[string]string{
1190 "bar": "a",
1191 },
1192 }
1193 b := map[string]interface{}{
1194 "foo": map[string]string{
1195 "bar": "b",
1196 },
1197 }
1198 diff := deep.Equal(a, b)
1199 if len(diff) == 0 {
1200 t.Fatalf("expected 1 diff, got zero")
1201 }
1202 if len(diff) != 1 {
1203 t.Errorf("expected 1 diff, got %d: %s", len(diff), diff)
1204 }
1205 }
1206
1207 func TestInterface2(t *testing.T) {
1208 defer func() {
1209 if val := recover(); val != nil {
1210 t.Fatalf("panic: %v", val)
1211 }
1212 }()
1213
1214 a := map[string]interface{}{
1215 "bar": 1,
1216 }
1217 b := map[string]interface{}{
1218 "bar": 1.23,
1219 }
1220 diff := deep.Equal(a, b)
1221 if len(diff) == 0 {
1222 t.Fatalf("expected 1 diff, got zero")
1223 }
1224 if len(diff) != 1 {
1225 t.Errorf("expected 1 diff, got %d: %s", len(diff), diff)
1226 }
1227 }
1228
1229 func TestInterface3(t *testing.T) {
1230 type Value struct{ int }
1231 a := map[string]interface{}{
1232 "foo": &Value{},
1233 }
1234 b := map[string]interface{}{
1235 "foo": 1.23,
1236 }
1237 diff := deep.Equal(a, b)
1238 if len(diff) == 0 {
1239 t.Fatalf("expected 1 diff, got zero")
1240 }
1241
1242 if len(diff) != 1 {
1243 t.Errorf("expected 1 diff, got: %s", diff)
1244 }
1245 }
1246
1247 func TestError(t *testing.T) {
1248 a := errors.New("it broke")
1249 b := errors.New("it broke")
1250
1251 diff := deep.Equal(a, b)
1252 if len(diff) != 0 {
1253 t.Fatalf("expected zero diffs, got %d: %s", len(diff), diff)
1254 }
1255
1256 b = errors.New("it fell apart")
1257 diff = deep.Equal(a, b)
1258 if len(diff) != 1 {
1259 t.Fatalf("expected 1 diff, got %d: %s", len(diff), diff)
1260 }
1261 if diff[0] != "it broke != it fell apart" {
1262 t.Errorf("got '%s', expected 'it broke != it fell apart'", diff[0])
1263 }
1264
1265
1266 type tWithError struct {
1267 Error error
1268 }
1269 t1 := tWithError{
1270 Error: a,
1271 }
1272 t2 := tWithError{
1273 Error: b,
1274 }
1275 diff = deep.Equal(t1, t2)
1276 if len(diff) != 1 {
1277 t.Fatalf("expected 1 diff, got %d: %s", len(diff), diff)
1278 }
1279 if diff[0] != "Error: it broke != it fell apart" {
1280 t.Errorf("got '%s', expected 'Error: it broke != it fell apart'", diff[0])
1281 }
1282
1283
1284 t1 = tWithError{
1285 Error: nil,
1286 }
1287 t2 = tWithError{
1288 Error: nil,
1289 }
1290 diff = deep.Equal(t1, t2)
1291 if len(diff) != 0 {
1292 t.Log(diff)
1293 t.Fatalf("expected 0 diff, got %d: %s", len(diff), diff)
1294 }
1295
1296
1297 t1 = tWithError{
1298 Error: errors.New("foo"),
1299 }
1300 t2 = tWithError{
1301 Error: nil,
1302 }
1303 diff = deep.Equal(t1, t2)
1304 if len(diff) != 1 {
1305 t.Log(diff)
1306 t.Fatalf("expected 1 diff, got %d: %s", len(diff), diff)
1307 }
1308 if diff[0] != "Error: *errors.errorString != <nil pointer>" {
1309 t.Errorf("got '%s', expected 'Error: *errors.errorString != <nil pointer>'", diff[0])
1310 }
1311 }
1312
1313 func TestErrorWithOtherFields(t *testing.T) {
1314 a := errors.New("it broke")
1315 b := errors.New("it fell apart")
1316
1317
1318 type tWithError struct {
1319 Error error
1320 Other string
1321 }
1322 t1 := tWithError{
1323 Error: a,
1324 Other: "ok",
1325 }
1326 t2 := tWithError{
1327 Error: b,
1328 Other: "ok",
1329 }
1330 diff := deep.Equal(t1, t2)
1331 if len(diff) != 1 {
1332 t.Fatalf("expected 1 diff, got %d: %s", len(diff), diff)
1333 }
1334 if diff[0] != "Error: it broke != it fell apart" {
1335 t.Errorf("got '%s', expected 'Error: it broke != it fell apart'", diff[0])
1336 }
1337
1338
1339 t1 = tWithError{
1340 Error: nil,
1341 Other: "ok",
1342 }
1343 t2 = tWithError{
1344 Error: nil,
1345 Other: "ok",
1346 }
1347 diff = deep.Equal(t1, t2)
1348 if len(diff) != 0 {
1349 t.Log(diff)
1350 t.Fatalf("expected 0 diff, got %d: %s", len(diff), diff)
1351 }
1352
1353
1354 t1 = tWithError{
1355 Error: nil,
1356 Other: "ok",
1357 }
1358 t2 = tWithError{
1359 Error: nil,
1360 Other: "nope",
1361 }
1362 diff = deep.Equal(t1, t2)
1363 if len(diff) != 1 {
1364 t.Fatalf("expected 1 diff, got %d: %s", len(diff), diff)
1365 }
1366 if diff[0] != "Other: ok != nope" {
1367 t.Errorf("got '%s', expected 'Other: ok != nope'", diff[0])
1368 }
1369
1370
1371 t1 = tWithError{
1372 Error: a,
1373 Other: "ok",
1374 }
1375 t2 = tWithError{
1376 Error: a,
1377 Other: "nope",
1378 }
1379 diff = deep.Equal(t1, t2)
1380 if len(diff) != 1 {
1381 t.Fatalf("expected 1 diff, got %d: %s", len(diff), diff)
1382 }
1383 if diff[0] != "Other: ok != nope" {
1384 t.Errorf("got '%s', expected 'Other: ok != nope'", diff[0])
1385 }
1386 }
1387
1388 type primKindError string
1389
1390 func (e primKindError) Error() string {
1391 return string(e)
1392 }
1393
1394 func TestErrorPrimitiveKind(t *testing.T) {
1395
1396
1397
1398
1399
1400 var err1 primKindError = "abc"
1401 var err2 primKindError = "abc"
1402 diff := deep.Equal(err1, err2)
1403 if len(diff) != 0 {
1404 t.Fatalf("expected zero diffs, got %d: %s", len(diff), diff)
1405 }
1406
1407 err2 = "def"
1408 diff = deep.Equal(err1, err2)
1409 if len(diff) != 1 {
1410 t.Fatalf("expected 1 diff, got %d: %s", len(diff), diff)
1411 }
1412 }
1413
1414 func TestErrorUnexported(t *testing.T) {
1415
1416 type foo struct {
1417 bar error
1418 }
1419 defaultCompareUnexportedFields := deep.CompareUnexportedFields
1420 deep.CompareUnexportedFields = true
1421 defer func() { deep.CompareUnexportedFields = defaultCompareUnexportedFields }()
1422 e1 := foo{bar: fmt.Errorf("error")}
1423 e2 := foo{bar: fmt.Errorf("error")}
1424 deep.Equal(e1, e2)
1425 }
1426
1427 func TestNil(t *testing.T) {
1428 type student struct {
1429 name string
1430 age int
1431 }
1432
1433 mark := student{"mark", 10}
1434 var someNilThing interface{} = nil
1435 diff := deep.Equal(someNilThing, mark)
1436 if diff == nil {
1437 t.Error("Nil value to comparison should not be equal")
1438 }
1439 diff = deep.Equal(mark, someNilThing)
1440 if diff == nil {
1441 t.Error("Nil value to comparison should not be equal")
1442 }
1443 diff = deep.Equal(someNilThing, someNilThing)
1444 if diff != nil {
1445 t.Error("Nil value to comparison should not be equal")
1446 }
1447 }
1448
1449 var testFunc = func() {}
1450
1451 func TestFunc(t *testing.T) {
1452
1453 type TestStruct struct {
1454 Function func()
1455 }
1456 t1 := TestStruct{
1457 Function: testFunc,
1458 }
1459 t2 := TestStruct{
1460 Function: testFunc,
1461 }
1462
1463
1464 diff := deep.Equal(t1, t2)
1465 if len(diff) != 0 {
1466 t.Fatalf("expected 0 diff when CompareFunctions=false, got %d: %s", len(diff), diff)
1467 }
1468
1469 deep.CompareFunctions = true
1470 defer func() { deep.CompareFunctions = false }()
1471
1472
1473 diff = deep.Equal(t1, t2)
1474 if len(diff) != 1 {
1475 t.Fatalf("expected 1 diff, got %d: %s", len(diff), diff)
1476 }
1477 if diff[0] != "Function: func != func" {
1478 t.Errorf("got '%s', expected 'Function: func != func'", diff[0])
1479 }
1480
1481
1482 t1.Function = nil
1483 diff = deep.Equal(t1, t2)
1484 if len(diff) != 1 {
1485 t.Fatalf("expected 1 diff, got %d: %s", len(diff), diff)
1486 }
1487 if diff[0] != "Function: nil func != func" {
1488 t.Errorf("got '%s', expected 'Function: nil func != func'", diff[0])
1489 }
1490
1491
1492 t1.Function = nil
1493 t2.Function = nil
1494 diff = deep.Equal(t1, t2)
1495 if len(diff) != 0 {
1496 t.Errorf("expected 0 diff, got %d: %s", len(diff), diff)
1497 }
1498 }
1499
1500 func TestSliceOrderString(t *testing.T) {
1501
1502
1503
1504 a := []string{"foo", "bar"}
1505 b := []string{"bar", "foo"}
1506 diff := deep.Equal(a, b, deep.FLAG_IGNORE_SLICE_ORDER)
1507 if len(diff) != 0 {
1508 t.Fatalf("expected 0 diff, got %d: %s", len(diff), diff)
1509 }
1510
1511
1512 a = []string{"foo", "foo", "bar"}
1513 b = []string{"bar", "foo", "foo"}
1514 diff = deep.Equal(a, b, deep.FLAG_IGNORE_SLICE_ORDER)
1515 if len(diff) != 0 {
1516 t.Fatalf("expected 0 diff, got %d: %s", len(diff), diff)
1517 }
1518
1519
1520 a = []string{"foo", "foo", "bar"}
1521 b = []string{"bar", "bar", "foo"}
1522 diff = deep.Equal(a, b, deep.FLAG_IGNORE_SLICE_ORDER)
1523 if len(diff) != 2 {
1524 t.Fatalf("expected 2 diff, got %d: %s", len(diff), diff)
1525 }
1526 m1 := "(unordered) slice[]=foo: value count: 2 != 1"
1527 m2 := "(unordered) slice[]=bar: value count: 1 != 2"
1528 if diff[0] != m1 && diff[0] != m2 {
1529 t.Errorf("got %s, expected '%s' or '%s'", diff[0], m1, m2)
1530 }
1531 if diff[1] != m1 && diff[1] != m2 {
1532 t.Errorf("got %s, expected '%s' or '%s'", diff[1], m1, m2)
1533 }
1534
1535
1536 a = []string{"foo", "bar"}
1537 b = []string{"bar", "foo", "gone"}
1538 diff = deep.Equal(a, b, deep.FLAG_IGNORE_SLICE_ORDER)
1539 if len(diff) != 1 {
1540 t.Fatalf("expected 2 diff, got %d: %s", len(diff), diff)
1541 }
1542 if diff[0] != "(unordered) slice[]=gone: value count: 0 != 1" {
1543 t.Errorf("got %s, expected ''", diff[0])
1544 }
1545
1546
1547 a = []string{"foo", "bar"}
1548 b = []string{"x"}
1549 diff = deep.Equal(a, b, deep.FLAG_IGNORE_SLICE_ORDER)
1550 if len(diff) != 3 {
1551 t.Fatalf("expected 2 diff, got %d: %s", len(diff), diff)
1552 }
1553 sort.Strings(diff)
1554 if diff[0] != "(unordered) slice[]=bar: value count: 1 != 0" {
1555 t.Errorf("got %s, expected '(unordered) slice[]=bar: value count: 1 != 0'", diff[0])
1556 }
1557 if diff[1] != "(unordered) slice[]=foo: value count: 1 != 0" {
1558 t.Errorf("got %s, expected '(unordered) slice[]=foo: value count: 1 != 0", diff[1])
1559 }
1560 if diff[2] != "(unordered) slice[]=x: value count: 0 != 1" {
1561 t.Errorf("got %s, expected '(unordered) slice[]=x: value count: 0 != 1'", diff[2])
1562 }
1563 }
1564
1565 func TestSliceOrderStruct(t *testing.T) {
1566
1567
1568
1569
1570 type T struct{ i int }
1571 a := []T{
1572 {i: 1},
1573 {i: 2},
1574 }
1575 b := []T{
1576 {i: 2},
1577 {i: 1},
1578 }
1579 diff := deep.Equal(a, b, deep.FLAG_IGNORE_SLICE_ORDER)
1580 if len(diff) != 0 {
1581 t.Fatalf("expected 0 diff, got %d: %s", len(diff), diff)
1582 }
1583 }
1584
View as plain text