mirror of
https://github.com/stretchr/testify.git
synced 2025-05-31 11:42:44 +00:00
Fixes #229 - show diffs for structs/maps/arrays/slices when Equal fails
This commit is contained in:
parent
0d5a14c5a4
commit
33c4c93911
@ -13,6 +13,9 @@ import (
|
||||
"time"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/pmezard/go-difflib/difflib"
|
||||
)
|
||||
|
||||
// TestingT is an interface wrapper around *testing.T
|
||||
@ -233,8 +236,9 @@ func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs
|
||||
func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
|
||||
|
||||
if !ObjectsAreEqual(expected, actual) {
|
||||
diff := diff(expected, actual)
|
||||
return Fail(t, fmt.Sprintf("Not equal: %#v (expected)\n"+
|
||||
" != %#v (actual)", expected, actual), msgAndArgs...)
|
||||
" != %#v (actual)%s", expected, actual, diff), msgAndArgs...)
|
||||
}
|
||||
|
||||
return true
|
||||
@ -921,3 +925,48 @@ func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{
|
||||
|
||||
return Equal(t, expectedJSONAsInterface, actualJSONAsInterface, msgAndArgs...)
|
||||
}
|
||||
|
||||
func typeAndKind(v interface{}) (reflect.Type, reflect.Kind) {
|
||||
t := reflect.TypeOf(v)
|
||||
k := t.Kind()
|
||||
|
||||
if k == reflect.Ptr {
|
||||
t = t.Elem()
|
||||
k = t.Kind()
|
||||
}
|
||||
return t, k
|
||||
}
|
||||
|
||||
// diff returns a diff of both values as long as both are of the same type and
|
||||
// are a struct, map, slice or array. Otherwise it returns an empty string.
|
||||
func diff(expected interface{}, actual interface{}) string {
|
||||
if expected == nil || actual == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
et, ek := typeAndKind(expected)
|
||||
at, _ := typeAndKind(actual)
|
||||
|
||||
if et != at {
|
||||
return ""
|
||||
}
|
||||
|
||||
if ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array {
|
||||
return ""
|
||||
}
|
||||
|
||||
e := spew.Sdump(expected)
|
||||
a := spew.Sdump(actual)
|
||||
|
||||
diff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{
|
||||
A: difflib.SplitLines(e),
|
||||
B: difflib.SplitLines(a),
|
||||
FromFile: "Expected",
|
||||
FromDate: "",
|
||||
ToFile: "Actual",
|
||||
ToDate: "",
|
||||
Context: 1,
|
||||
})
|
||||
|
||||
return "\n\nDiff:\n" + diff
|
||||
}
|
||||
|
@ -984,3 +984,77 @@ func TestJSONEq_ArraysOfDifferentOrder(t *testing.T) {
|
||||
mockT := new(testing.T)
|
||||
False(t, JSONEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `[{ "hello": "world", "nested": "hash"}, "foo"]`))
|
||||
}
|
||||
|
||||
func TestDiff(t *testing.T) {
|
||||
expected := `
|
||||
|
||||
Diff:
|
||||
--- Expected
|
||||
+++ Actual
|
||||
@@ -1,3 +1,3 @@
|
||||
(struct { foo string }) {
|
||||
- foo: (string) (len=5) "hello"
|
||||
+ foo: (string) (len=3) "bar"
|
||||
}
|
||||
`
|
||||
actual := diff(
|
||||
struct{ foo string }{"hello"},
|
||||
struct{ foo string }{"bar"},
|
||||
)
|
||||
Equal(t, expected, actual)
|
||||
|
||||
expected = `
|
||||
|
||||
Diff:
|
||||
--- Expected
|
||||
+++ Actual
|
||||
@@ -2,5 +2,5 @@
|
||||
(int) 1,
|
||||
- (int) 2,
|
||||
(int) 3,
|
||||
- (int) 4
|
||||
+ (int) 5,
|
||||
+ (int) 7
|
||||
}
|
||||
`
|
||||
actual = diff(
|
||||
[]int{1, 2, 3, 4},
|
||||
[]int{1, 3, 5, 7},
|
||||
)
|
||||
Equal(t, expected, actual)
|
||||
|
||||
expected = `
|
||||
|
||||
Diff:
|
||||
--- Expected
|
||||
+++ Actual
|
||||
@@ -2,4 +2,4 @@
|
||||
(int) 1,
|
||||
- (int) 2,
|
||||
- (int) 3
|
||||
+ (int) 3,
|
||||
+ (int) 5
|
||||
}
|
||||
`
|
||||
actual = diff(
|
||||
[]int{1, 2, 3, 4}[0:3],
|
||||
[]int{1, 3, 5, 7}[0:3],
|
||||
)
|
||||
Equal(t, expected, actual)
|
||||
|
||||
// output for maps cannot be equally tested since order is random
|
||||
actual = diff(
|
||||
map[string]int{"one": 1, "two": 2, "three": 3, "four": 4},
|
||||
map[string]int{"one": 1, "three": 3, "five": 5, "seven": 7},
|
||||
)
|
||||
NotZero(t, len(actual))
|
||||
}
|
||||
|
||||
func TestDiffEmptyCases(t *testing.T) {
|
||||
Equal(t, "", diff(nil, nil))
|
||||
Equal(t, "", diff(struct{ foo string }{}, nil))
|
||||
Equal(t, "", diff(nil, struct{ foo string }{}))
|
||||
Equal(t, "", diff(1, 2))
|
||||
Equal(t, "", diff(1, 2))
|
||||
Equal(t, "", diff([]int{1}, []bool{true}))
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user