bump gotest.tools v2.3.0, google/go-cmp v0.2.0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
6
vendor/github.com/google/go-cmp/cmp/cmpopts/equate.go
generated
vendored
6
vendor/github.com/google/go-cmp/cmp/cmpopts/equate.go
generated
vendored
@@ -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)),
|
||||
|
||||
11
vendor/github.com/google/go-cmp/cmp/cmpopts/ignore.go
generated
vendored
11
vendor/github.com/google/go-cmp/cmp/cmpopts/ignore.go
generated
vendored
@@ -50,7 +50,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 +95,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
|
||||
@@ -131,14 +131,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.
|
||||
|
||||
4
vendor/github.com/google/go-cmp/cmp/cmpopts/sort.go
generated
vendored
4
vendor/github.com/google/go-cmp/cmp/cmpopts/sort.go
generated
vendored
@@ -24,7 +24,7 @@ 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.
|
||||
// SortSlices can be used in conjunction with EquateEmpty.
|
||||
func SortSlices(less interface{}) cmp.Option {
|
||||
vf := reflect.ValueOf(less)
|
||||
if !function.IsType(vf.Type(), function.Less) || vf.IsNil() {
|
||||
@@ -95,7 +95,7 @@ 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.
|
||||
// SortMaps can be used in conjunction with EquateEmpty.
|
||||
func SortMaps(less interface{}) cmp.Option {
|
||||
vf := reflect.ValueOf(less)
|
||||
if !function.IsType(vf.Type(), function.Less) || vf.IsNil() {
|
||||
|
||||
42
vendor/github.com/google/go-cmp/cmp/compare.go
generated
vendored
42
vendor/github.com/google/go-cmp/cmp/compare.go
generated
vendored
@@ -22,7 +22,7 @@
|
||||
// equality is determined by recursively comparing the primitive kinds on both
|
||||
// values, much like reflect.DeepEqual. Unlike reflect.DeepEqual, unexported
|
||||
// fields are not compared by default; they result in panics unless suppressed
|
||||
// by using an Ignore option (see cmpopts.IgnoreUnexported) or explictly compared
|
||||
// by using an Ignore option (see cmpopts.IgnoreUnexported) or explicitly compared
|
||||
// using the AllowUnexported option.
|
||||
package cmp
|
||||
|
||||
@@ -35,7 +35,7 @@ import (
|
||||
"github.com/google/go-cmp/cmp/internal/value"
|
||||
)
|
||||
|
||||
// BUG: Maps with keys containing NaN values cannot be properly compared due to
|
||||
// BUG(dsnet): Maps with keys containing NaN values cannot be properly compared due to
|
||||
// the reflection package's inability to retrieve such entries. Equal will panic
|
||||
// anytime it comes across a NaN key, but this behavior may change.
|
||||
//
|
||||
@@ -61,8 +61,8 @@ var nothing = reflect.Value{}
|
||||
//
|
||||
// • If the values have an Equal method of the form "(T) Equal(T) bool" or
|
||||
// "(T) Equal(I) bool" where T is assignable to I, then use the result of
|
||||
// x.Equal(y). Otherwise, no such method exists and evaluation proceeds to
|
||||
// the next rule.
|
||||
// x.Equal(y) even if x or y is nil.
|
||||
// Otherwise, no such method exists and evaluation proceeds to the next rule.
|
||||
//
|
||||
// • Lastly, try to compare x and y based on their basic kinds.
|
||||
// Simple kinds like booleans, integers, floats, complex numbers, strings, and
|
||||
@@ -304,7 +304,8 @@ func (s *state) tryOptions(vx, vy reflect.Value, t reflect.Type) bool {
|
||||
|
||||
// Evaluate all filters and apply the remaining options.
|
||||
if opt := opts.filter(s, vx, vy, t); opt != nil {
|
||||
return opt.apply(s, vx, vy)
|
||||
opt.apply(s, vx, vy)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -322,6 +323,7 @@ func (s *state) tryMethod(vx, vy reflect.Value, t reflect.Type) bool {
|
||||
}
|
||||
|
||||
func (s *state) callTRFunc(f, v reflect.Value) reflect.Value {
|
||||
v = sanitizeValue(v, f.Type().In(0))
|
||||
if !s.dynChecker.Next() {
|
||||
return f.Call([]reflect.Value{v})[0]
|
||||
}
|
||||
@@ -345,6 +347,8 @@ func (s *state) callTRFunc(f, v reflect.Value) reflect.Value {
|
||||
}
|
||||
|
||||
func (s *state) callTTBFunc(f, x, y reflect.Value) bool {
|
||||
x = sanitizeValue(x, f.Type().In(0))
|
||||
y = sanitizeValue(y, f.Type().In(1))
|
||||
if !s.dynChecker.Next() {
|
||||
return f.Call([]reflect.Value{x, y})[0].Bool()
|
||||
}
|
||||
@@ -372,20 +376,40 @@ func detectRaces(c chan<- reflect.Value, f reflect.Value, vs ...reflect.Value) {
|
||||
ret = f.Call(vs)[0]
|
||||
}
|
||||
|
||||
// sanitizeValue converts nil interfaces of type T to those of type R,
|
||||
// assuming that T is assignable to R.
|
||||
// Otherwise, it returns the input value as is.
|
||||
func sanitizeValue(v reflect.Value, t reflect.Type) reflect.Value {
|
||||
// TODO(dsnet): Remove this hacky workaround.
|
||||
// See https://golang.org/issue/22143
|
||||
if v.Kind() == reflect.Interface && v.IsNil() && v.Type() != t {
|
||||
return reflect.New(t).Elem()
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func (s *state) compareArray(vx, vy reflect.Value, t reflect.Type) {
|
||||
step := &sliceIndex{pathStep{t.Elem()}, 0, 0}
|
||||
s.curPath.push(step)
|
||||
|
||||
// Compute an edit-script for slices vx and vy.
|
||||
eq, es := diff.Difference(vx.Len(), vy.Len(), func(ix, iy int) diff.Result {
|
||||
es := diff.Difference(vx.Len(), vy.Len(), func(ix, iy int) diff.Result {
|
||||
step.xkey, step.ykey = ix, iy
|
||||
return s.statelessCompare(vx.Index(ix), vy.Index(iy))
|
||||
})
|
||||
|
||||
// Equal or no edit-script, so report entire slices as is.
|
||||
if eq || es == nil {
|
||||
// Report the entire slice as is if the arrays are of primitive kind,
|
||||
// and the arrays are different enough.
|
||||
isPrimitive := false
|
||||
switch t.Elem().Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
|
||||
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,
|
||||
reflect.Bool, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128:
|
||||
isPrimitive = true
|
||||
}
|
||||
if isPrimitive && es.Dist() > (vx.Len()+vy.Len())/4 {
|
||||
s.curPath.pop() // Pop first since we are reporting the whole slice
|
||||
s.report(eq, vx, vy)
|
||||
s.report(false, vx, vy)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
2
vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go
generated
vendored
2
vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go
generated
vendored
@@ -50,7 +50,7 @@ import (
|
||||
//
|
||||
// The series of '.', 'X', 'Y', and 'M' characters at the bottom represents
|
||||
// the currently established path from the forward and reverse searches,
|
||||
// seperated by a '|' character.
|
||||
// separated by a '|' character.
|
||||
|
||||
const (
|
||||
updateDelay = 100 * time.Millisecond
|
||||
|
||||
18
vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go
generated
vendored
18
vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go
generated
vendored
@@ -106,9 +106,9 @@ func (r Result) Similar() bool {
|
||||
// Difference reports whether two lists of lengths nx and ny are equal
|
||||
// given the definition of equality provided as f.
|
||||
//
|
||||
// This function may return a edit-script, which is a sequence of operations
|
||||
// needed to convert one list into the other. If non-nil, the following
|
||||
// invariants for the edit-script are maintained:
|
||||
// This function returns an edit-script, which is a sequence of operations
|
||||
// needed to convert one list into the other. The following invariants for
|
||||
// the edit-script are maintained:
|
||||
// • eq == (es.Dist()==0)
|
||||
// • nx == es.LenX()
|
||||
// • ny == es.LenY()
|
||||
@@ -117,17 +117,7 @@ func (r Result) Similar() bool {
|
||||
// produces an edit-script with a minimal Levenshtein distance). This algorithm
|
||||
// favors performance over optimality. The exact output is not guaranteed to
|
||||
// be stable and may change over time.
|
||||
func Difference(nx, ny int, f EqualFunc) (eq bool, es EditScript) {
|
||||
es = searchGraph(nx, ny, f)
|
||||
st := es.stats()
|
||||
eq = len(es) == st.NI
|
||||
if !eq && st.NI < (nx+ny)/4 {
|
||||
return eq, nil // Edit-script more distracting than helpful
|
||||
}
|
||||
return eq, es
|
||||
}
|
||||
|
||||
func searchGraph(nx, ny int, f EqualFunc) EditScript {
|
||||
func Difference(nx, ny int, f EqualFunc) (es EditScript) {
|
||||
// This algorithm is based on traversing what is known as an "edit-graph".
|
||||
// See Figure 1 from "An O(ND) Difference Algorithm and Its Variations"
|
||||
// by Eugene W. Myers. Since D can be as large as N itself, this is
|
||||
|
||||
78
vendor/github.com/google/go-cmp/cmp/internal/value/format.go
generated
vendored
78
vendor/github.com/google/go-cmp/cmp/internal/value/format.go
generated
vendored
@@ -8,15 +8,11 @@ package value
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// formatFakePointers controls whether to substitute pointer addresses with nil.
|
||||
// This is used for deterministic testing.
|
||||
var formatFakePointers = false
|
||||
|
||||
var stringerIface = reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
|
||||
|
||||
// Format formats the value v as a string.
|
||||
@@ -26,28 +22,35 @@ var stringerIface = reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
|
||||
// * Avoids printing struct fields that are zero
|
||||
// * Prints a nil-slice as being nil, not empty
|
||||
// * Prints map entries in deterministic order
|
||||
func Format(v reflect.Value, useStringer bool) string {
|
||||
return formatAny(v, formatConfig{useStringer, true, true, !formatFakePointers}, nil)
|
||||
func Format(v reflect.Value, conf FormatConfig) string {
|
||||
conf.printType = true
|
||||
conf.followPointers = true
|
||||
conf.realPointers = true
|
||||
return formatAny(v, conf, nil)
|
||||
}
|
||||
|
||||
type formatConfig struct {
|
||||
useStringer bool // Should the String method be used if available?
|
||||
printType bool // Should we print the type before the value?
|
||||
followPointers bool // Should we recursively follow pointers?
|
||||
realPointers bool // Should we print the real address of pointers?
|
||||
type FormatConfig struct {
|
||||
UseStringer bool // Should the String method be used if available?
|
||||
printType bool // Should we print the type before the value?
|
||||
PrintPrimitiveType bool // Should we print the type of primitives?
|
||||
followPointers bool // Should we recursively follow pointers?
|
||||
realPointers bool // Should we print the real address of pointers?
|
||||
}
|
||||
|
||||
func formatAny(v reflect.Value, conf formatConfig, visited map[uintptr]bool) string {
|
||||
func formatAny(v reflect.Value, conf FormatConfig, visited map[uintptr]bool) string {
|
||||
// TODO: Should this be a multi-line printout in certain situations?
|
||||
|
||||
if !v.IsValid() {
|
||||
return "<non-existent>"
|
||||
}
|
||||
if conf.useStringer && v.Type().Implements(stringerIface) && v.CanInterface() {
|
||||
if conf.UseStringer && v.Type().Implements(stringerIface) && v.CanInterface() {
|
||||
if (v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface) && v.IsNil() {
|
||||
return "<nil>"
|
||||
}
|
||||
return fmt.Sprintf("%q", v.Interface().(fmt.Stringer).String())
|
||||
|
||||
const stringerPrefix = "s" // Indicates that the String method was used
|
||||
s := v.Interface().(fmt.Stringer).String()
|
||||
return stringerPrefix + formatString(s)
|
||||
}
|
||||
|
||||
switch v.Kind() {
|
||||
@@ -66,7 +69,7 @@ func formatAny(v reflect.Value, conf formatConfig, visited map[uintptr]bool) str
|
||||
case reflect.Complex64, reflect.Complex128:
|
||||
return formatPrimitive(v.Type(), v.Complex(), conf)
|
||||
case reflect.String:
|
||||
return formatPrimitive(v.Type(), fmt.Sprintf("%q", v), conf)
|
||||
return formatPrimitive(v.Type(), formatString(v.String()), conf)
|
||||
case reflect.UnsafePointer, reflect.Chan, reflect.Func:
|
||||
return formatPointer(v, conf)
|
||||
case reflect.Ptr:
|
||||
@@ -127,11 +130,13 @@ func formatAny(v reflect.Value, conf formatConfig, visited map[uintptr]bool) str
|
||||
visited = insertPointer(visited, v.Pointer())
|
||||
|
||||
var ss []string
|
||||
subConf := conf
|
||||
subConf.printType = v.Type().Elem().Kind() == reflect.Interface
|
||||
keyConf, valConf := conf, conf
|
||||
keyConf.printType = v.Type().Key().Kind() == reflect.Interface
|
||||
keyConf.followPointers = false
|
||||
valConf.printType = v.Type().Elem().Kind() == reflect.Interface
|
||||
for _, k := range SortKeys(v.MapKeys()) {
|
||||
sk := formatAny(k, formatConfig{realPointers: conf.realPointers}, visited)
|
||||
sv := formatAny(v.MapIndex(k), subConf, visited)
|
||||
sk := formatAny(k, keyConf, visited)
|
||||
sv := formatAny(v.MapIndex(k), valConf, visited)
|
||||
ss = append(ss, fmt.Sprintf("%s: %s", sk, sv))
|
||||
}
|
||||
s := fmt.Sprintf("{%s}", strings.Join(ss, ", "))
|
||||
@@ -149,7 +154,7 @@ func formatAny(v reflect.Value, conf formatConfig, visited map[uintptr]bool) str
|
||||
continue // Elide zero value fields
|
||||
}
|
||||
name := v.Type().Field(i).Name
|
||||
subConf.useStringer = conf.useStringer && isExported(name)
|
||||
subConf.UseStringer = conf.UseStringer
|
||||
s := formatAny(vv, subConf, visited)
|
||||
ss = append(ss, fmt.Sprintf("%s: %s", name, s))
|
||||
}
|
||||
@@ -163,14 +168,33 @@ func formatAny(v reflect.Value, conf formatConfig, visited map[uintptr]bool) str
|
||||
}
|
||||
}
|
||||
|
||||
func formatPrimitive(t reflect.Type, v interface{}, conf formatConfig) string {
|
||||
if conf.printType && t.PkgPath() != "" {
|
||||
func formatString(s string) string {
|
||||
// Use quoted string if it the same length as a raw string literal.
|
||||
// Otherwise, attempt to use the raw string form.
|
||||
qs := strconv.Quote(s)
|
||||
if len(qs) == 1+len(s)+1 {
|
||||
return qs
|
||||
}
|
||||
|
||||
// Disallow newlines to ensure output is a single line.
|
||||
// Only allow printable runes for readability purposes.
|
||||
rawInvalid := func(r rune) bool {
|
||||
return r == '`' || r == '\n' || !unicode.IsPrint(r)
|
||||
}
|
||||
if strings.IndexFunc(s, rawInvalid) < 0 {
|
||||
return "`" + s + "`"
|
||||
}
|
||||
return qs
|
||||
}
|
||||
|
||||
func formatPrimitive(t reflect.Type, v interface{}, conf FormatConfig) string {
|
||||
if conf.printType && (conf.PrintPrimitiveType || t.PkgPath() != "") {
|
||||
return fmt.Sprintf("%v(%v)", t, v)
|
||||
}
|
||||
return fmt.Sprintf("%v", v)
|
||||
}
|
||||
|
||||
func formatPointer(v reflect.Value, conf formatConfig) string {
|
||||
func formatPointer(v reflect.Value, conf FormatConfig) string {
|
||||
p := v.Pointer()
|
||||
if !conf.realPointers {
|
||||
p = 0 // For deterministic printing purposes
|
||||
@@ -251,9 +275,3 @@ func isZero(v reflect.Value) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// isExported reports whether the identifier is exported.
|
||||
func isExported(id string) bool {
|
||||
r, _ := utf8.DecodeRuneInString(id)
|
||||
return unicode.IsUpper(r)
|
||||
}
|
||||
|
||||
2
vendor/github.com/google/go-cmp/cmp/internal/value/sort.go
generated
vendored
2
vendor/github.com/google/go-cmp/cmp/internal/value/sort.go
generated
vendored
@@ -24,7 +24,7 @@ func SortKeys(vs []reflect.Value) []reflect.Value {
|
||||
// Deduplicate keys (fails for NaNs).
|
||||
vs2 := vs[:1]
|
||||
for _, v := range vs[1:] {
|
||||
if v.Interface() != vs2[len(vs2)-1].Interface() {
|
||||
if isLess(vs2[len(vs2)-1], v) {
|
||||
vs2 = append(vs2, v)
|
||||
}
|
||||
}
|
||||
|
||||
37
vendor/github.com/google/go-cmp/cmp/options.go
generated
vendored
37
vendor/github.com/google/go-cmp/cmp/options.go
generated
vendored
@@ -38,9 +38,8 @@ type Option interface {
|
||||
type applicableOption interface {
|
||||
Option
|
||||
|
||||
// apply executes the option and reports whether the option was applied.
|
||||
// Each option may mutate s.
|
||||
apply(s *state, vx, vy reflect.Value) bool
|
||||
// apply executes the option, which may mutate s or panic.
|
||||
apply(s *state, vx, vy reflect.Value)
|
||||
}
|
||||
|
||||
// coreOption represents the following types:
|
||||
@@ -85,7 +84,7 @@ func (opts Options) filter(s *state, vx, vy reflect.Value, t reflect.Type) (out
|
||||
return out
|
||||
}
|
||||
|
||||
func (opts Options) apply(s *state, _, _ reflect.Value) bool {
|
||||
func (opts Options) apply(s *state, _, _ reflect.Value) {
|
||||
const warning = "ambiguous set of applicable options"
|
||||
const help = "consider using filters to ensure at most one Comparer or Transformer may apply"
|
||||
var ss []string
|
||||
@@ -196,7 +195,7 @@ type ignore struct{ core }
|
||||
|
||||
func (ignore) isFiltered() bool { return false }
|
||||
func (ignore) filter(_ *state, _, _ reflect.Value, _ reflect.Type) applicableOption { return ignore{} }
|
||||
func (ignore) apply(_ *state, _, _ reflect.Value) bool { return true }
|
||||
func (ignore) apply(_ *state, _, _ reflect.Value) { return }
|
||||
func (ignore) String() string { return "Ignore()" }
|
||||
|
||||
// invalid is a sentinel Option type to indicate that some options could not
|
||||
@@ -204,7 +203,7 @@ func (ignore) String() string
|
||||
type invalid struct{ core }
|
||||
|
||||
func (invalid) filter(_ *state, _, _ reflect.Value, _ reflect.Type) applicableOption { return invalid{} }
|
||||
func (invalid) apply(s *state, _, _ reflect.Value) bool {
|
||||
func (invalid) apply(s *state, _, _ reflect.Value) {
|
||||
const help = "consider using AllowUnexported or cmpopts.IgnoreUnexported"
|
||||
panic(fmt.Sprintf("cannot handle unexported field: %#v\n%s", s.curPath, help))
|
||||
}
|
||||
@@ -215,9 +214,12 @@ func (invalid) apply(s *state, _, _ reflect.Value) bool {
|
||||
// The transformer f must be a function "func(T) R" that converts values of
|
||||
// type T to those of type R and is implicitly filtered to input values
|
||||
// assignable to T. The transformer must not mutate T in any way.
|
||||
// If T and R are the same type, an additional filter must be applied to
|
||||
// act as the base case to prevent an infinite recursion applying the same
|
||||
// transform to itself (see the SortedSlice example).
|
||||
//
|
||||
// To help prevent some cases of infinite recursive cycles applying the
|
||||
// same transform to the output of itself (e.g., in the case where the
|
||||
// input and output types are the same), an implicit filter is added such that
|
||||
// a transformer is applicable only if that exact transformer is not already
|
||||
// in the tail of the Path since the last non-Transform step.
|
||||
//
|
||||
// The name is a user provided label that is used as the Transform.Name in the
|
||||
// transformation PathStep. If empty, an arbitrary name is used.
|
||||
@@ -248,14 +250,21 @@ type transformer struct {
|
||||
|
||||
func (tr *transformer) isFiltered() bool { return tr.typ != nil }
|
||||
|
||||
func (tr *transformer) filter(_ *state, _, _ reflect.Value, t reflect.Type) applicableOption {
|
||||
func (tr *transformer) filter(s *state, _, _ reflect.Value, t reflect.Type) applicableOption {
|
||||
for i := len(s.curPath) - 1; i >= 0; i-- {
|
||||
if t, ok := s.curPath[i].(*transform); !ok {
|
||||
break // Hit most recent non-Transform step
|
||||
} else if tr == t.trans {
|
||||
return nil // Cannot directly use same Transform
|
||||
}
|
||||
}
|
||||
if tr.typ == nil || t.AssignableTo(tr.typ) {
|
||||
return tr
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tr *transformer) apply(s *state, vx, vy reflect.Value) bool {
|
||||
func (tr *transformer) apply(s *state, vx, vy reflect.Value) {
|
||||
// Update path before calling the Transformer so that dynamic checks
|
||||
// will use the updated path.
|
||||
s.curPath.push(&transform{pathStep{tr.fnc.Type().Out(0)}, tr})
|
||||
@@ -264,7 +273,6 @@ func (tr *transformer) apply(s *state, vx, vy reflect.Value) bool {
|
||||
vx = s.callTRFunc(tr.fnc, vx)
|
||||
vy = s.callTRFunc(tr.fnc, vy)
|
||||
s.compareAny(vx, vy)
|
||||
return true
|
||||
}
|
||||
|
||||
func (tr transformer) String() string {
|
||||
@@ -310,10 +318,9 @@ func (cm *comparer) filter(_ *state, _, _ reflect.Value, t reflect.Type) applica
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cm *comparer) apply(s *state, vx, vy reflect.Value) bool {
|
||||
func (cm *comparer) apply(s *state, vx, vy reflect.Value) {
|
||||
eq := s.callTTBFunc(cm.fnc, vx, vy)
|
||||
s.report(eq, vx, vy)
|
||||
return true
|
||||
}
|
||||
|
||||
func (cm comparer) String() string {
|
||||
@@ -348,7 +355,7 @@ func (cm comparer) String() string {
|
||||
// all unexported fields on specified struct types.
|
||||
func AllowUnexported(types ...interface{}) Option {
|
||||
if !supportAllowUnexported {
|
||||
panic("AllowUnexported is not supported on App Engine Classic or GopherJS")
|
||||
panic("AllowUnexported is not supported on purego builds, Google App Engine Standard, or GopherJS")
|
||||
}
|
||||
m := make(map[reflect.Type]bool)
|
||||
for _, typ := range types {
|
||||
|
||||
36
vendor/github.com/google/go-cmp/cmp/path.go
generated
vendored
36
vendor/github.com/google/go-cmp/cmp/path.go
generated
vendored
@@ -79,6 +79,11 @@ type (
|
||||
PathStep
|
||||
Name() string
|
||||
Func() reflect.Value
|
||||
|
||||
// Option returns the originally constructed Transformer option.
|
||||
// The == operator can be used to detect the exact option used.
|
||||
Option() Option
|
||||
|
||||
isTransform()
|
||||
}
|
||||
)
|
||||
@@ -94,10 +99,21 @@ func (pa *Path) pop() {
|
||||
// Last returns the last PathStep in the Path.
|
||||
// If the path is empty, this returns a non-nil PathStep that reports a nil Type.
|
||||
func (pa Path) Last() PathStep {
|
||||
if len(pa) > 0 {
|
||||
return pa[len(pa)-1]
|
||||
return pa.Index(-1)
|
||||
}
|
||||
|
||||
// Index returns the ith step in the Path and supports negative indexing.
|
||||
// A negative index starts counting from the tail of the Path such that -1
|
||||
// refers to the last step, -2 refers to the second-to-last step, and so on.
|
||||
// If index is invalid, this returns a non-nil PathStep that reports a nil Type.
|
||||
func (pa Path) Index(i int) PathStep {
|
||||
if i < 0 {
|
||||
i = len(pa) + i
|
||||
}
|
||||
return pathStep{}
|
||||
if i < 0 || i >= len(pa) {
|
||||
return pathStep{}
|
||||
}
|
||||
return pa[i]
|
||||
}
|
||||
|
||||
// String returns the simplified path to a node.
|
||||
@@ -150,13 +166,12 @@ func (pa Path) GoString() string {
|
||||
ssPost = append(ssPost, ")")
|
||||
continue
|
||||
case *typeAssertion:
|
||||
// Elide type assertions immediately following a transform to
|
||||
// prevent overly verbose path printouts.
|
||||
// Some transforms return interface{} because of Go's lack of
|
||||
// generics, but typically take in and return the exact same
|
||||
// concrete type. Other times, the transform creates an anonymous
|
||||
// struct, which will be very verbose to print.
|
||||
if _, ok := nextStep.(*transform); ok {
|
||||
// As a special-case, elide type assertions on anonymous types
|
||||
// since they are typically generated dynamically and can be very
|
||||
// verbose. For example, some transforms return interface{} because
|
||||
// of Go's lack of generics, but typically take in and return the
|
||||
// exact same concrete type.
|
||||
if s.Type().PkgPath() == "" {
|
||||
continue
|
||||
}
|
||||
}
|
||||
@@ -250,6 +265,7 @@ func (sf structField) Name() string { return sf.name }
|
||||
func (sf structField) Index() int { return sf.idx }
|
||||
func (tf transform) Name() string { return tf.trans.name }
|
||||
func (tf transform) Func() reflect.Value { return tf.trans.fnc }
|
||||
func (tf transform) Option() Option { return tf.trans }
|
||||
|
||||
func (pathStep) isPathStep() {}
|
||||
func (sliceIndex) isSliceIndex() {}
|
||||
|
||||
12
vendor/github.com/google/go-cmp/cmp/reporter.go
generated
vendored
12
vendor/github.com/google/go-cmp/cmp/reporter.go
generated
vendored
@@ -30,12 +30,12 @@ func (r *defaultReporter) Report(x, y reflect.Value, eq bool, p Path) {
|
||||
const maxLines = 256
|
||||
r.ndiffs++
|
||||
if r.nbytes < maxBytes && r.nlines < maxLines {
|
||||
sx := value.Format(x, true)
|
||||
sy := value.Format(y, true)
|
||||
sx := value.Format(x, value.FormatConfig{UseStringer: true})
|
||||
sy := value.Format(y, value.FormatConfig{UseStringer: true})
|
||||
if sx == sy {
|
||||
// Stringer is not helpful, so rely on more exact formatting.
|
||||
sx = value.Format(x, false)
|
||||
sy = value.Format(y, false)
|
||||
// Unhelpful output, so use more exact formatting.
|
||||
sx = value.Format(x, value.FormatConfig{PrintPrimitiveType: true})
|
||||
sy = value.Format(y, value.FormatConfig{PrintPrimitiveType: true})
|
||||
}
|
||||
s := fmt.Sprintf("%#v:\n\t-: %s\n\t+: %s\n", p, sx, sy)
|
||||
r.diffs = append(r.diffs, s)
|
||||
@@ -49,5 +49,5 @@ func (r *defaultReporter) String() string {
|
||||
if r.ndiffs == len(r.diffs) {
|
||||
return s
|
||||
}
|
||||
return fmt.Sprintf("%s... %d more differences ...", s, len(r.diffs)-r.ndiffs)
|
||||
return fmt.Sprintf("%s... %d more differences ...", s, r.ndiffs-len(r.diffs))
|
||||
}
|
||||
|
||||
2
vendor/github.com/google/go-cmp/cmp/unsafe_panic.go
generated
vendored
2
vendor/github.com/google/go-cmp/cmp/unsafe_panic.go
generated
vendored
@@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE.md file.
|
||||
|
||||
// +build appengine js
|
||||
// +build purego appengine js
|
||||
|
||||
package cmp
|
||||
|
||||
|
||||
2
vendor/github.com/google/go-cmp/cmp/unsafe_reflect.go
generated
vendored
2
vendor/github.com/google/go-cmp/cmp/unsafe_reflect.go
generated
vendored
@@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE.md file.
|
||||
|
||||
// +build !appengine,!js
|
||||
// +build !purego,!appengine,!js
|
||||
|
||||
package cmp
|
||||
|
||||
|
||||
Reference in New Issue
Block a user