diff_test.go 6.8 KB

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