From f51ae9765f195bb6491b604afec2002b5cbe668b Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Tue, 12 Mar 2019 11:24:17 +0100 Subject: vendor/github.com/google/go-cmp: update to HEAD To pick up fix for: https://github.com/google/go-cmp/issues/103 --- .../github.com/google/go-cmp/cmp/cmpopts/equate.go | 6 +- .../github.com/google/go-cmp/cmp/cmpopts/ignore.go | 73 +++++++++++++++++++--- .../github.com/google/go-cmp/cmp/cmpopts/sort.go | 37 +++++------ .../google/go-cmp/cmp/cmpopts/sort_go17.go | 46 -------------- .../google/go-cmp/cmp/cmpopts/sort_go18.go | 31 --------- .../github.com/google/go-cmp/cmp/cmpopts/xform.go | 35 +++++++++++ 6 files changed, 123 insertions(+), 105 deletions(-) delete mode 100644 vendor/github.com/google/go-cmp/cmp/cmpopts/sort_go17.go delete mode 100644 vendor/github.com/google/go-cmp/cmp/cmpopts/sort_go18.go create mode 100644 vendor/github.com/google/go-cmp/cmp/cmpopts/xform.go (limited to 'vendor/github.com/google/go-cmp/cmp/cmpopts') diff --git a/vendor/github.com/google/go-cmp/cmp/cmpopts/equate.go b/vendor/github.com/google/go-cmp/cmp/cmpopts/equate.go index cc39492cf..41bbddc61 100644 --- a/vendor/github.com/google/go-cmp/cmp/cmpopts/equate.go +++ b/vendor/github.com/google/go-cmp/cmp/cmpopts/equate.go @@ -17,7 +17,7 @@ func equateAlways(_, _ interface{}) bool { return true } // EquateEmpty returns a Comparer option that determines all maps and slices // with a length of zero to be equal, regardless of whether they are nil. // -// EquateEmpty can be used in conjuction with SortSlices and SortMaps. +// EquateEmpty can be used in conjunction with SortSlices and SortMaps. func EquateEmpty() cmp.Option { return cmp.FilterValues(isEmpty, cmp.Comparer(equateAlways)) } @@ -42,7 +42,7 @@ func isEmpty(x, y interface{}) bool { // The mathematical expression used is equivalent to: // |x-y| ≤ max(fraction*min(|x|, |y|), margin) // -// EquateApprox can be used in conjuction with EquateNaNs. +// EquateApprox can be used in conjunction with EquateNaNs. func EquateApprox(fraction, margin float64) cmp.Option { if margin < 0 || fraction < 0 || math.IsNaN(margin) || math.IsNaN(fraction) { panic("margin or fraction must be a non-negative number") @@ -73,7 +73,7 @@ func (a approximator) compareF32(x, y float32) bool { // EquateNaNs returns a Comparer option that determines float32 and float64 // NaN values to be equal. // -// EquateNaNs can be used in conjuction with EquateApprox. +// EquateNaNs can be used in conjunction with EquateApprox. func EquateNaNs() cmp.Option { return cmp.Options{ cmp.FilterValues(areNaNsF64s, cmp.Comparer(equateAlways)), diff --git a/vendor/github.com/google/go-cmp/cmp/cmpopts/ignore.go b/vendor/github.com/google/go-cmp/cmp/cmpopts/ignore.go index 016891da3..ff8e785d4 100644 --- a/vendor/github.com/google/go-cmp/cmp/cmpopts/ignore.go +++ b/vendor/github.com/google/go-cmp/cmp/cmpopts/ignore.go @@ -11,6 +11,7 @@ import ( "unicode/utf8" "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/internal/function" ) // IgnoreFields returns an Option that ignores exported fields of the @@ -50,7 +51,7 @@ func (tf typeFilter) filter(p cmp.Path) bool { if len(p) < 1 { return false } - t := p[len(p)-1].Type() + t := p.Last().Type() for _, ti := range tf { if t.AssignableTo(ti) { return true @@ -95,7 +96,7 @@ func (tf ifaceFilter) filter(p cmp.Path) bool { if len(p) < 1 { return false } - t := p[len(p)-1].Type() + t := p.Last().Type() for _, ti := range tf { if t.AssignableTo(ti) { return true @@ -112,6 +113,10 @@ func (tf ifaceFilter) filter(p cmp.Path) bool { // In particular, unexported fields within the struct's exported fields // of struct types, including anonymous fields, will not be ignored unless the // type of the field itself is also passed to IgnoreUnexported. +// +// Avoid ignoring unexported fields of a type which you do not control (i.e. a +// type from another repository), as changes to the implementation of such types +// may change how the comparison behaves. Prefer a custom Comparer instead. func IgnoreUnexported(typs ...interface{}) cmp.Option { ux := newUnexportedFilter(typs...) return cmp.FilterPath(ux.filter, cmp.Ignore()) @@ -131,14 +136,11 @@ func newUnexportedFilter(typs ...interface{}) unexportedFilter { return ux } func (xf unexportedFilter) filter(p cmp.Path) bool { - if len(p) < 2 { - return false - } - sf, ok := p[len(p)-1].(cmp.StructField) + sf, ok := p.Index(-1).(cmp.StructField) if !ok { return false } - return xf.m[p[len(p)-2].Type()] && !isExported(sf.Name()) + return xf.m[p.Index(-2).Type()] && !isExported(sf.Name()) } // isExported reports whether the identifier is exported. @@ -146,3 +148,60 @@ func isExported(id string) bool { r, _ := utf8.DecodeRuneInString(id) return unicode.IsUpper(r) } + +// IgnoreSliceElements returns an Option that ignores elements of []V. +// The discard function must be of the form "func(T) bool" which is used to +// ignore slice elements of type V, where V is assignable to T. +// Elements are ignored if the function reports true. +func IgnoreSliceElements(discardFunc interface{}) cmp.Option { + vf := reflect.ValueOf(discardFunc) + if !function.IsType(vf.Type(), function.ValuePredicate) || vf.IsNil() { + panic(fmt.Sprintf("invalid discard function: %T", discardFunc)) + } + return cmp.FilterPath(func(p cmp.Path) bool { + si, ok := p.Index(-1).(cmp.SliceIndex) + if !ok { + return false + } + if !si.Type().AssignableTo(vf.Type().In(0)) { + return false + } + vx, vy := si.Values() + if vx.IsValid() && vf.Call([]reflect.Value{vx})[0].Bool() { + return true + } + if vy.IsValid() && vf.Call([]reflect.Value{vy})[0].Bool() { + return true + } + return false + }, cmp.Ignore()) +} + +// IgnoreMapEntries returns an Option that ignores entries of map[K]V. +// The discard function must be of the form "func(T, R) bool" which is used to +// ignore map entries of type K and V, where K and V are assignable to T and R. +// Entries are ignored if the function reports true. +func IgnoreMapEntries(discardFunc interface{}) cmp.Option { + vf := reflect.ValueOf(discardFunc) + if !function.IsType(vf.Type(), function.KeyValuePredicate) || vf.IsNil() { + panic(fmt.Sprintf("invalid discard function: %T", discardFunc)) + } + return cmp.FilterPath(func(p cmp.Path) bool { + mi, ok := p.Index(-1).(cmp.MapIndex) + if !ok { + return false + } + if !mi.Key().Type().AssignableTo(vf.Type().In(0)) || !mi.Type().AssignableTo(vf.Type().In(1)) { + return false + } + k := mi.Key() + vx, vy := mi.Values() + if vx.IsValid() && vf.Call([]reflect.Value{k, vx})[0].Bool() { + return true + } + if vy.IsValid() && vf.Call([]reflect.Value{k, vy})[0].Bool() { + return true + } + return false + }, cmp.Ignore()) +} diff --git a/vendor/github.com/google/go-cmp/cmp/cmpopts/sort.go b/vendor/github.com/google/go-cmp/cmp/cmpopts/sort.go index a566d240b..3a4804621 100644 --- a/vendor/github.com/google/go-cmp/cmp/cmpopts/sort.go +++ b/vendor/github.com/google/go-cmp/cmp/cmpopts/sort.go @@ -7,6 +7,7 @@ package cmpopts import ( "fmt" "reflect" + "sort" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/internal/function" @@ -24,14 +25,14 @@ import ( // The less function does not have to be "total". That is, if !less(x, y) and // !less(y, x) for two elements x and y, their relative order is maintained. // -// SortSlices can be used in conjuction with EquateEmpty. -func SortSlices(less interface{}) cmp.Option { - vf := reflect.ValueOf(less) +// SortSlices can be used in conjunction with EquateEmpty. +func SortSlices(lessFunc interface{}) cmp.Option { + vf := reflect.ValueOf(lessFunc) if !function.IsType(vf.Type(), function.Less) || vf.IsNil() { - panic(fmt.Sprintf("invalid less function: %T", less)) + panic(fmt.Sprintf("invalid less function: %T", lessFunc)) } ss := sliceSorter{vf.Type().In(0), vf} - return cmp.FilterValues(ss.filter, cmp.Transformer("Sort", ss.sort)) + return cmp.FilterValues(ss.filter, cmp.Transformer("cmpopts.SortSlices", ss.sort)) } type sliceSorter struct { @@ -48,8 +49,8 @@ func (ss sliceSorter) filter(x, y interface{}) bool { } // Check whether the slices are already sorted to avoid an infinite // recursion cycle applying the same transform to itself. - ok1 := sliceIsSorted(x, func(i, j int) bool { return ss.less(vx, i, j) }) - ok2 := sliceIsSorted(y, func(i, j int) bool { return ss.less(vy, i, j) }) + ok1 := sort.SliceIsSorted(x, func(i, j int) bool { return ss.less(vx, i, j) }) + ok2 := sort.SliceIsSorted(y, func(i, j int) bool { return ss.less(vy, i, j) }) return !ok1 || !ok2 } func (ss sliceSorter) sort(x interface{}) interface{} { @@ -58,7 +59,7 @@ func (ss sliceSorter) sort(x interface{}) interface{} { for i := 0; i < src.Len(); i++ { dst.Index(i).Set(src.Index(i)) } - sortSliceStable(dst.Interface(), func(i, j int) bool { return ss.less(dst, i, j) }) + sort.SliceStable(dst.Interface(), func(i, j int) bool { return ss.less(dst, i, j) }) ss.checkSort(dst) return dst.Interface() } @@ -95,14 +96,14 @@ func (ss sliceSorter) less(v reflect.Value, i, j int) bool { // • Transitive: if !less(x, y) and !less(y, z), then !less(x, z) // • Total: if x != y, then either less(x, y) or less(y, x) // -// SortMaps can be used in conjuction with EquateEmpty. -func SortMaps(less interface{}) cmp.Option { - vf := reflect.ValueOf(less) +// SortMaps can be used in conjunction with EquateEmpty. +func SortMaps(lessFunc interface{}) cmp.Option { + vf := reflect.ValueOf(lessFunc) if !function.IsType(vf.Type(), function.Less) || vf.IsNil() { - panic(fmt.Sprintf("invalid less function: %T", less)) + panic(fmt.Sprintf("invalid less function: %T", lessFunc)) } ms := mapSorter{vf.Type().In(0), vf} - return cmp.FilterValues(ms.filter, cmp.Transformer("Sort", ms.sort)) + return cmp.FilterValues(ms.filter, cmp.Transformer("cmpopts.SortMaps", ms.sort)) } type mapSorter struct { @@ -118,7 +119,10 @@ func (ms mapSorter) filter(x, y interface{}) bool { } func (ms mapSorter) sort(x interface{}) interface{} { src := reflect.ValueOf(x) - outType := mapEntryType(src.Type()) + outType := reflect.StructOf([]reflect.StructField{ + {Name: "K", Type: src.Type().Key()}, + {Name: "V", Type: src.Type().Elem()}, + }) dst := reflect.MakeSlice(reflect.SliceOf(outType), src.Len(), src.Len()) for i, k := range src.MapKeys() { v := reflect.New(outType).Elem() @@ -126,7 +130,7 @@ func (ms mapSorter) sort(x interface{}) interface{} { v.Field(1).Set(src.MapIndex(k)) dst.Index(i).Set(v) } - sortSlice(dst.Interface(), func(i, j int) bool { return ms.less(dst, i, j) }) + sort.Slice(dst.Interface(), func(i, j int) bool { return ms.less(dst, i, j) }) ms.checkSort(dst) return dst.Interface() } @@ -139,8 +143,5 @@ func (ms mapSorter) checkSort(v reflect.Value) { } func (ms mapSorter) less(v reflect.Value, i, j int) bool { vx, vy := v.Index(i).Field(0), v.Index(j).Field(0) - if !hasReflectStructOf { - vx, vy = vx.Elem(), vy.Elem() - } return ms.fnc.Call([]reflect.Value{vx, vy})[0].Bool() } diff --git a/vendor/github.com/google/go-cmp/cmp/cmpopts/sort_go17.go b/vendor/github.com/google/go-cmp/cmp/cmpopts/sort_go17.go deleted file mode 100644 index 839b88ca4..000000000 --- a/vendor/github.com/google/go-cmp/cmp/cmpopts/sort_go17.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2017, The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE.md file. - -// +build !go1.8 - -package cmpopts - -import ( - "reflect" - "sort" -) - -const hasReflectStructOf = false - -func mapEntryType(reflect.Type) reflect.Type { - return reflect.TypeOf(struct{ K, V interface{} }{}) -} - -func sliceIsSorted(slice interface{}, less func(i, j int) bool) bool { - return sort.IsSorted(reflectSliceSorter{reflect.ValueOf(slice), less}) -} -func sortSlice(slice interface{}, less func(i, j int) bool) { - sort.Sort(reflectSliceSorter{reflect.ValueOf(slice), less}) -} -func sortSliceStable(slice interface{}, less func(i, j int) bool) { - sort.Stable(reflectSliceSorter{reflect.ValueOf(slice), less}) -} - -type reflectSliceSorter struct { - slice reflect.Value - less func(i, j int) bool -} - -func (ss reflectSliceSorter) Len() int { - return ss.slice.Len() -} -func (ss reflectSliceSorter) Less(i, j int) bool { - return ss.less(i, j) -} -func (ss reflectSliceSorter) Swap(i, j int) { - vi := ss.slice.Index(i).Interface() - vj := ss.slice.Index(j).Interface() - ss.slice.Index(i).Set(reflect.ValueOf(vj)) - ss.slice.Index(j).Set(reflect.ValueOf(vi)) -} diff --git a/vendor/github.com/google/go-cmp/cmp/cmpopts/sort_go18.go b/vendor/github.com/google/go-cmp/cmp/cmpopts/sort_go18.go deleted file mode 100644 index 8a59c0d38..000000000 --- a/vendor/github.com/google/go-cmp/cmp/cmpopts/sort_go18.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2017, The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE.md file. - -// +build go1.8 - -package cmpopts - -import ( - "reflect" - "sort" -) - -const hasReflectStructOf = true - -func mapEntryType(t reflect.Type) reflect.Type { - return reflect.StructOf([]reflect.StructField{ - {Name: "K", Type: t.Key()}, - {Name: "V", Type: t.Elem()}, - }) -} - -func sliceIsSorted(slice interface{}, less func(i, j int) bool) bool { - return sort.SliceIsSorted(slice, less) -} -func sortSlice(slice interface{}, less func(i, j int) bool) { - sort.Slice(slice, less) -} -func sortSliceStable(slice interface{}, less func(i, j int) bool) { - sort.SliceStable(slice, less) -} diff --git a/vendor/github.com/google/go-cmp/cmp/cmpopts/xform.go b/vendor/github.com/google/go-cmp/cmp/cmpopts/xform.go new file mode 100644 index 000000000..9d651553d --- /dev/null +++ b/vendor/github.com/google/go-cmp/cmp/cmpopts/xform.go @@ -0,0 +1,35 @@ +// Copyright 2018, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +package cmpopts + +import ( + "github.com/google/go-cmp/cmp" +) + +type xformFilter struct{ xform cmp.Option } + +func (xf xformFilter) filter(p cmp.Path) bool { + for _, ps := range p { + if t, ok := ps.(cmp.Transform); ok && t.Option() == xf.xform { + return false + } + } + return true +} + +// AcyclicTransformer returns a Transformer with a filter applied that ensures +// that the transformer cannot be recursively applied upon its own output. +// +// An example use case is a transformer that splits a string by lines: +// AcyclicTransformer("SplitLines", func(s string) []string{ +// return strings.Split(s, "\n") +// }) +// +// Had this been an unfiltered Transformer instead, this would result in an +// infinite cycle converting a string to []string to [][]string and so on. +func AcyclicTransformer(name string, xformFunc interface{}) cmp.Option { + xf := xformFilter{cmp.Transformer(name, xformFunc)} + return cmp.FilterPath(xf.filter, xf.xform) +} -- cgit mrf-deployment