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