Skip to content
Snippets Groups Projects
Commit 32df62d9 authored by renovate's avatar renovate
Browse files

Update module go-test/deep to v1

parent 48554377
No related branches found
No related tags found
1 merge request!17Update module go-test/deep to v1
......@@ -10,7 +10,7 @@ require (
git.autistici.org/id/usermetadb v0.0.0-20200209112823-95a30f3b610e
github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737 // indirect
github.com/go-ldap/ldap/v3 v3.2.4
github.com/go-test/deep v0.0.0-20180509200213-57af0be209c5
github.com/go-test/deep v1.0.7
github.com/lib/pq v0.0.0-20190326042056-d6156e141ac6 // indirect
github.com/mattn/go-sqlite3 v0.0.0-20190716071503-d6f416f91c46 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
......
language: go
go:
- "1.7"
- "1.8"
- "1.9"
- "1.10"
- "1.12"
- "1.13"
- "1.14"
before_install:
- go get github.com/mattn/goveralls
- go get golang.org/x/tools/cover
script:
- $HOME/gopath/bin/goveralls -service=travis-ci
- $HOME/gopath/bin/goveralls -service=travis-ci -package github.com/go-test/deep
# go-test/deep Changelog
## v1.0.7 released 2020-07-11
* Fixed issue #39: Confusing diff when comparing distinct types with the same name (PR #44)
## v1.0.6 released 2020-04-21
* Added `NilMapsAreEmpty` variable which causes a nil map to equal an empty map (PR #43) (@yalegko)
## v1.0.5 released 2020-01-16
* Added `NilSlicesAreEmpty` variable which causes a nil slice to be equal to an empty slice (PR #27) (@Anaminus)
## v1.0.4 released 2019-09-15
* Added \`deep:"-"\` structure field tag to ignore field (PR #38) (@flga)
## v1.0.3 released 2019-08-18
* Fixed issue #31: panic on typed primitives that implement error interface
## v1.0.2 released 2019-07-14
* Enabled Go module (@radeksimko)
* Changed supported and tested Go versions: 1.10, 1.11, and 1.12 (dropped 1.9)
* Changed Error equality: additional struct fields are compared too (PR #29) (@andrewmostello)
* Fixed typos and ineffassign issues (PR #25) (@tariq1890)
* Fixed diff order for nil comparison (PR #16) (@gmarik)
* Fixed slice equality when slices are extracted from the same array (PR #11) (@risteli)
* Fixed test spelling and messages (PR #19) (@sofuture)
* Fixed issue #15: panic on comparing struct with anonymous time.Time
* Fixed issue #18: Panic when comparing structs with time.Time value and CompareUnexportedFields is true
* Fixed issue #21: Set default MaxDepth = 0 (disabled) (PR #23)
## v1.0.1 released 2018-01-28
* Fixed #12: Arrays are not properly compared (samlitowitz)
* Fixed issue #12: Arrays are not properly compared (@samlitowitz)
## v1.0.0 releaesd 2017-10-27
......
......@@ -19,15 +19,22 @@ var (
// MaxDiff specifies the maximum number of differences to return.
MaxDiff = 10
// MaxDepth specifies the maximum levels of a struct to recurse into.
MaxDepth = 10
// MaxDepth specifies the maximum levels of a struct to recurse into,
// if greater than zero. If zero, there is no limit.
MaxDepth = 0
// LogErrors causes errors to be logged to STDERR when true.
LogErrors = false
// CompareUnexportedFields causes unexported struct fields, like s in
// T{s int}, to be comparsed when true.
// T{s int}, to be compared when true.
CompareUnexportedFields = false
// NilSlicesAreEmpty causes a nil slice to be equal to an empty slice.
NilSlicesAreEmpty = false
// NilMapsAreEmpty causes a nil map to be equal to an empty map.
NilMapsAreEmpty = false
)
var (
......@@ -50,11 +57,15 @@ type cmp struct {
var errorType = reflect.TypeOf((*error)(nil)).Elem()
// Equal compares variables a and b, recursing into their structure up to
// MaxDepth levels deep, and returns a list of differences, or nil if there are
// none. Some differences may not be found if an error is also returned.
// MaxDepth levels deep (if greater than zero), and returns a list of differences,
// or nil if there are none. Some differences may not be found if an error is
// also returned.
//
// If a type has an Equal method, like time.Equal, it is called to check for
// equality.
//
// When comparing a struct, if a field has the tag `deep:"-"` then it will be
// ignored.
func Equal(a, b interface{}) []string {
aVal := reflect.ValueOf(a)
bVal := reflect.ValueOf(b)
......@@ -66,7 +77,7 @@ func Equal(a, b interface{}) []string {
if a == nil && b == nil {
return nil
} else if a == nil && b != nil {
c.saveDiff(b, "<nil pointer>")
c.saveDiff("<nil pointer>", b)
} else if a != nil && b == nil {
c.saveDiff(a, "<nil pointer>")
}
......@@ -82,7 +93,7 @@ func Equal(a, b interface{}) []string {
}
func (c *cmp) equals(a, b reflect.Value, level int) {
if level > MaxDepth {
if MaxDepth > 0 && level > MaxDepth {
logError(ErrMaxRecursion)
return
}
......@@ -97,11 +108,22 @@ func (c *cmp) equals(a, b reflect.Value, level int) {
return
}
// If differenet types, they can't be equal
// If different types, they can't be equal
aType := a.Type()
bType := b.Type()
if aType != bType {
// Built-in types don't have a name, so don't report [3]int != [2]int as " != "
if aType.Name() == "" || aType.Name() != bType.Name() {
c.saveDiff(aType, bType)
} else {
// Type names can be the same, e.g. pkg/v1.Error and pkg/v2.Error
// are both exported as pkg, so unless we include the full pkg path
// the diff will be "pkg.Error != pkg.Error"
// https://github.com/go-test/deep/issues/39
aFullType := aType.PkgPath() + "." + aType.Name()
bFullType := bType.PkgPath() + "." + bType.Name()
c.saveDiff(aFullType, bFullType)
}
logError(ErrTypeMismatch)
return
}
......@@ -110,32 +132,33 @@ func (c *cmp) equals(a, b reflect.Value, level int) {
aKind := a.Kind()
bKind := b.Kind()
// Do a and b have underlying elements? Yes if they're ptr or interface.
aElem := aKind == reflect.Ptr || aKind == reflect.Interface
bElem := bKind == reflect.Ptr || bKind == reflect.Interface
// If both types implement the error interface, compare the error strings.
// This must be done before dereferencing because the interface is on a
// pointer receiver.
// pointer receiver. Re https://github.com/go-test/deep/issues/31, a/b might
// be primitive kinds; see TestErrorPrimitiveKind.
if aType.Implements(errorType) && bType.Implements(errorType) {
if a.Elem().IsValid() && b.Elem().IsValid() { // both err != nil
if (!aElem || !a.IsNil()) && (!bElem || !b.IsNil()) {
aString := a.MethodByName("Error").Call(nil)[0].String()
bString := b.MethodByName("Error").Call(nil)[0].String()
if aString != bString {
c.saveDiff(aString, bString)
}
return
}
}
}
// Dereference pointers and interface{}
if aElem, bElem := (aKind == reflect.Ptr || aKind == reflect.Interface),
(bKind == reflect.Ptr || bKind == reflect.Interface); aElem || bElem {
if aElem || bElem {
if aElem {
a = a.Elem()
}
if bElem {
b = b.Elem()
}
c.equals(a, b, level+1)
return
}
......@@ -185,6 +208,10 @@ func (c *cmp) equals(a, b reflect.Value, level int) {
continue // skip unexported field, e.g. s in type T struct {s string}
}
if aType.Field(i).Tag.Get("deep") == "-" {
continue // field wants to be ignored
}
c.push(aType.Field(i).Name) // push field name to buff
// Get the Value for each field, e.g. FirstName has Type = string,
......@@ -218,11 +245,21 @@ func (c *cmp) equals(a, b reflect.Value, level int) {
*/
if a.IsNil() || b.IsNil() {
if NilMapsAreEmpty {
if a.IsNil() && b.Len() != 0 {
c.saveDiff("<nil map>", b)
return
} else if a.Len() != 0 && b.IsNil() {
c.saveDiff(a, "<nil map>")
return
}
} else {
if a.IsNil() && !b.IsNil() {
c.saveDiff("<nil map>", b)
} else if !a.IsNil() && b.IsNil() {
c.saveDiff(a, "<nil map>")
}
}
return
}
......@@ -231,7 +268,7 @@ func (c *cmp) equals(a, b reflect.Value, level int) {
}
for _, key := range a.MapKeys() {
c.push(fmt.Sprintf("map[%s]", key))
c.push(fmt.Sprintf("map[%v]", key))
aVal := a.MapIndex(key)
bVal := b.MapIndex(key)
......@@ -253,7 +290,7 @@ func (c *cmp) equals(a, b reflect.Value, level int) {
continue
}
c.push(fmt.Sprintf("map[%s]", key))
c.push(fmt.Sprintf("map[%v]", key))
c.saveDiff("<does not have key>", b.MapIndex(key))
c.pop()
if len(c.diff) >= MaxDiff {
......@@ -271,21 +308,31 @@ func (c *cmp) equals(a, b reflect.Value, level int) {
}
}
case reflect.Slice:
if a.IsNil() || b.IsNil() {
if NilSlicesAreEmpty {
if a.IsNil() && b.Len() != 0 {
c.saveDiff("<nil slice>", b)
return
} else if a.Len() != 0 && b.IsNil() {
c.saveDiff(a, "<nil slice>")
return
}
} else {
if a.IsNil() && !b.IsNil() {
c.saveDiff("<nil slice>", b)
return
} else if !a.IsNil() && b.IsNil() {
c.saveDiff(a, "<nil slice>")
}
return
}
if a.Pointer() == b.Pointer() {
return
}
aLen := a.Len()
bLen := b.Len()
if a.Pointer() == b.Pointer() && aLen == bLen {
return
}
n := aLen
if bLen > aLen {
n = bLen
......@@ -310,8 +357,13 @@ func (c *cmp) equals(a, b reflect.Value, level int) {
/////////////////////////////////////////////////////////////////////
case reflect.Float32, reflect.Float64:
// Avoid 0.04147685731961082 != 0.041476857319611
// 6 decimal places is close enough
// Round floats to FloatPrecision decimal places to compare with
// user-defined precision. As is commonly know, floats have "imprecision"
// such that 0.1 becomes 0.100000001490116119384765625. This cannot
// be avoided; it can only be handled. Issue 30 suggested that floats
// be compared using an epsilon: equal = |a-b| < epsilon.
// In many cases the result is the same, but I think epsilon is a little
// less clear for users to reason about. See issue 30 for details.
aval := fmt.Sprintf(c.floatFormat, a.Float())
bval := fmt.Sprintf(c.floatFormat, b.Float())
if aval != bval {
......
module github.com/go-test/deep
go 1.13
......@@ -58,7 +58,7 @@ github.com/go-asn1-ber/asn1-ber
github.com/go-ldap/ldap/v3
# github.com/go-sql-driver/mysql v1.4.0
github.com/go-sql-driver/mysql
# github.com/go-test/deep v0.0.0-20180509200213-57af0be209c5
# github.com/go-test/deep v1.0.7
## explicit
github.com/go-test/deep
# github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment