1package pretty 2 3import ( 4 "bytes" 5 "fmt" 6 "log" 7 "reflect" 8 "testing" 9 "unsafe" 10) 11 12var ( 13 _ Logfer = (*testing.T)(nil) 14 _ Logfer = (*testing.B)(nil) 15 _ Printfer = (*log.Logger)(nil) 16) 17 18type difftest struct { 19 a interface{} 20 b interface{} 21 exp []string 22} 23 24type S struct { 25 A int 26 S *S 27 I interface{} 28 C []int 29} 30 31type ( 32 N struct{ N int } 33 E interface{} 34) 35 36var ( 37 c0 = make(chan int) 38 c1 = make(chan int) 39 f0 = func() {} 40 f1 = func() {} 41 i0 = 0 42 i1 = 1 43) 44 45var diffs = []difftest{ 46 {a: nil, b: nil}, 47 {a: S{A: 1}, b: S{A: 1}}, 48 49 {0, "", []string{`int != string`}}, 50 {0, 1, []string{`0 != 1`}}, 51 {S{}, new(S), []string{`pretty.S != *pretty.S`}}, 52 {"a", "b", []string{`"a" != "b"`}}, 53 {S{}, S{A: 1}, []string{`A: 0 != 1`}}, 54 {new(S), &S{A: 1}, []string{`A: 0 != 1`}}, 55 {S{S: new(S)}, S{S: &S{A: 1}}, []string{`S.A: 0 != 1`}}, 56 {S{}, S{I: 0}, []string{`I: nil != int(0)`}}, 57 {S{I: 1}, S{I: "x"}, []string{`I: int != string`}}, 58 {S{}, S{C: []int{1}}, []string{`C: []int[0] != []int[1]`}}, 59 {S{C: []int{}}, S{C: []int{1}}, []string{`C: []int[0] != []int[1]`}}, 60 {S{C: []int{1, 2, 3}}, S{C: []int{1, 2, 4}}, []string{`C[2]: 3 != 4`}}, 61 {S{}, S{A: 1, S: new(S)}, []string{`A: 0 != 1`, `S: nil != &pretty.S{}`}}, 62 63 // unexported fields of every reflect.Kind (both equal and unequal) 64 {struct{ x bool }{false}, struct{ x bool }{false}, nil}, 65 {struct{ x bool }{false}, struct{ x bool }{true}, []string{`x: false != true`}}, 66 {struct{ x int }{0}, struct{ x int }{0}, nil}, 67 {struct{ x int }{0}, struct{ x int }{1}, []string{`x: 0 != 1`}}, 68 {struct{ x int8 }{0}, struct{ x int8 }{0}, nil}, 69 {struct{ x int8 }{0}, struct{ x int8 }{1}, []string{`x: 0 != 1`}}, 70 {struct{ x int16 }{0}, struct{ x int16 }{0}, nil}, 71 {struct{ x int16 }{0}, struct{ x int16 }{1}, []string{`x: 0 != 1`}}, 72 {struct{ x int32 }{0}, struct{ x int32 }{0}, nil}, 73 {struct{ x int32 }{0}, struct{ x int32 }{1}, []string{`x: 0 != 1`}}, 74 {struct{ x int64 }{0}, struct{ x int64 }{0}, nil}, 75 {struct{ x int64 }{0}, struct{ x int64 }{1}, []string{`x: 0 != 1`}}, 76 {struct{ x uint }{0}, struct{ x uint }{0}, nil}, 77 {struct{ x uint }{0}, struct{ x uint }{1}, []string{`x: 0 != 1`}}, 78 {struct{ x uint8 }{0}, struct{ x uint8 }{0}, nil}, 79 {struct{ x uint8 }{0}, struct{ x uint8 }{1}, []string{`x: 0 != 1`}}, 80 {struct{ x uint16 }{0}, struct{ x uint16 }{0}, nil}, 81 {struct{ x uint16 }{0}, struct{ x uint16 }{1}, []string{`x: 0 != 1`}}, 82 {struct{ x uint32 }{0}, struct{ x uint32 }{0}, nil}, 83 {struct{ x uint32 }{0}, struct{ x uint32 }{1}, []string{`x: 0 != 1`}}, 84 {struct{ x uint64 }{0}, struct{ x uint64 }{0}, nil}, 85 {struct{ x uint64 }{0}, struct{ x uint64 }{1}, []string{`x: 0 != 1`}}, 86 {struct{ x uintptr }{0}, struct{ x uintptr }{0}, nil}, 87 {struct{ x uintptr }{0}, struct{ x uintptr }{1}, []string{`x: 0 != 1`}}, 88 {struct{ x float32 }{0}, struct{ x float32 }{0}, nil}, 89 {struct{ x float32 }{0}, struct{ x float32 }{1}, []string{`x: 0 != 1`}}, 90 {struct{ x float64 }{0}, struct{ x float64 }{0}, nil}, 91 {struct{ x float64 }{0}, struct{ x float64 }{1}, []string{`x: 0 != 1`}}, 92 {struct{ x complex64 }{0}, struct{ x complex64 }{0}, nil}, 93 {struct{ x complex64 }{0}, struct{ x complex64 }{1}, []string{`x: (0+0i) != (1+0i)`}}, 94 {struct{ x complex128 }{0}, struct{ x complex128 }{0}, nil}, 95 {struct{ x complex128 }{0}, struct{ x complex128 }{1}, []string{`x: (0+0i) != (1+0i)`}}, 96 {struct{ x [1]int }{[1]int{0}}, struct{ x [1]int }{[1]int{0}}, nil}, 97 {struct{ x [1]int }{[1]int{0}}, struct{ x [1]int }{[1]int{1}}, []string{`x[0]: 0 != 1`}}, 98 {struct{ x chan int }{c0}, struct{ x chan int }{c0}, nil}, 99 {struct{ x chan int }{c0}, struct{ x chan int }{c1}, []string{fmt.Sprintf("x: %p != %p", c0, c1)}}, 100 {struct{ x func() }{f0}, struct{ x func() }{f0}, nil}, 101 {struct{ x func() }{f0}, struct{ x func() }{f1}, []string{fmt.Sprintf("x: %p != %p", f0, f1)}}, 102 {struct{ x interface{} }{0}, struct{ x interface{} }{0}, nil}, 103 {struct{ x interface{} }{0}, struct{ x interface{} }{1}, []string{`x: 0 != 1`}}, 104 {struct{ x interface{} }{0}, struct{ x interface{} }{""}, []string{`x: int != string`}}, 105 {struct{ x interface{} }{0}, struct{ x interface{} }{nil}, []string{`x: int(0) != nil`}}, 106 {struct{ x interface{} }{nil}, struct{ x interface{} }{0}, []string{`x: nil != int(0)`}}, 107 {struct{ x map[int]int }{map[int]int{0: 0}}, struct{ x map[int]int }{map[int]int{0: 0}}, nil}, 108 {struct{ x map[int]int }{map[int]int{0: 0}}, struct{ x map[int]int }{map[int]int{0: 1}}, []string{`x[0]: 0 != 1`}}, 109 {struct{ x *int }{new(int)}, struct{ x *int }{new(int)}, nil}, 110 {struct{ x *int }{&i0}, struct{ x *int }{&i1}, []string{`x: 0 != 1`}}, 111 {struct{ x *int }{nil}, struct{ x *int }{&i0}, []string{`x: nil != &int(0)`}}, 112 {struct{ x *int }{&i0}, struct{ x *int }{nil}, []string{`x: &int(0) != nil`}}, 113 {struct{ x []int }{[]int{0}}, struct{ x []int }{[]int{0}}, nil}, 114 {struct{ x []int }{[]int{0}}, struct{ x []int }{[]int{1}}, []string{`x[0]: 0 != 1`}}, 115 {struct{ x string }{"a"}, struct{ x string }{"a"}, nil}, 116 {struct{ x string }{"a"}, struct{ x string }{"b"}, []string{`x: "a" != "b"`}}, 117 {struct{ x N }{N{0}}, struct{ x N }{N{0}}, nil}, 118 {struct{ x N }{N{0}}, struct{ x N }{N{1}}, []string{`x.N: 0 != 1`}}, 119 { 120 struct{ x unsafe.Pointer }{unsafe.Pointer(uintptr(0))}, 121 struct{ x unsafe.Pointer }{unsafe.Pointer(uintptr(0))}, 122 nil, 123 }, 124 { 125 struct{ x unsafe.Pointer }{unsafe.Pointer(uintptr(0))}, 126 struct{ x unsafe.Pointer }{unsafe.Pointer(uintptr(1))}, 127 []string{`x: 0x0 != 0x1`}, 128 }, 129} 130 131func TestDiff(t *testing.T) { 132 for _, tt := range diffs { 133 got := Diff(tt.a, tt.b) 134 eq := len(got) == len(tt.exp) 135 if eq { 136 for i := range got { 137 eq = eq && got[i] == tt.exp[i] 138 } 139 } 140 if !eq { 141 t.Errorf("diffing % #v", tt.a) 142 t.Errorf("with % #v", tt.b) 143 diffdiff(t, got, tt.exp) 144 continue 145 } 146 } 147} 148 149func TestKeyEqual(t *testing.T) { 150 var emptyInterfaceZero interface{} = 0 151 152 cases := []interface{}{ 153 new(bool), 154 new(int), 155 new(int8), 156 new(int16), 157 new(int32), 158 new(int64), 159 new(uint), 160 new(uint8), 161 new(uint16), 162 new(uint32), 163 new(uint64), 164 new(uintptr), 165 new(float32), 166 new(float64), 167 new(complex64), 168 new(complex128), 169 new([1]int), 170 new(chan int), 171 new(unsafe.Pointer), 172 new(interface{}), 173 &emptyInterfaceZero, 174 new(*int), 175 new(string), 176 new(struct{ int }), 177 } 178 179 for _, test := range cases { 180 rv := reflect.ValueOf(test).Elem() 181 if !keyEqual(rv, rv) { 182 t.Errorf("keyEqual(%s, %s) = false want true", rv.Type(), rv.Type()) 183 } 184 } 185} 186 187func TestFdiff(t *testing.T) { 188 var buf bytes.Buffer 189 Fdiff(&buf, 0, 1) 190 want := "0 != 1\n" 191 if got := buf.String(); got != want { 192 t.Errorf("Fdiff(0, 1) = %q want %q", got, want) 193 } 194} 195 196func diffdiff(t *testing.T, got, exp []string) { 197 minus(t, "unexpected:", got, exp) 198 minus(t, "missing:", exp, got) 199} 200 201func minus(t *testing.T, s string, a, b []string) { 202 var i, j int 203 for i = 0; i < len(a); i++ { 204 for j = 0; j < len(b); j++ { 205 if a[i] == b[j] { 206 break 207 } 208 } 209 if j == len(b) { 210 t.Error(s, a[i]) 211 } 212 } 213} 214