aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Willemsen <dwillemsen@google.com>2022-03-30 00:21:51 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2022-03-30 00:21:51 +0000
commitdc0bb5f896735a80840881206dec5ce4b555c179 (patch)
tree740cf616383317a58c11695d1c5cf7c47f4c6e79
parent69c354c47fa87cab01c05cef1b9b814a4ecc411a (diff)
parent54a4cc70bedfc1e1c9b09291982055bb5e5932ce (diff)
downloadgo-cmp-dc0bb5f896735a80840881206dec5ce4b555c179.tar.gz
Merge tag 'v0.5.7' am: 54a4cc70be
Original change: https://android-review.googlesource.com/c/platform/external/go-cmp/+/2047006 Change-Id: I2bbabb46fbdcb32817f7842f50c574404f40dffe Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--.github/workflows/test.yml4
-rw-r--r--Android.gen.bp1
-rw-r--r--METADATA8
-rw-r--r--README.md4
-rw-r--r--cmp/cmpopts/equate.go2
-rw-r--r--cmp/cmpopts/errors_go113.go1
-rw-r--r--cmp/cmpopts/errors_xerrors.go1
-rw-r--r--cmp/compare.go17
-rw-r--r--cmp/compare_test.go68
-rw-r--r--cmp/example_test.go8
-rw-r--r--cmp/export_panic.go1
-rw-r--r--cmp/export_unsafe.go1
-rw-r--r--cmp/internal/diff/debug_disable.go1
-rw-r--r--cmp/internal/diff/debug_enable.go1
-rw-r--r--cmp/internal/flags/toolchain_legacy.go10
-rw-r--r--cmp/internal/flags/toolchain_recent.go10
-rw-r--r--cmp/internal/value/name.go7
-rw-r--r--cmp/internal/value/name_test.go2
-rw-r--r--cmp/internal/value/pointer_purego.go1
-rw-r--r--cmp/internal/value/pointer_unsafe.go1
-rw-r--r--cmp/path.go2
-rw-r--r--cmp/report_reflect.go3
-rw-r--r--cmp/report_slices.go6
-rw-r--r--cmp/testdata/diffs90
-rw-r--r--go.mod2
25 files changed, 146 insertions, 106 deletions
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 6b1b1c4..5664da6 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -9,7 +9,7 @@ jobs:
working-directory: ${{ env.GOPATH }}/src/github.com/${{ github.repository }}
strategy:
matrix:
- go-version: [1.8.x, 1.9.x, 1.10.x, 1.11.x, 1.12.x, 1.13.x, 1.14.x, 1.15.x, 1.16.x]
+ go-version: [1.11.x, 1.12.x, 1.13.x, 1.14.x, 1.15.x, 1.16.x, 1.17.x]
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
@@ -26,5 +26,5 @@ jobs:
- name: Test
run: go test -v -race ./...
- name: Format
- if: matrix.go-version == '1.16.x'
+ if: matrix.go-version == '1.17.x'
run: diff -u <(echo -n) <(gofmt -d .)
diff --git a/Android.gen.bp b/Android.gen.bp
index 3472b6a..0f9c559 100644
--- a/Android.gen.bp
+++ b/Android.gen.bp
@@ -66,7 +66,6 @@ bootstrap_go_package {
pkgPath: "github.com/google/go-cmp/cmp/internal/flags",
srcs: [
"cmp/internal/flags/flags.go",
- "cmp/internal/flags/toolchain_recent.go",
],
}
diff --git a/METADATA b/METADATA
index c90ae19..5615722 100644
--- a/METADATA
+++ b/METADATA
@@ -9,11 +9,11 @@ third_party {
type: GIT
value: "https://github.com/google/go-cmp.git"
}
- version: "v0.5.6"
+ version: "v0.5.7"
license_type: NOTICE
last_upgrade_date {
- year: 2021
- month: 8
- day: 27
+ year: 2022
+ month: 3
+ day: 29
}
}
diff --git a/README.md b/README.md
index ed0eb9b..e592e3a 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
# Package for equality of Go values
[![GoDev](https://img.shields.io/static/v1?label=godev&message=reference&color=00add8)][godev]
-[![Build Status](https://travis-ci.org/google/go-cmp.svg?branch=master)][travis]
+[![Build Status](https://github.com/google/go-cmp/actions/workflows/test.yml/badge.svg?branch=master)][actions]
This package is intended to be a more powerful and safer alternative to
`reflect.DeepEqual` for comparing whether two values are semantically equal.
@@ -29,7 +29,7 @@ See the [documentation][godev] for more information.
This is not an official Google product.
[godev]: https://pkg.go.dev/github.com/google/go-cmp/cmp
-[travis]: https://travis-ci.org/google/go-cmp
+[actions]: https://github.com/google/go-cmp/actions
## Install
diff --git a/cmp/cmpopts/equate.go b/cmp/cmpopts/equate.go
index e4ffca8..62837c9 100644
--- a/cmp/cmpopts/equate.go
+++ b/cmp/cmpopts/equate.go
@@ -111,7 +111,7 @@ type timeApproximator struct {
func (a timeApproximator) compare(x, y time.Time) bool {
// Avoid subtracting times to avoid overflow when the
- // difference is larger than the largest representible duration.
+ // difference is larger than the largest representable duration.
if x.After(y) {
// Ensure x is always before y
x, y = y, x
diff --git a/cmp/cmpopts/errors_go113.go b/cmp/cmpopts/errors_go113.go
index 26fe25d..8eb2b84 100644
--- a/cmp/cmpopts/errors_go113.go
+++ b/cmp/cmpopts/errors_go113.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build go1.13
// +build go1.13
package cmpopts
diff --git a/cmp/cmpopts/errors_xerrors.go b/cmp/cmpopts/errors_xerrors.go
index 6eeb8d6..60b0727 100644
--- a/cmp/cmpopts/errors_xerrors.go
+++ b/cmp/cmpopts/errors_xerrors.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build !go1.13
// +build !go1.13
// TODO(≥go1.13): For support on <go1.13, we use the xerrors package.
diff --git a/cmp/compare.go b/cmp/compare.go
index 86d0903..2a54467 100644
--- a/cmp/compare.go
+++ b/cmp/compare.go
@@ -36,7 +36,6 @@ import (
"strings"
"github.com/google/go-cmp/cmp/internal/diff"
- "github.com/google/go-cmp/cmp/internal/flags"
"github.com/google/go-cmp/cmp/internal/function"
"github.com/google/go-cmp/cmp/internal/value"
)
@@ -319,7 +318,6 @@ func (s *state) tryMethod(t reflect.Type, vx, vy reflect.Value) bool {
}
func (s *state) callTRFunc(f, v reflect.Value, step Transform) reflect.Value {
- v = sanitizeValue(v, f.Type().In(0))
if !s.dynChecker.Next() {
return f.Call([]reflect.Value{v})[0]
}
@@ -343,8 +341,6 @@ func (s *state) callTRFunc(f, v reflect.Value, step Transform) 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,19 +368,6 @@ 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(≥go1.10): Workaround for reflect bug (https://golang.org/issue/22143).
- if !flags.AtLeastGo110 {
- if v.Kind() == reflect.Interface && v.IsNil() && v.Type() != t {
- return reflect.New(t).Elem()
- }
- }
- return v
-}
-
func (s *state) compareStruct(t reflect.Type, vx, vy reflect.Value) {
var addr bool
var vax, vay reflect.Value // Addressable versions of vx and vy
diff --git a/cmp/compare_test.go b/cmp/compare_test.go
index 649c917..9ad9456 100644
--- a/cmp/compare_test.go
+++ b/cmp/compare_test.go
@@ -6,7 +6,7 @@ package cmp_test
import (
"bytes"
- "crypto/md5"
+ "crypto/sha256"
"encoding/json"
"errors"
"flag"
@@ -476,8 +476,8 @@ func comparerTests() []test {
reason: "comparer for fmt.Stringer used to compare differing types with different strings",
}, {
label: label + "/DifferingHash",
- x: md5.Sum([]byte{'a'}),
- y: md5.Sum([]byte{'b'}),
+ x: sha256.Sum256([]byte{'a'}),
+ y: sha256.Sum256([]byte{'b'}),
wantEqual: false,
reason: "hash differs",
}, {
@@ -515,7 +515,7 @@ func comparerTests() []test {
wantPanic: "non-deterministic or non-symmetric function detected",
reason: "non-deterministic filter",
}, {
- label: label + "/AssymetricComparer",
+ label: label + "/AsymmetricComparer",
x: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
y: []int{10, 9, 8, 7, 6, 5, 4, 3, 2, 1},
opts: []cmp.Option{
@@ -657,8 +657,8 @@ func comparerTests() []test {
reason: "all zero map entries are ignored (even if missing)",
}, {
label: label + "/PanicUnexportedNamed",
- x: namedWithUnexported{},
- y: namedWithUnexported{},
+ x: namedWithUnexported{unexported: "x"},
+ y: namedWithUnexported{unexported: "y"},
wantPanic: strconv.Quote(reflect.TypeOf(namedWithUnexported{}).PkgPath()) + ".namedWithUnexported",
reason: "panic on named struct type with unexported field",
}, {
@@ -1279,17 +1279,18 @@ using the AllowUnexported option.`, "\n"),
}, {
label: label + "/LargeMapKey",
x: map[*[]byte]int{func() *[]byte {
- b := make([]byte, 1<<20, 1<<20)
+ b := make([]byte, 1<<20)
return &b
}(): 0},
y: map[*[]byte]int{func() *[]byte {
- b := make([]byte, 1<<20, 1<<20)
+ b := make([]byte, 1<<20)
return &b
}(): 0},
reason: "printing map keys should have some verbosity limit imposed",
}, {
- label: label + "/LargeStringInInterface",
- x: struct{ X interface{} }{"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sit amet pretium ligula, at gravida quam. Integer iaculis, velit at sagittis ultricies, lacus metus scelerisque turpis, ornare feugiat nulla nisl ac erat. Maecenas elementum ultricies libero, sed efficitur lacus molestie non. Nulla ac pretium dolor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque mi lorem, consectetur id porttitor id, sollicitudin sit amet enim. Duis eu dolor magna. Nunc ut augue turpis."},
+ label: label + "/LargeStringInInterface",
+ x: struct{ X interface{} }{"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sit amet pretium ligula, at gravida quam. Integer iaculis, velit at sagittis ultricies, lacus metus scelerisque turpis, ornare feugiat nulla nisl ac erat. Maecenas elementum ultricies libero, sed efficitur lacus molestie non. Nulla ac pretium dolor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque mi lorem, consectetur id porttitor id, sollicitudin sit amet enim. Duis eu dolor magna. Nunc ut augue turpis."},
+
y: struct{ X interface{} }{"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sit amet pretium ligula, at gravida quam. Integer iaculis, velit at sagittis ultricies, lacus metus scelerisque turpis, ornare feugiat nulla nisl ac erat. Maecenas elementum ultricies libero, sed efficitur lacus molestie non. Nulla ac pretium dolor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque mi lorem, consectetur id porttitor id, sollicitudin sit amet enim. Duis eu dolor magna. Nunc ut augue turpis,"},
reason: "strings within an interface should benefit from specialized diffing",
}, {
@@ -1317,6 +1318,39 @@ using the AllowUnexported option.`, "\n"),
x: "d5c14bdf6bac81c27afc5429500ed750\n25483503b557c606dad4f144d27ae10b\n90bdbcdbb6ea7156068e3dcfb7459244\n978f480a6e3cced51e297fbff9a506b7\n",
y: "Xd5c14bdf6bac81c27afc5429500ed750\nX25483503b557c606dad4f144d27ae10b\nX90bdbcdbb6ea7156068e3dcfb7459244\nX978f480a6e3cced51e297fbff9a506b7\n",
reason: "all lines are different, so diffing based on lines is pointless",
+ }, {
+ label: label + "/StringifiedBytes",
+ x: struct{ X []byte }{[]byte("hello, world!")},
+ y: struct{ X []byte }{},
+ reason: "[]byte should be printed as text since it is printable text",
+ }, {
+ label: label + "/NonStringifiedBytes",
+ x: struct{ X []byte }{[]byte("\xde\xad\xbe\xef")},
+ y: struct{ X []byte }{},
+ reason: "[]byte should not be printed as text since it is binary data",
+ }, {
+ label: label + "/StringifiedNamedBytes",
+ x: struct{ X MyBytes }{MyBytes("hello, world!")},
+ y: struct{ X MyBytes }{},
+ reason: "MyBytes should be printed as text since it is printable text",
+ }, {
+ label: label + "/NonStringifiedNamedBytes",
+ x: struct{ X MyBytes }{MyBytes("\xde\xad\xbe\xef")},
+ y: struct{ X MyBytes }{},
+ reason: "MyBytes should not be printed as text since it is binary data",
+ }, {
+ label: label + "/ShortJSON",
+ x: `{
+ "id": 1,
+ "foo": true,
+ "bar": true,
+}`,
+ y: `{
+ "id": 1434180,
+ "foo": true,
+ "bar": true,
+}`,
+ reason: "short multiline JSON should prefer triple-quoted string diff as it is more readable",
}}
}
@@ -1413,14 +1447,6 @@ func embeddedTests() []test {
return s
}
- // TODO(≥go1.10): Workaround for reflect bug (https://golang.org/issue/21122).
- wantPanicNotGo110 := func(s string) string {
- if !flags.AtLeastGo110 {
- return ""
- }
- return s
- }
-
return []test{{
label: label + "/ParentStructA/PanicUnexported1",
x: ts.ParentStructA{},
@@ -1711,8 +1737,7 @@ func embeddedTests() []test {
label: label + "/ParentStructG/PanicUnexported1",
x: ts.ParentStructG{},
y: ts.ParentStructG{},
- wantPanic: wantPanicNotGo110("cannot handle unexported field"),
- wantEqual: !flags.AtLeastGo110,
+ wantPanic: "cannot handle unexported field",
reason: "ParentStructG has unexported fields",
}, {
label: label + "/ParentStructG/Ignored",
@@ -1802,8 +1827,7 @@ func embeddedTests() []test {
label: label + "/ParentStructI/PanicUnexported1",
x: ts.ParentStructI{},
y: ts.ParentStructI{},
- wantPanic: wantPanicNotGo110("cannot handle unexported field"),
- wantEqual: !flags.AtLeastGo110,
+ wantPanic: "cannot handle unexported field",
reason: "ParentStructI has unexported fields",
}, {
label: label + "/ParentStructI/Ignored1",
diff --git a/cmp/example_test.go b/cmp/example_test.go
index d165383..e1f4338 100644
--- a/cmp/example_test.go
+++ b/cmp/example_test.go
@@ -98,9 +98,9 @@ func ExampleOption_equalNaNs() {
return (math.IsNaN(x) && math.IsNaN(y)) || x == y
})
- x := []float64{1.0, math.NaN(), math.E, -0.0, +0.0}
- y := []float64{1.0, math.NaN(), math.E, -0.0, +0.0}
- z := []float64{1.0, math.NaN(), math.Pi, -0.0, +0.0} // Pi constant instead of E
+ x := []float64{1.0, math.NaN(), math.E, 0.0}
+ y := []float64{1.0, math.NaN(), math.E, 0.0}
+ z := []float64{1.0, math.NaN(), math.Pi, 0.0} // Pi constant instead of E
fmt.Println(cmp.Equal(x, y, opt))
fmt.Println(cmp.Equal(y, z, opt))
@@ -216,7 +216,7 @@ func ExampleOption_sortedSlice() {
type otherString string
func (x otherString) Equal(y otherString) bool {
- return strings.ToLower(string(x)) == strings.ToLower(string(y))
+ return strings.EqualFold(string(x), string(y))
}
// If the Equal method defined on a type is not suitable, the type can be
diff --git a/cmp/export_panic.go b/cmp/export_panic.go
index 5ff0b42..ae851fe 100644
--- a/cmp/export_panic.go
+++ b/cmp/export_panic.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build purego
// +build purego
package cmp
diff --git a/cmp/export_unsafe.go b/cmp/export_unsafe.go
index 21eb548..e2c0f74 100644
--- a/cmp/export_unsafe.go
+++ b/cmp/export_unsafe.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build !purego
// +build !purego
package cmp
diff --git a/cmp/internal/diff/debug_disable.go b/cmp/internal/diff/debug_disable.go
index 1daaaac..36062a6 100644
--- a/cmp/internal/diff/debug_disable.go
+++ b/cmp/internal/diff/debug_disable.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build !cmp_debug
// +build !cmp_debug
package diff
diff --git a/cmp/internal/diff/debug_enable.go b/cmp/internal/diff/debug_enable.go
index 4b91dbc..a3b97a1 100644
--- a/cmp/internal/diff/debug_enable.go
+++ b/cmp/internal/diff/debug_enable.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build cmp_debug
// +build cmp_debug
package diff
diff --git a/cmp/internal/flags/toolchain_legacy.go b/cmp/internal/flags/toolchain_legacy.go
deleted file mode 100644
index 82d1d7f..0000000
--- a/cmp/internal/flags/toolchain_legacy.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2019, 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 file.
-
-// +build !go1.10
-
-package flags
-
-// AtLeastGo110 reports whether the Go toolchain is at least Go 1.10.
-const AtLeastGo110 = false
diff --git a/cmp/internal/flags/toolchain_recent.go b/cmp/internal/flags/toolchain_recent.go
deleted file mode 100644
index 8646f05..0000000
--- a/cmp/internal/flags/toolchain_recent.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2019, 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 file.
-
-// +build go1.10
-
-package flags
-
-// AtLeastGo110 reports whether the Go toolchain is at least Go 1.10.
-const AtLeastGo110 = true
diff --git a/cmp/internal/value/name.go b/cmp/internal/value/name.go
index b6c12ce..7b498bb 100644
--- a/cmp/internal/value/name.go
+++ b/cmp/internal/value/name.go
@@ -9,6 +9,8 @@ import (
"strconv"
)
+var anyType = reflect.TypeOf((*interface{})(nil)).Elem()
+
// TypeString is nearly identical to reflect.Type.String,
// but has an additional option to specify that full type names be used.
func TypeString(t reflect.Type, qualified bool) string {
@@ -20,6 +22,11 @@ func appendTypeName(b []byte, t reflect.Type, qualified, elideFunc bool) []byte
// of the same name and within the same package,
// but declared within the namespace of different functions.
+ // Use the "any" alias instead of "interface{}" for better readability.
+ if t == anyType {
+ return append(b, "any"...)
+ }
+
// Named type.
if t.Name() != "" {
if qualified && t.PkgPath() != "" {
diff --git a/cmp/internal/value/name_test.go b/cmp/internal/value/name_test.go
index 3eec91c..c177e72 100644
--- a/cmp/internal/value/name_test.go
+++ b/cmp/internal/value/name_test.go
@@ -111,7 +111,7 @@ func TestTypeString(t *testing.T) {
want: "*$PackagePath.Named",
}, {
in: (*interface{})(nil),
- want: "*interface{}",
+ want: "*any",
}, {
in: (*interface{ Read([]byte) (int, error) })(nil),
want: "*interface{ Read([]uint8) (int, error) }",
diff --git a/cmp/internal/value/pointer_purego.go b/cmp/internal/value/pointer_purego.go
index 44f4a5a..1a71bfc 100644
--- a/cmp/internal/value/pointer_purego.go
+++ b/cmp/internal/value/pointer_purego.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build purego
// +build purego
package value
diff --git a/cmp/internal/value/pointer_unsafe.go b/cmp/internal/value/pointer_unsafe.go
index a605953..16e6860 100644
--- a/cmp/internal/value/pointer_unsafe.go
+++ b/cmp/internal/value/pointer_unsafe.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build !purego
// +build !purego
package value
diff --git a/cmp/path.go b/cmp/path.go
index f01eff3..c710034 100644
--- a/cmp/path.go
+++ b/cmp/path.go
@@ -178,7 +178,7 @@ type structField struct {
unexported bool
mayForce bool // Forcibly allow visibility
paddr bool // Was parent addressable?
- pvx, pvy reflect.Value // Parent values (always addressible)
+ pvx, pvy reflect.Value // Parent values (always addressable)
field reflect.StructField // Field information
}
diff --git a/cmp/report_reflect.go b/cmp/report_reflect.go
index 33f0357..76c04fd 100644
--- a/cmp/report_reflect.go
+++ b/cmp/report_reflect.go
@@ -207,9 +207,10 @@ func (opts formatOptions) FormatValue(v reflect.Value, parentKind reflect.Kind,
// Check whether this is a []byte of text data.
if t.Elem() == reflect.TypeOf(byte(0)) {
b := v.Bytes()
- isPrintSpace := func(r rune) bool { return unicode.IsPrint(r) && unicode.IsSpace(r) }
+ isPrintSpace := func(r rune) bool { return unicode.IsPrint(r) || unicode.IsSpace(r) }
if len(b) > 0 && utf8.Valid(b) && len(bytes.TrimFunc(b, isPrintSpace)) == 0 {
out = opts.formatString("", string(b))
+ skipType = true
return opts.WithTypeMode(emitType).FormatType(t, out)
}
}
diff --git a/cmp/report_slices.go b/cmp/report_slices.go
index 2ad3bc8..68b5c1a 100644
--- a/cmp/report_slices.go
+++ b/cmp/report_slices.go
@@ -80,7 +80,7 @@ func (opts formatOptions) CanFormatDiffSlice(v *valueNode) bool {
}
// Use specialized string diffing for longer slices or strings.
- const minLength = 64
+ const minLength = 32
return vx.Len() >= minLength && vy.Len() >= minLength
}
@@ -563,10 +563,10 @@ func cleanupSurroundingIdentical(groups []diffStats, eq func(i, j int) bool) []d
nx := ds.NumIdentical + ds.NumRemoved + ds.NumModified
ny := ds.NumIdentical + ds.NumInserted + ds.NumModified
var numLeadingIdentical, numTrailingIdentical int
- for i := 0; i < nx && i < ny && eq(ix+i, iy+i); i++ {
+ for j := 0; j < nx && j < ny && eq(ix+j, iy+j); j++ {
numLeadingIdentical++
}
- for i := 0; i < nx && i < ny && eq(ix+nx-1-i, iy+ny-1-i); i++ {
+ for j := 0; j < nx && j < ny && eq(ix+nx-1-j, iy+ny-1-j); j++ {
numTrailingIdentical++
}
if numIdentical := numLeadingIdentical + numTrailingIdentical; numIdentical > 0 {
diff --git a/cmp/testdata/diffs b/cmp/testdata/diffs
index a3d5909..d207803 100644
--- a/cmp/testdata/diffs
+++ b/cmp/testdata/diffs
@@ -38,13 +38,15 @@
)
>>> TestDiff/Comparer/StringerInequal
<<< TestDiff/Comparer/DifferingHash
- [16]uint8{
-- 0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8, 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61,
-+ 0x92, 0xeb, 0x5f, 0xfe, 0xe6, 0xae, 0x2f, 0xec, 0x3a, 0xd7, 0x1c, 0x77, 0x75, 0x31, 0x57, 0x8f,
+ [32]uint8{
+- 0xca, 0x97, 0x81, 0x12, 0xca, 0x1b, 0xbd, 0xca, 0xfa, 0xc2, 0x31, 0xb3, 0x9a, 0x23, 0xdc, 0x4d,
+- 0xa7, 0x86, 0xef, 0xf8, 0x14, 0x7c, 0x4e, 0x72, 0xb9, 0x80, 0x77, 0x85, 0xaf, 0xee, 0x48, 0xbb,
++ 0x3e, 0x23, 0xe8, 0x16, 0x00, 0x39, 0x59, 0x4a, 0x33, 0x89, 0x4f, 0x65, 0x64, 0xe1, 0xb1, 0x34,
++ 0x8b, 0xbd, 0x7a, 0x00, 0x88, 0xd4, 0x2c, 0x4a, 0xcb, 0x73, 0xee, 0xae, 0xd5, 0x9c, 0x00, 0x9d,
}
>>> TestDiff/Comparer/DifferingHash
<<< TestDiff/Comparer/NilStringer
- interface{}(
+ any(
- &fmt.Stringer(nil),
)
>>> TestDiff/Comparer/NilStringer
@@ -133,19 +135,19 @@
)
>>> TestDiff/Comparer/StringerMapKey
<<< TestDiff/Comparer/StringerBacktick
- interface{}(
+ any(
- []*testprotos.Stringer{s`multi\nline\nline\nline`},
)
>>> TestDiff/Comparer/StringerBacktick
<<< TestDiff/Comparer/DynamicMap
- []interface{}{
- map[string]interface{}{
+ []any{
+ map[string]any{
"avg": float64(0.278),
- "hr": int(65),
+ "hr": float64(65),
"name": string("Mark McGwire"),
},
- map[string]interface{}{
+ map[string]any{
"avg": float64(0.288),
- "hr": int(63),
+ "hr": float64(63),
@@ -197,14 +199,14 @@
}
>>> TestDiff/Transformer/Filtered
<<< TestDiff/Transformer/DisjointOutput
- int(Inverse(λ, interface{}(
+ int(Inverse(λ, any(
- string("zero"),
+ float64(1),
)))
>>> TestDiff/Transformer/DisjointOutput
<<< TestDiff/Transformer/JSON
- string(Inverse(ParseJSON, map[string]interface{}{
- "address": map[string]interface{}{
+ string(Inverse(ParseJSON, map[string]any{
+ "address": map[string]any{
- "city": string("Los Angeles"),
+ "city": string("New York"),
"postalCode": string("10021-3100"),
@@ -213,18 +215,18 @@
"streetAddress": string("21 2nd Street"),
},
"age": float64(25),
- "children": []interface{}{},
+ "children": []any{},
"firstName": string("John"),
"isAlive": bool(true),
"lastName": string("Smith"),
- "phoneNumbers": []interface{}{
- map[string]interface{}{
+ "phoneNumbers": []any{
+ map[string]any{
- "number": string("212 555-4321"),
+ "number": string("212 555-1234"),
"type": string("home"),
},
- map[string]interface{}{"number": string("646 555-4567"), "type": string("office")},
- map[string]interface{}{"number": string("123 456-7890"), "type": string("mobile")},
+ map[string]any{"number": string("646 555-4567"), "type": string("office")},
+ map[string]any{"number": string("123 456-7890"), "type": string("mobile")},
},
+ "spouse": nil,
}))
@@ -265,7 +267,7 @@
}
>>> TestDiff/Reporter/PanicError
<<< TestDiff/Reporter/AmbiguousType
- interface{}(
+ any(
- "github.com/google/go-cmp/cmp/internal/teststructs/foo1".Bar{},
+ "github.com/google/go-cmp/cmp/internal/teststructs/foo2".Bar{},
)
@@ -295,7 +297,7 @@
}
>>> TestDiff/Reporter/AmbiguousPointerMap
<<< TestDiff/Reporter/AmbiguousStringer
- interface{}(
+ any(
- cmp_test.Stringer("hello"),
+ &cmp_test.Stringer("hello"),
)
@@ -325,7 +327,7 @@
)
>>> TestDiff/Reporter/AmbiguousSliceHeader
<<< TestDiff/Reporter/AmbiguousStringerMapKey
- map[interface{}]string{
+ map[any]string{
- nil: "nil",
+ &⟪0xdeadf00f⟫"github.com/google/go-cmp/cmp_test".Stringer("hello"): "goodbye",
- "github.com/google/go-cmp/cmp_test".Stringer("hello"): "goodbye",
@@ -334,13 +336,13 @@
}
>>> TestDiff/Reporter/AmbiguousStringerMapKey
<<< TestDiff/Reporter/NonAmbiguousStringerMapKey
- map[interface{}]string{
+ map[any]string{
+ s"fizz": "buzz",
- s"hello": "goodbye",
}
>>> TestDiff/Reporter/NonAmbiguousStringerMapKey
<<< TestDiff/Reporter/InvalidUTF8
- interface{}(
+ any(
- cmp_test.MyString("\xed\xa0\x80"),
)
>>> TestDiff/Reporter/InvalidUTF8
@@ -397,7 +399,7 @@
}
>>> TestDiff/Reporter/BatchedWithComparer
<<< TestDiff/Reporter/BatchedLong
- interface{}(
+ any(
- cmp_test.MyComposite{IntsA: []int8{0, 1, 2, 3, 4, 5, 6, 7, ...}},
)
>>> TestDiff/Reporter/BatchedLong
@@ -1015,7 +1017,7 @@
}
>>> TestDiff/Reporter/LargeMapKey
<<< TestDiff/Reporter/LargeStringInInterface
- struct{ X interface{} }{
+ struct{ X any }{
X: strings.Join({
... // 485 identical bytes
"s mus. Pellentesque mi lorem, consectetur id porttitor id, solli",
@@ -1026,7 +1028,7 @@
}
>>> TestDiff/Reporter/LargeStringInInterface
<<< TestDiff/Reporter/LargeBytesInInterface
- struct{ X interface{} }{
+ struct{ X any }{
X: bytes.Join({
... // 485 identical bytes
"s mus. Pellentesque mi lorem, consectetur id porttitor id, solli",
@@ -1037,7 +1039,7 @@
}
>>> TestDiff/Reporter/LargeBytesInInterface
<<< TestDiff/Reporter/LargeStandaloneString
- struct{ X interface{} }{
+ struct{ X any }{
- X: [1]string{
- "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sit amet pretium ligula, at gravida quam. Integer iaculis, velit at sagittis ultricies, lacus metus scelerisque turpis, ornare feugiat nulla nisl ac erat. Maecenas elementum ultricies libero, sed efficitur lacus molestie non. Nulla ac pretium dolor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque mi lorem, consectetur id porttitor id, sollicitudin sit amet enim. Duis eu dolor magna. Nunc ut augue turpis.",
- },
@@ -1096,6 +1098,42 @@
"978f480a6e3cced51e297fbff9a506b7\n",
}, "")
>>> TestDiff/Reporter/AllLinesDiffer
+<<< TestDiff/Reporter/StringifiedBytes
+ struct{ X []uint8 }{
+- X: []uint8("hello, world!"),
++ X: nil,
+ }
+>>> TestDiff/Reporter/StringifiedBytes
+<<< TestDiff/Reporter/NonStringifiedBytes
+ struct{ X []uint8 }{
+- X: []uint8{0xde, 0xad, 0xbe, 0xef},
++ X: nil,
+ }
+>>> TestDiff/Reporter/NonStringifiedBytes
+<<< TestDiff/Reporter/StringifiedNamedBytes
+ struct{ X cmp_test.MyBytes }{
+- X: cmp_test.MyBytes("hello, world!"),
++ X: nil,
+ }
+>>> TestDiff/Reporter/StringifiedNamedBytes
+<<< TestDiff/Reporter/NonStringifiedNamedBytes
+ struct{ X cmp_test.MyBytes }{
+- X: cmp_test.MyBytes{0xde, 0xad, 0xbe, 0xef},
++ X: nil,
+ }
+>>> TestDiff/Reporter/NonStringifiedNamedBytes
+<<< TestDiff/Reporter/ShortJSON
+ (
+ """
+ {
+- "id": 1,
++ "id": 1434180,
+ "foo": true,
+ "bar": true,
+ }
+ """
+ )
+>>> TestDiff/Reporter/ShortJSON
<<< TestDiff/EmbeddedStruct/ParentStructA/Inequal
teststructs.ParentStructA{
privateStruct: teststructs.privateStruct{
@@ -1588,7 +1626,7 @@
... // 4 identical fields
ContSlaps: nil,
ContSlapsInterval: 0,
- Animal: []interface{}{
+ Animal: []any{
teststructs.Goat{
Target: "corporation",
Slaps: nil,
diff --git a/go.mod b/go.mod
index 5391dee..4cdb762 100644
--- a/go.mod
+++ b/go.mod
@@ -1,5 +1,5 @@
module github.com/google/go-cmp
-go 1.8
+go 1.11
require golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543