diff --git a/go.mod b/go.mod index 0a00c839b683cbd9b188250260606900fbb0e76b..6e6643ec546d9dd1db8cf15059de75a416baa31c 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( git.autistici.org/id/usermetadb v0.0.0-20220817085057-e52734a753fb github.com/ProtonMail/gopenpgp/v2 v2.4.10 github.com/go-ldap/ldap/v3 v3.4.4 - github.com/go-test/deep v1.0.8 + github.com/go-test/deep v1.1.0 github.com/patrickmn/go-cache v0.0.0-20180815053127-5633e0862627 github.com/pquerna/otp v1.3.0 github.com/prometheus/client_golang v1.12.2 diff --git a/go.sum b/go.sum index e8d6711a1cca2aff1723a6821460b89cae4b1041..2a63aa4563c1eeb9c6adc86f4da9d319ba7c43af 100644 --- a/go.sum +++ b/go.sum @@ -338,6 +338,8 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg= +github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.0 h1:MSdYClljsF3PbENUUEx85nkWfJSGfzYI9yEBZOJz6CY= diff --git a/vendor/github.com/go-test/deep/.travis.yml b/vendor/github.com/go-test/deep/.travis.yml deleted file mode 100644 index c459ee7b0e814117182a0afa453a06e67a0844a2..0000000000000000000000000000000000000000 --- a/vendor/github.com/go-test/deep/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: go - -go: - - "1.15" - - "1.16" - - "1.17" - -before_install: - - go get github.com/mattn/goveralls - - go get golang.org/x/tools/cover - -script: - - $HOME/gopath/bin/goveralls -service=travis-pro -package github.com/go-test/deep diff --git a/vendor/github.com/go-test/deep/CHANGES.md b/vendor/github.com/go-test/deep/CHANGES.md index ade9e79c68f78a30108d40ff828c216c82e719dc..98f8c18b18f93e42abea825646bcb67fb4e32631 100644 --- a/vendor/github.com/go-test/deep/CHANGES.md +++ b/vendor/github.com/go-test/deep/CHANGES.md @@ -1,5 +1,11 @@ # go-test/deep Changelog +## v1.0.9 released 2022-12-09 + +* Fixed issue #45: Panic when comparing errors in unexported fields (PR #54) (@seveas) +* Fixed issue #46: Functions are handled differently from reflect.DeepEqual (PR #55) (@countcb) +* Updated matrix to go1.17, go1.18, and go1.19 and moved testing to GitHub Actions + ## v1.0.8 released 2021-10-13 * Updated matrix to go1.15, go1.16, and go1.17 diff --git a/vendor/github.com/go-test/deep/README.md b/vendor/github.com/go-test/deep/README.md index 56770a69b34b74f31d398bffc5ab6cd8a4ce0a8c..08a86070d1a5646b3c6601b13e089ebb954cb0ee 100644 --- a/vendor/github.com/go-test/deep/README.md +++ b/vendor/github.com/go-test/deep/README.md @@ -1,6 +1,8 @@ # Deep Variable Equality for Humans -[](https://goreportcard.com/report/github.com/go-test/deep) [](https://app.travis-ci.com/go-test/deep) [](https://coveralls.io/github/go-test/deep?branch=master) [](https://pkg.go.dev/github.com/go-test/deep) +[](https://goreportcard.com/report/github.com/go-test/deep) +[](https://coveralls.io/github/go-test/deep?branch=master) +[](https://pkg.go.dev/github.com/go-test/deep) This package provides a single function: `deep.Equal`. It's like [reflect.DeepEqual](http://golang.org/pkg/reflect/#DeepEqual) but much friendlier to humans (or any sentient being) for two reason: diff --git a/vendor/github.com/go-test/deep/deep.go b/vendor/github.com/go-test/deep/deep.go index dbc89c04bb9ddaa659cbe85597e1c72f268924b0..4aab66a8b467e8770e3b1c508067f2367d7dfbeb 100644 --- a/vendor/github.com/go-test/deep/deep.go +++ b/vendor/github.com/go-test/deep/deep.go @@ -27,9 +27,17 @@ var ( LogErrors = false // CompareUnexportedFields causes unexported struct fields, like s in - // T{s int}, to be compared when true. + // T{s int}, to be compared when true. This does not work for comparing + // error or Time types on unexported fields because methods on unexported + // fields cannot be called. CompareUnexportedFields = false + // CompareFunctions compares functions the same as reflect.DeepEqual: + // only two nil functions are equal. Every other combination is not equal. + // This is disabled by default because previous versions of this package + // ignored functions. Enabling it can possibly report new diffs. + CompareFunctions = false + // NilSlicesAreEmpty causes a nil slice to be equal to an empty slice. NilSlicesAreEmpty = false @@ -48,10 +56,24 @@ var ( ErrNotHandled = errors.New("cannot compare the reflect.Kind") ) +const ( + // FLAG_NONE is a placeholder for default Equal behavior. You don't have to + // pass it to Equal; if you do, it does nothing. + FLAG_NONE byte = iota + + // FLAG_IGNORE_SLICE_ORDER causes Equal to ignore slice order so that + // []int{1, 2} and []int{2, 1} are equal. Only slices of primitive scalars + // like numbers and strings are supported. Slices of complex types, + // like []T where T is a struct, are undefined because Equal does not + // recurse into the slice value when this flag is enabled. + FLAG_IGNORE_SLICE_ORDER +) + type cmp struct { diff []string buff []string floatFormat string + flag map[byte]bool } var errorType = reflect.TypeOf((*error)(nil)).Elem() @@ -66,13 +88,17 @@ var errorType = reflect.TypeOf((*error)(nil)).Elem() // // When comparing a struct, if a field has the tag `deep:"-"` then it will be // ignored. -func Equal(a, b interface{}) []string { +func Equal(a, b interface{}, flags ...interface{}) []string { aVal := reflect.ValueOf(a) bVal := reflect.ValueOf(b) c := &cmp{ diff: []string{}, buff: []string{}, floatFormat: fmt.Sprintf("%%.%df", FloatPrecision), + flag: map[byte]bool{}, + } + for i := range flags { + c.flag[flags[i].(byte)] = true } if a == nil && b == nil { return nil @@ -137,18 +163,23 @@ func (c *cmp) equals(a, b reflect.Value, level int) { 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. 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 (!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 - } + // This must be done before dereferencing because errors.New() returns a + // pointer to a struct that implements the interface: + // func (e *errorString) Error() string { + // And we check CanInterface as a hack to make sure the underlying method + // is callable because https://github.com/golang/go/issues/32438 + // Issues: + // https://github.com/go-test/deep/issues/31 + // https://github.com/go-test/deep/issues/45 + if (aType.Implements(errorType) && bType.Implements(errorType)) && + ((!aElem || !a.IsNil()) && (!bElem || !b.IsNil())) && + (a.CanInterface() && b.CanInterface()) { + 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{} @@ -326,29 +357,54 @@ func (c *cmp) equals(a, b reflect.Value, level int) { } } + // Equal if same underlying pointer and same length, this latter handles + // foo := []int{1, 2, 3, 4} + // a := foo[0:2] // == {1,2} + // b := foo[2:4] // == {3,4} + // a and b are same pointer but different slices (lengths) of the underlying + // array, so not equal. aLen := a.Len() bLen := b.Len() - if a.Pointer() == b.Pointer() && aLen == bLen { return } - n := aLen - if bLen > aLen { - n = bLen - } - for i := 0; i < n; i++ { - c.push(fmt.Sprintf("slice[%d]", i)) - if i < aLen && i < bLen { - c.equals(a.Index(i), b.Index(i), level+1) - } else if i < aLen { - c.saveDiff(a.Index(i), "<no value>") - } else { - c.saveDiff("<no value>", b.Index(i)) + if c.flag[FLAG_IGNORE_SLICE_ORDER] { + // Compare slices by value and value count; ignore order. + // Value equality is impliclity established by the maps: + // any value v1 will hash to the same map value if it's equal + // to another value v2. Then equality is determiend by value + // count: presuming v1==v2, then the slics are equal if there + // are equal numbers of v1 in each slice. + am := map[interface{}]int{} + for i := 0; i < a.Len(); i++ { + am[a.Index(i).Interface()] += 1 } - c.pop() - if len(c.diff) >= MaxDiff { - break + bm := map[interface{}]int{} + for i := 0; i < b.Len(); i++ { + bm[b.Index(i).Interface()] += 1 + } + c.cmpMapValueCounts(a, b, am, bm, true) // a cmp b + c.cmpMapValueCounts(b, a, bm, am, false) // b cmp a + } else { + // Compare slices by order + n := aLen + if bLen > aLen { + n = bLen + } + for i := 0; i < n; i++ { + c.push(fmt.Sprintf("slice[%d]", i)) + if i < aLen && i < bLen { + c.equals(a.Index(i), b.Index(i), level+1) + } else if i < aLen { + c.saveDiff(a.Index(i), "<no value>") + } else { + c.saveDiff("<no value>", b.Index(i)) + } + c.pop() + if len(c.diff) >= MaxDiff { + break + } } } @@ -385,7 +441,19 @@ func (c *cmp) equals(a, b reflect.Value, level int) { if a.String() != b.String() { c.saveDiff(a.String(), b.String()) } - + case reflect.Func: + if CompareFunctions { + if !a.IsNil() || !b.IsNil() { + aVal, bVal := "nil func", "nil func" + if !a.IsNil() { + aVal = "func" + } + if !b.IsNil() { + bVal = "func" + } + c.saveDiff(aVal, bVal) + } + } default: logError(ErrNotHandled) } @@ -410,6 +478,25 @@ func (c *cmp) saveDiff(aval, bval interface{}) { } } +func (c *cmp) cmpMapValueCounts(a, b reflect.Value, am, bm map[interface{}]int, a2b bool) { + for v := range am { + aCount, _ := am[v] + bCount, _ := bm[v] + + if aCount != bCount { + c.push(fmt.Sprintf("(unordered) slice[]=%v: value count", v)) + if a2b { + c.saveDiff(fmt.Sprintf("%d", aCount), fmt.Sprintf("%d", bCount)) + } else { + c.saveDiff(fmt.Sprintf("%d", bCount), fmt.Sprintf("%d", aCount)) + } + c.pop() + } + delete(am, v) + delete(bm, v) + } +} + func logError(err error) { if LogErrors { log.Println(err) diff --git a/vendor/modules.txt b/vendor/modules.txt index d38131a83f857cc4897ac61f55c8ab256831f8bd..3eae13c635ca7911cfd4aa2f9b11a5a8700182a1 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -190,7 +190,7 @@ github.com/go-logr/logr/funcr github.com/go-logr/stdr # github.com/go-sql-driver/mysql v1.6.0 github.com/go-sql-driver/mysql -# github.com/go-test/deep v1.0.8 +# github.com/go-test/deep v1.1.0 ## explicit github.com/go-test/deep # github.com/gogo/protobuf v1.3.2