aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Tsai <joetsai@digital-static.net>2020-06-17 14:41:50 -0700
committerGitHub <noreply@github.com>2020-06-17 14:41:50 -0700
commitc49bfce0ac9115b09320b47c3b9534cc5afd4579 (patch)
treeb644e2fd16ed59d1fb4f89a74b1233d65d907ea7
parent12277310d373db3799bcc3f14684adee17319122 (diff)
downloadgo-cmp-c49bfce0ac9115b09320b47c3b9534cc5afd4579.tar.gz
Update test case names (#218)
Provide a unique name for every test case. Provide a reason for every test case. The purpose of a unique name is so that insertion/removal of a case does not cause all subsequent names to suddenly shift, causing a larger number of differences in testdata/diffs.
-rw-r--r--cmp/compare_test.go638
-rw-r--r--cmp/testdata/diffs276
2 files changed, 557 insertions, 357 deletions
diff --git a/cmp/compare_test.go b/cmp/compare_test.go
index be8a2f6..c94f6c0 100644
--- a/cmp/compare_test.go
+++ b/cmp/compare_test.go
@@ -155,9 +155,12 @@ func TestDiff(t *testing.T) {
gotDiff = cmp.Diff(tt.x, tt.y, tt.opts...)
}()
- // TODO: Require every test case to provide a reason.
- // TODO: Forbid any test cases with the same name.
- if tt.wantPanic == "" {
+ switch {
+ case strings.Contains(t.Name(), "#"):
+ panic("unique test name must be provided")
+ case tt.reason == "":
+ panic("reason must be provided")
+ case tt.wantPanic == "":
if gotPanic != "" {
t.Fatalf("unexpected panic message: %s\nreason: %v", gotPanic, tt.reason)
}
@@ -175,7 +178,7 @@ func TestDiff(t *testing.T) {
if gotEqual != tt.wantEqual {
t.Fatalf("Equal = %v, want %v\nreason: %v", gotEqual, tt.wantEqual, tt.reason)
}
- } else {
+ default:
if !strings.Contains(gotPanic, tt.wantPanic) {
t.Fatalf("panic message:\ngot: %s\nwant: %s\nreason: %v", gotPanic, tt.wantPanic, tt.reason)
}
@@ -234,35 +237,40 @@ func comparerTests() []test {
}
return []test{{
- label: label,
+ label: label + "/Nil",
x: nil,
y: nil,
wantEqual: true,
+ reason: "nils are equal",
}, {
- label: label,
+ label: label + "/Integer",
x: 1,
y: 1,
wantEqual: true,
+ reason: "identical integers are equal",
}, {
- label: label,
+ label: label + "/UnfilteredIgnore",
x: 1,
y: 1,
opts: []cmp.Option{cmp.Ignore()},
wantPanic: "cannot use an unfiltered option",
+ reason: "unfiltered options are functionally useless",
}, {
- label: label,
+ label: label + "/UnfilteredCompare",
x: 1,
y: 1,
opts: []cmp.Option{cmp.Comparer(func(_, _ interface{}) bool { return true })},
wantPanic: "cannot use an unfiltered option",
+ reason: "unfiltered options are functionally useless",
}, {
- label: label,
+ label: label + "/UnfilteredTransform",
x: 1,
y: 1,
opts: []cmp.Option{cmp.Transformer("λ", func(x interface{}) interface{} { return x })},
wantPanic: "cannot use an unfiltered option",
+ reason: "unfiltered options are functionally useless",
}, {
- label: label,
+ label: label + "/AmbiguousOptions",
x: 1,
y: 1,
opts: []cmp.Option{
@@ -270,8 +278,9 @@ func comparerTests() []test {
cmp.Transformer("λ", func(x int) float64 { return float64(x) }),
},
wantPanic: "ambiguous set of applicable options",
+ reason: "both options apply on int, leading to ambiguity",
}, {
- label: label,
+ label: label + "/IgnorePrecedence",
x: 1,
y: 1,
opts: []cmp.Option{
@@ -282,84 +291,98 @@ func comparerTests() []test {
cmp.Transformer("λ", func(x int) float64 { return float64(x) }),
},
wantEqual: true,
+ reason: "ignore takes precedence over other options",
}, {
- label: label,
+ label: label + "/UnknownOption",
opts: []cmp.Option{struct{ cmp.Option }{}},
wantPanic: "unknown option",
+ reason: "use of unknown option should panic",
}, {
- label: label,
+ label: label + "/StructEqual",
x: struct{ A, B, C int }{1, 2, 3},
y: struct{ A, B, C int }{1, 2, 3},
wantEqual: true,
+ reason: "struct comparison with all equal fields",
}, {
- label: label,
+ label: label + "/StructInequal",
x: struct{ A, B, C int }{1, 2, 3},
y: struct{ A, B, C int }{1, 2, 4},
wantEqual: false,
+ reason: "struct comparison with inequal C field",
}, {
- label: label,
+ label: label + "/StructUnexported",
x: struct{ a, b, c int }{1, 2, 3},
y: struct{ a, b, c int }{1, 2, 4},
wantPanic: "cannot handle unexported field",
+ reason: "unexported fields result in a panic by default",
}, {
- label: label,
+ label: label + "/PointerStructEqual",
x: &struct{ A *int }{newInt(4)},
y: &struct{ A *int }{newInt(4)},
wantEqual: true,
+ reason: "comparison of pointer to struct with equal A field",
}, {
- label: label,
+ label: label + "/PointerStructInequal",
x: &struct{ A *int }{newInt(4)},
y: &struct{ A *int }{newInt(5)},
wantEqual: false,
+ reason: "comparison of pointer to struct with inequal A field",
}, {
- label: label,
+ label: label + "/PointerStructTrueComparer",
x: &struct{ A *int }{newInt(4)},
y: &struct{ A *int }{newInt(5)},
opts: []cmp.Option{
cmp.Comparer(func(x, y int) bool { return true }),
},
wantEqual: true,
+ reason: "comparison of pointer to struct with inequal A field, but treated as equal with always equal comparer",
}, {
- label: label,
+ label: label + "/PointerStructNonNilComparer",
x: &struct{ A *int }{newInt(4)},
y: &struct{ A *int }{newInt(5)},
opts: []cmp.Option{
cmp.Comparer(func(x, y *int) bool { return x != nil && y != nil }),
},
wantEqual: true,
+ reason: "comparison of pointer to struct with inequal A field, but treated as equal with comparer checking pointers for nilness",
}, {
- label: label,
+ label: label + "/StructNestedPointerEqual",
x: &struct{ R *bytes.Buffer }{},
y: &struct{ R *bytes.Buffer }{},
wantEqual: true,
+ reason: "equal since both pointers in R field are nil",
}, {
- label: label,
+ label: label + "/StructNestedPointerInequal",
x: &struct{ R *bytes.Buffer }{new(bytes.Buffer)},
y: &struct{ R *bytes.Buffer }{},
wantEqual: false,
+ reason: "inequal since R field is inequal",
}, {
- label: label,
+ label: label + "/StructNestedPointerTrueComparer",
x: &struct{ R *bytes.Buffer }{new(bytes.Buffer)},
y: &struct{ R *bytes.Buffer }{},
opts: []cmp.Option{
cmp.Comparer(func(x, y io.Reader) bool { return true }),
},
wantEqual: true,
+ reason: "equal despite inequal R field values since the comparer always reports true",
}, {
- label: label,
+ label: label + "/StructNestedValueUnexportedPanic1",
x: &struct{ R bytes.Buffer }{},
y: &struct{ R bytes.Buffer }{},
wantPanic: "cannot handle unexported field",
+ reason: "bytes.Buffer contains unexported fields",
}, {
- label: label,
+ label: label + "/StructNestedValueUnexportedPanic2",
x: &struct{ R bytes.Buffer }{},
y: &struct{ R bytes.Buffer }{},
opts: []cmp.Option{
cmp.Comparer(func(x, y io.Reader) bool { return true }),
},
wantPanic: "cannot handle unexported field",
+ reason: "bytes.Buffer value does not implement io.Reader",
}, {
- label: label,
+ label: label + "/StructNestedValueEqual",
x: &struct{ R bytes.Buffer }{},
y: &struct{ R bytes.Buffer }{},
opts: []cmp.Option{
@@ -367,13 +390,15 @@ func comparerTests() []test {
cmp.Comparer(func(x, y io.Reader) bool { return true }),
},
wantEqual: true,
+ reason: "bytes.Buffer pointer due to shallow copy does implement io.Reader",
}, {
- label: label,
+ label: label + "/RegexpUnexportedPanic",
x: []*regexp.Regexp{nil, regexp.MustCompile("a*b*c*")},
y: []*regexp.Regexp{nil, regexp.MustCompile("a*b*c*")},
wantPanic: "cannot handle unexported field",
+ reason: "regexp.Regexp contains unexported fields",
}, {
- label: label,
+ label: label + "/RegexpEqual",
x: []*regexp.Regexp{nil, regexp.MustCompile("a*b*c*")},
y: []*regexp.Regexp{nil, regexp.MustCompile("a*b*c*")},
opts: []cmp.Option{cmp.Comparer(func(x, y *regexp.Regexp) bool {
@@ -383,8 +408,9 @@ func comparerTests() []test {
return x.String() == y.String()
})},
wantEqual: true,
+ reason: "comparer for *regexp.Regexp applied with equal regexp strings",
}, {
- label: label,
+ label: label + "/RegexpInequal",
x: []*regexp.Regexp{nil, regexp.MustCompile("a*b*c*")},
y: []*regexp.Regexp{nil, regexp.MustCompile("a*b*d*")},
opts: []cmp.Option{cmp.Comparer(func(x, y *regexp.Regexp) bool {
@@ -394,8 +420,9 @@ func comparerTests() []test {
return x.String() == y.String()
})},
wantEqual: false,
+ reason: "comparer for *regexp.Regexp applied with inequal regexp strings",
}, {
- label: label,
+ label: label + "/TriplePointerEqual",
x: func() ***int {
a := 0
b := &a
@@ -409,8 +436,9 @@ func comparerTests() []test {
return &c
}(),
wantEqual: true,
+ reason: "three layers of pointers to the same value",
}, {
- label: label,
+ label: label + "/TriplePointerInequal",
x: func() ***int {
a := 0
b := &a
@@ -424,40 +452,47 @@ func comparerTests() []test {
return &c
}(),
wantEqual: false,
+ reason: "three layers of pointers to different values",
}, {
- label: label,
+ label: label + "/SliceWithDifferingCapacity",
x: []int{1, 2, 3, 4, 5}[:3],
y: []int{1, 2, 3},
wantEqual: true,
+ reason: "elements past the slice length are not compared",
}, {
- label: label,
+ label: label + "/StringerEqual",
x: struct{ fmt.Stringer }{bytes.NewBufferString("hello")},
y: struct{ fmt.Stringer }{regexp.MustCompile("hello")},
opts: []cmp.Option{cmp.Comparer(func(x, y fmt.Stringer) bool { return x.String() == y.String() })},
wantEqual: true,
+ reason: "comparer for fmt.Stringer used to compare differing types with same string",
}, {
- label: label,
+ label: label + "/StringerInequal",
x: struct{ fmt.Stringer }{bytes.NewBufferString("hello")},
y: struct{ fmt.Stringer }{regexp.MustCompile("hello2")},
opts: []cmp.Option{cmp.Comparer(func(x, y fmt.Stringer) bool { return x.String() == y.String() })},
wantEqual: false,
+ reason: "comparer for fmt.Stringer used to compare differing types with different strings",
}, {
- label: label,
+ label: label + "/DifferingHash",
x: md5.Sum([]byte{'a'}),
y: md5.Sum([]byte{'b'}),
wantEqual: false,
+ reason: "hash differs",
}, {
- label: label,
+ label: label + "/NilStringer",
x: new(fmt.Stringer),
y: nil,
wantEqual: false,
+ reason: "by default differing types are always inequal",
}, {
- label: label,
+ label: label + "/TarHeaders",
x: makeTarHeaders('0'),
y: makeTarHeaders('\x00'),
wantEqual: false,
+ reason: "type flag differs between the headers",
}, {
- label: label,
+ label: label + "/NonDeterministicComparer",
x: make([]int, 1000),
y: make([]int, 1000),
opts: []cmp.Option{
@@ -466,8 +501,9 @@ func comparerTests() []test {
}),
},
wantPanic: "non-deterministic or non-symmetric function detected",
+ reason: "non-deterministic comparer",
}, {
- label: label,
+ label: label + "/NonDeterministicFilter",
x: make([]int, 1000),
y: make([]int, 1000),
opts: []cmp.Option{
@@ -476,8 +512,9 @@ func comparerTests() []test {
}, cmp.Ignore()),
},
wantPanic: "non-deterministic or non-symmetric function detected",
+ reason: "non-deterministic filter",
}, {
- label: label,
+ label: label + "/AssymetricComparer",
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{
@@ -486,8 +523,9 @@ func comparerTests() []test {
}),
},
wantPanic: "non-deterministic or non-symmetric function detected",
+ reason: "asymmetric comparer",
}, {
- label: label,
+ label: label + "/NonDeterministicTransformer",
x: make([]string, 1000),
y: make([]string, 1000),
opts: []cmp.Option{
@@ -496,10 +534,9 @@ func comparerTests() []test {
}),
},
wantPanic: "non-deterministic function detected",
+ reason: "non-deterministic transformer",
}, {
- // Make sure the dynamic checks don't raise a false positive for
- // non-reflexive comparisons.
- label: label,
+ label: label + "/IrreflexiveComparison",
x: make([]int, 10),
y: make([]int, 10),
opts: []cmp.Option{
@@ -508,19 +545,20 @@ func comparerTests() []test {
}),
},
wantEqual: false,
+ reason: "dynamic checks should not panic for non-reflexive comparisons",
}, {
- // Ensure reasonable Stringer formatting of map keys.
- label: label,
+ label: label + "/StringerMapKey",
x: map[*pb.Stringer]*pb.Stringer{{"hello"}: {"world"}},
y: map[*pb.Stringer]*pb.Stringer(nil),
wantEqual: false,
+ reason: "stringer should be used to format the map key",
}, {
- // Ensure Stringer avoids double-quote escaping if possible.
- label: label,
+ label: label + "/StringerBacktick",
x: []*pb.Stringer{{`multi\nline\nline\nline`}},
wantEqual: false,
+ reason: "stringer should use backtick quoting if more readable",
}, {
- label: label,
+ label: label + "/AvoidPanicAssignableConverter",
x: struct{ I Iface2 }{},
y: struct{ I Iface2 }{},
opts: []cmp.Option{
@@ -529,8 +567,9 @@ func comparerTests() []test {
}),
},
wantEqual: true,
+ reason: "function call using Go reflection should automatically convert assignable interfaces; see https://golang.org/issues/22143",
}, {
- label: label,
+ label: label + "/AvoidPanicAssignableTransformer",
x: struct{ I Iface2 }{},
y: struct{ I Iface2 }{},
opts: []cmp.Option{
@@ -539,8 +578,9 @@ func comparerTests() []test {
}),
},
wantEqual: true,
+ reason: "function call using Go reflection should automatically convert assignable interfaces; see https://golang.org/issues/22143",
}, {
- label: label,
+ label: label + "/AvoidPanicAssignableFilter",
x: struct{ I Iface2 }{},
y: struct{ I Iface2 }{},
opts: []cmp.Option{
@@ -549,13 +589,15 @@ func comparerTests() []test {
}, cmp.Ignore()),
},
wantEqual: true,
+ reason: "function call using Go reflection should automatically convert assignable interfaces; see https://golang.org/issues/22143",
}, {
- label: label,
+ label: label + "/DynamicMap",
x: []interface{}{map[string]interface{}{"avg": 0.278, "hr": 65, "name": "Mark McGwire"}, map[string]interface{}{"avg": 0.288, "hr": 63, "name": "Sammy Sosa"}},
y: []interface{}{map[string]interface{}{"avg": 0.278, "hr": 65.0, "name": "Mark McGwire"}, map[string]interface{}{"avg": 0.288, "hr": 63.0, "name": "Sammy Sosa"}},
wantEqual: false,
+ reason: "dynamic map with differing types (but semantically equivalent values) should be inequal",
}, {
- label: label,
+ label: label + "/MapKeyPointer",
x: map[*int]string{
new(int): "hello",
},
@@ -563,8 +605,9 @@ func comparerTests() []test {
new(int): "world",
},
wantEqual: false,
+ reason: "map keys should use shallow (rather than deep) pointer comparison",
}, {
- label: label,
+ label: label + "/IgnoreSliceElements",
x: [2][]int{
{0, 0, 0, 1, 2, 3, 0, 0, 4, 5, 6, 7, 8, 0, 9, 0, 0},
{0, 1, 0, 0, 0, 20},
@@ -588,7 +631,7 @@ func comparerTests() []test {
wantEqual: false,
reason: "all zero slice elements are ignored (even if missing)",
}, {
- label: label,
+ label: label + "/IgnoreMapEntries",
x: [2]map[string]int{
{"ignore1": 0, "ignore2": 0, "keep1": 1, "keep2": 2, "KEEP3": 3, "IGNORE3": 0},
{"keep1": 1, "ignore1": 0},
@@ -612,19 +655,19 @@ func comparerTests() []test {
wantEqual: false,
reason: "all zero map entries are ignored (even if missing)",
}, {
- label: label,
+ label: label + "/PanicUnexportedNamed",
x: namedWithUnexported{},
y: namedWithUnexported{},
wantPanic: strconv.Quote(reflect.TypeOf(namedWithUnexported{}).PkgPath()) + ".namedWithUnexported",
reason: "panic on named struct type with unexported field",
}, {
- label: label,
+ label: label + "/PanicUnexportedUnnamed",
x: struct{ a int }{},
y: struct{ a int }{},
wantPanic: strconv.Quote(reflect.TypeOf(namedWithUnexported{}).PkgPath()) + ".(struct { a int })",
reason: "panic on unnamed struct type with unexported field",
}, {
- label: label,
+ label: label + "/UnaddressableStruct",
x: struct{ s fmt.Stringer }{new(bytes.Buffer)},
y: struct{ s fmt.Stringer }{nil},
opts: []cmp.Option{
@@ -676,7 +719,7 @@ func transformerTests() []test {
}
return []test{{
- label: label,
+ label: label + "/Uints",
x: uint8(0),
y: uint8(1),
opts: []cmp.Option{
@@ -685,8 +728,9 @@ func transformerTests() []test {
cmp.Transformer("λ", func(in uint32) uint64 { return uint64(in) }),
},
wantEqual: false,
+ reason: "transform uint8 -> uint16 -> uint32 -> uint64",
}, {
- label: label,
+ label: label + "/Ambiguous",
x: 0,
y: 1,
opts: []cmp.Option{
@@ -694,8 +738,9 @@ func transformerTests() []test {
cmp.Transformer("λ", func(in int) int { return in }),
},
wantPanic: "ambiguous set of applicable options",
+ reason: "both transformers apply on int",
}, {
- label: label,
+ label: label + "/Filtered",
x: []int{0, -5, 0, -1},
y: []int{1, 3, 0, -5},
opts: []cmp.Option{
@@ -709,8 +754,9 @@ func transformerTests() []test {
),
},
wantEqual: false,
+ reason: "disjoint transformers filtered based on the values",
}, {
- label: label,
+ label: label + "/DisjointOutput",
x: 0,
y: 1,
opts: []cmp.Option{
@@ -722,8 +768,9 @@ func transformerTests() []test {
}),
},
wantEqual: false,
+ reason: "output type differs based on input value",
}, {
- label: label,
+ label: label + "/JSON",
x: `{
"firstName": "John",
"lastName": "Smith",
@@ -761,8 +808,9 @@ func transformerTests() []test {
}),
},
wantEqual: false,
+ reason: "transformer used to parse JSON input",
}, {
- label: label,
+ label: label + "/AcyclicString",
x: StringBytes{String: "some\nmulti\nLine\nstring", Bytes: []byte("some\nmulti\nline\nbytes")},
y: StringBytes{String: "some\nmulti\nline\nstring", Bytes: []byte("some\nmulti\nline\nBytes")},
opts: []cmp.Option{
@@ -770,22 +818,27 @@ func transformerTests() []test {
transformOnce("SplitBytes", func(b []byte) [][]byte { return bytes.Split(b, []byte("\n")) }),
},
wantEqual: false,
+ reason: "string -> []string and []byte -> [][]byte transformer only applied once",
}, {
- x: "a\nb\nc\n",
- y: "a\nb\nc\n",
+ label: label + "/CyclicString",
+ x: "a\nb\nc\n",
+ y: "a\nb\nc\n",
opts: []cmp.Option{
cmp.Transformer("SplitLines", func(s string) []string { return strings.Split(s, "\n") }),
},
wantPanic: "recursive set of Transformers detected",
+ reason: "cyclic transformation from string -> []string -> string",
}, {
- x: complex64(0),
- y: complex64(0),
+ label: label + "/CyclicComplex",
+ x: complex64(0),
+ y: complex64(0),
opts: []cmp.Option{
cmp.Transformer("T1", func(x complex64) complex128 { return complex128(x) }),
cmp.Transformer("T2", func(x complex128) [2]float64 { return [2]float64{real(x), imag(x)} }),
cmp.Transformer("T3", func(x float64) complex64 { return complex64(complex(x, 0)) }),
},
wantPanic: "recursive set of Transformers detected",
+ reason: "cyclic transformation from complex64 -> complex128 -> [2]float64 -> complex64",
}}
}
@@ -915,18 +968,18 @@ func reporterTests() []test {
wantEqual: false,
reason: "reporter should call String as there is no ambiguity between the two map keys",
}, {
- label: "/InvalidUTF8",
+ label: label + "/InvalidUTF8",
x: MyString("\xed\xa0\x80"),
wantEqual: false,
reason: "invalid UTF-8 should format as quoted string",
}, {
- label: label,
+ label: label + "/UnbatchedSlice",
x: MyComposite{IntsA: []int8{11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}},
y: MyComposite{IntsA: []int8{10, 11, 21, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}},
wantEqual: false,
reason: "unbatched diffing desired since few elements differ",
}, {
- label: label,
+ label: label + "/BatchedSlice",
x: MyComposite{IntsA: []int8{10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}},
y: MyComposite{IntsA: []int8{12, 29, 13, 27, 22, 23, 17, 18, 19, 20, 21, 10, 26, 16, 25, 28, 11, 15, 24, 14}},
wantEqual: false,
@@ -946,7 +999,7 @@ func reporterTests() []test {
wantEqual: false,
reason: "batched output desired for a single slice of primitives unique to one of the inputs",
}, {
- label: label,
+ label: label + "/BatchedNamedAndUnnamed",
x: MyComposite{
BytesA: []byte{1, 2, 3},
BytesB: []MyByte{4, 5, 6},
@@ -978,19 +1031,19 @@ func reporterTests() []test {
wantEqual: false,
reason: "batched diffing available for both named and unnamed slices",
}, {
- label: label,
+ label: label + "/BinaryHexdump",
x: MyComposite{BytesA: []byte("\xf3\x0f\x8a\xa4\xd3\x12R\t$\xbeX\x95A\xfd$fX\x8byT\xac\r\xd8qwp\x20j\\s\u007f\x8c\x17U\xc04\xcen\xf7\xaaG\xee2\x9d\xc5\xca\x1eX\xaf\x8f'\xf3\x02J\x90\xedi.p2\xb4\xab0 \xb6\xbd\\b4\x17\xb0\x00\xbbO~'G\x06\xf4.f\xfdc\xd7\x04ݷ0\xb7\xd1U~{\xf6\xb3~\x1dWi \x9e\xbc\xdf\xe1M\xa9\xef\xa2\xd2\xed\xb4Gx\xc9\xc9'\xa4\xc6\xce\xecDp]")},
y: MyComposite{BytesA: []byte("\xf3\x0f\x8a\xa4\xd3\x12R\t$\xbeT\xac\r\xd8qwp\x20j\\s\u007f\x8c\x17U\xc04\xcen\xf7\xaaG\xee2\x9d\xc5\xca\x1eX\xaf\x8f'\xf3\x02J\x90\xedi.p2\xb4\xab0 \xb6\xbd\\b4\x17\xb0\x00\xbbO~'G\x06\xf4.f\xfdc\xd7\x04ݷ0\xb7\xd1u-[]]\xf6\xb3haha~\x1dWI \x9e\xbc\xdf\xe1M\xa9\xef\xa2\xd2\xed\xb4Gx\xc9\xc9'\xa4\xc6\xce\xecDp]")},
wantEqual: false,
reason: "binary diff in hexdump form since data is binary data",
}, {
- label: label,
+ label: label + "/StringHexdump",
x: MyComposite{StringB: MyString("readme.txt\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000000600\x000000000\x000000000\x0000000000046\x0000000000000\x00011173\x00 0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ustar\x0000\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000000000\x000000000\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")},
y: MyComposite{StringB: MyString("gopher.txt\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000000600\x000000000\x000000000\x0000000000043\x0000000000000\x00011217\x00 0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ustar\x0000\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000000000\x000000000\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")},
wantEqual: false,
reason: "binary diff desired since string looks like binary data",
}, {
- label: label,
+ label: label + "/BinaryString",
x: MyComposite{BytesA: []byte(`{"firstName":"John","lastName":"Smith","isAlive":true,"age":27,"address":{"streetAddress":"314 54th Avenue","city":"New York","state":"NY","postalCode":"10021-3100"},"phoneNumbers":[{"type":"home","number":"212 555-1234"},{"type":"office","number":"646 555-4567"},{"type":"mobile","number":"123 456-7890"}],"children":[],"spouse":null}`)},
y: MyComposite{BytesA: []byte(`{"firstName":"John","lastName":"Smith","isAlive":true,"age":27,"address":{"streetAddress":"21 2nd Street","city":"New York","state":"NY","postalCode":"10021-3100"},"phoneNumbers":[{"type":"home","number":"212 555-1234"},{"type":"office","number":"646 555-4567"},{"type":"mobile","number":"123 456-7890"}],"children":[],"spouse":null}`)},
wantEqual: false,
@@ -1096,7 +1149,7 @@ func reporterTests() []test {
wantEqual: false,
reason: "total slice difference output is truncated due to excessive number of differences",
}, {
- label: label,
+ label: label + "/MultilineString",
x: MyComposite{
StringA: strings.TrimPrefix(`
Package cmp determines equality of values.
@@ -1147,7 +1200,7 @@ using the AllowUnexported option.`, "\n"),
wantEqual: false,
reason: "batched per-line diff desired since string looks like multi-line textual data",
}, {
- label: label,
+ label: label + "/Slices",
x: MyComposite{
BytesA: []byte{1, 2, 3},
BytesB: []MyByte{4, 5, 6},
@@ -1166,7 +1219,7 @@ using the AllowUnexported option.`, "\n"),
wantEqual: false,
reason: "batched diffing for non-nil slices and nil slices",
}, {
- label: label,
+ label: label + "/EmptySlices",
x: MyComposite{
BytesA: []byte{},
BytesB: []MyByte{},
@@ -1188,7 +1241,7 @@ using the AllowUnexported option.`, "\n"),
}
func embeddedTests() []test {
- const label = "EmbeddedStruct/"
+ const label = "EmbeddedStruct"
privateStruct := *new(ts.ParentStructA).PrivateStruct()
@@ -1289,52 +1342,58 @@ func embeddedTests() []test {
}
return []test{{
- label: label + "ParentStructA",
+ label: label + "/ParentStructA/PanicUnexported1",
x: ts.ParentStructA{},
y: ts.ParentStructA{},
wantPanic: "cannot handle unexported field",
+ reason: "ParentStructA has an unexported field",
}, {
- label: label + "ParentStructA",
+ label: label + "/ParentStructA/Ignored",
x: ts.ParentStructA{},
y: ts.ParentStructA{},
opts: []cmp.Option{
cmpopts.IgnoreUnexported(ts.ParentStructA{}),
},
wantEqual: true,
+ reason: "the only field (which is unexported) of ParentStructA is ignored",
}, {
- label: label + "ParentStructA",
+ label: label + "/ParentStructA/PanicUnexported2",
x: createStructA(0),
y: createStructA(0),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructA{}),
},
wantPanic: "cannot handle unexported field",
+ reason: "privateStruct also has unexported fields",
}, {
- label: label + "ParentStructA",
+ label: label + "/ParentStructA/Equal",
x: createStructA(0),
y: createStructA(0),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructA{}, privateStruct),
},
wantEqual: true,
+ reason: "unexported fields of both ParentStructA and privateStruct are allowed",
}, {
- label: label + "ParentStructA",
+ label: label + "/ParentStructA/Inequal",
x: createStructA(0),
y: createStructA(1),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructA{}, privateStruct),
},
wantEqual: false,
+ reason: "the two values differ on some fields",
}, {
- label: label + "ParentStructB",
+ label: label + "/ParentStructB/PanicUnexported1",
x: ts.ParentStructB{},
y: ts.ParentStructB{},
opts: []cmp.Option{
cmpopts.IgnoreUnexported(ts.ParentStructB{}),
},
wantPanic: "cannot handle unexported field",
+ reason: "PublicStruct has an unexported field",
}, {
- label: label + "ParentStructB",
+ label: label + "/ParentStructB/Ignored",
x: ts.ParentStructB{},
y: ts.ParentStructB{},
opts: []cmp.Option{
@@ -1342,77 +1401,87 @@ func embeddedTests() []test {
cmpopts.IgnoreUnexported(ts.PublicStruct{}),
},
wantEqual: true,
+ reason: "unexported fields of both ParentStructB and PublicStruct are ignored",
}, {
- label: label + "ParentStructB",
+ label: label + "/ParentStructB/PanicUnexported2",
x: createStructB(0),
y: createStructB(0),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructB{}),
},
wantPanic: "cannot handle unexported field",
+ reason: "PublicStruct also has unexported fields",
}, {
- label: label + "ParentStructB",
+ label: label + "/ParentStructB/Equal",
x: createStructB(0),
y: createStructB(0),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructB{}, ts.PublicStruct{}),
},
wantEqual: true,
+ reason: "unexported fields of both ParentStructB and PublicStruct are allowed",
}, {
- label: label + "ParentStructB",
+ label: label + "/ParentStructB/Inequal",
x: createStructB(0),
y: createStructB(1),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructB{}, ts.PublicStruct{}),
},
wantEqual: false,
+ reason: "the two values differ on some fields",
}, {
- label: label + "ParentStructC",
+ label: label + "/ParentStructC/PanicUnexported1",
x: ts.ParentStructC{},
y: ts.ParentStructC{},
wantPanic: "cannot handle unexported field",
+ reason: "ParentStructC has unexported fields",
}, {
- label: label + "ParentStructC",
+ label: label + "/ParentStructC/Ignored",
x: ts.ParentStructC{},
y: ts.ParentStructC{},
opts: []cmp.Option{
cmpopts.IgnoreUnexported(ts.ParentStructC{}),
},
wantEqual: true,
+ reason: "unexported fields of ParentStructC are ignored",
}, {
- label: label + "ParentStructC",
+ label: label + "/ParentStructC/PanicUnexported2",
x: createStructC(0),
y: createStructC(0),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructC{}),
},
wantPanic: "cannot handle unexported field",
+ reason: "privateStruct also has unexported fields",
}, {
- label: label + "ParentStructC",
+ label: label + "/ParentStructC/Equal",
x: createStructC(0),
y: createStructC(0),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructC{}, privateStruct),
},
wantEqual: true,
+ reason: "unexported fields of both ParentStructC and privateStruct are allowed",
}, {
- label: label + "ParentStructC",
+ label: label + "/ParentStructC/Inequal",
x: createStructC(0),
y: createStructC(1),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructC{}, privateStruct),
},
wantEqual: false,
+ reason: "the two values differ on some fields",
}, {
- label: label + "ParentStructD",
+ label: label + "/ParentStructD/PanicUnexported1",
x: ts.ParentStructD{},
y: ts.ParentStructD{},
opts: []cmp.Option{
cmpopts.IgnoreUnexported(ts.ParentStructD{}),
},
wantPanic: "cannot handle unexported field",
+ reason: "ParentStructD has unexported fields",
}, {
- label: label + "ParentStructD",
+ label: label + "/ParentStructD/Ignored",
x: ts.ParentStructD{},
y: ts.ParentStructD{},
opts: []cmp.Option{
@@ -1420,40 +1489,45 @@ func embeddedTests() []test {
cmpopts.IgnoreUnexported(ts.PublicStruct{}),
},
wantEqual: true,
+ reason: "unexported fields of ParentStructD and PublicStruct are ignored",
}, {
- label: label + "ParentStructD",
+ label: label + "/ParentStructD/PanicUnexported2",
x: createStructD(0),
y: createStructD(0),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructD{}),
},
wantPanic: "cannot handle unexported field",
+ reason: "PublicStruct also has unexported fields",
}, {
- label: label + "ParentStructD",
+ label: label + "/ParentStructD/Equal",
x: createStructD(0),
y: createStructD(0),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructD{}, ts.PublicStruct{}),
},
wantEqual: true,
+ reason: "unexported fields of both ParentStructD and PublicStruct are allowed",
}, {
- label: label + "ParentStructD",
+ label: label + "/ParentStructD/Inequal",
x: createStructD(0),
y: createStructD(1),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructD{}, ts.PublicStruct{}),
},
wantEqual: false,
+ reason: "the two values differ on some fields",
}, {
- label: label + "ParentStructE",
+ label: label + "/ParentStructE/PanicUnexported1",
x: ts.ParentStructE{},
y: ts.ParentStructE{},
opts: []cmp.Option{
cmpopts.IgnoreUnexported(ts.ParentStructE{}),
},
wantPanic: "cannot handle unexported field",
+ reason: "ParentStructE has unexported fields",
}, {
- label: label + "ParentStructE",
+ label: label + "/ParentStructE/Ignored",
x: ts.ParentStructE{},
y: ts.ParentStructE{},
opts: []cmp.Option{
@@ -1461,48 +1535,54 @@ func embeddedTests() []test {
cmpopts.IgnoreUnexported(ts.PublicStruct{}),
},
wantEqual: true,
+ reason: "unexported fields of ParentStructE and PublicStruct are ignored",
}, {
- label: label + "ParentStructE",
+ label: label + "/ParentStructE/PanicUnexported2",
x: createStructE(0),
y: createStructE(0),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructE{}),
},
wantPanic: "cannot handle unexported field",
+ reason: "PublicStruct and privateStruct also has unexported fields",
}, {
- label: label + "ParentStructE",
+ label: label + "/ParentStructE/PanicUnexported3",
x: createStructE(0),
y: createStructE(0),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructE{}, ts.PublicStruct{}),
},
wantPanic: "cannot handle unexported field",
+ reason: "privateStruct also has unexported fields",
}, {
- label: label + "ParentStructE",
+ label: label + "/ParentStructE/Equal",
x: createStructE(0),
y: createStructE(0),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructE{}, ts.PublicStruct{}, privateStruct),
},
wantEqual: true,
+ reason: "unexported fields of both ParentStructE, PublicStruct, and privateStruct are allowed",
}, {
- label: label + "ParentStructE",
+ label: label + "/ParentStructE/Inequal",
x: createStructE(0),
y: createStructE(1),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructE{}, ts.PublicStruct{}, privateStruct),
},
wantEqual: false,
+ reason: "the two values differ on some fields",
}, {
- label: label + "ParentStructF",
+ label: label + "/ParentStructF/PanicUnexported1",
x: ts.ParentStructF{},
y: ts.ParentStructF{},
opts: []cmp.Option{
cmpopts.IgnoreUnexported(ts.ParentStructF{}),
},
wantPanic: "cannot handle unexported field",
+ reason: "ParentStructF has unexported fields",
}, {
- label: label + "ParentStructF",
+ label: label + "/ParentStructF/Ignored",
x: ts.ParentStructF{},
y: ts.ParentStructF{},
opts: []cmp.Option{
@@ -1510,227 +1590,256 @@ func embeddedTests() []test {
cmpopts.IgnoreUnexported(ts.PublicStruct{}),
},
wantEqual: true,
+ reason: "unexported fields of ParentStructF and PublicStruct are ignored",
}, {
- label: label + "ParentStructF",
+ label: label + "/ParentStructF/PanicUnexported2",
x: createStructF(0),
y: createStructF(0),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructF{}),
},
wantPanic: "cannot handle unexported field",
+ reason: "PublicStruct and privateStruct also has unexported fields",
}, {
- label: label + "ParentStructF",
+ label: label + "/ParentStructF/PanicUnexported3",
x: createStructF(0),
y: createStructF(0),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructF{}, ts.PublicStruct{}),
},
wantPanic: "cannot handle unexported field",
+ reason: "privateStruct also has unexported fields",
}, {
- label: label + "ParentStructF",
+ label: label + "/ParentStructF/Equal",
x: createStructF(0),
y: createStructF(0),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructF{}, ts.PublicStruct{}, privateStruct),
},
wantEqual: true,
+ reason: "unexported fields of both ParentStructF, PublicStruct, and privateStruct are allowed",
}, {
- label: label + "ParentStructF",
+ label: label + "/ParentStructF/Inequal",
x: createStructF(0),
y: createStructF(1),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructF{}, ts.PublicStruct{}, privateStruct),
},
wantEqual: false,
+ reason: "the two values differ on some fields",
}, {
- label: label + "ParentStructG",
+ label: label + "/ParentStructG/PanicUnexported1",
x: ts.ParentStructG{},
y: ts.ParentStructG{},
wantPanic: wantPanicNotGo110("cannot handle unexported field"),
wantEqual: !flags.AtLeastGo110,
+ reason: "ParentStructG has unexported fields",
}, {
- label: label + "ParentStructG",
+ label: label + "/ParentStructG/Ignored",
x: ts.ParentStructG{},
y: ts.ParentStructG{},
opts: []cmp.Option{
cmpopts.IgnoreUnexported(ts.ParentStructG{}),
},
wantEqual: true,
+ reason: "unexported fields of ParentStructG are ignored",
}, {
- label: label + "ParentStructG",
+ label: label + "/ParentStructG/PanicUnexported2",
x: createStructG(0),
y: createStructG(0),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructG{}),
},
wantPanic: "cannot handle unexported field",
+ reason: "privateStruct also has unexported fields",
}, {
- label: label + "ParentStructG",
+ label: label + "/ParentStructG/Equal",
x: createStructG(0),
y: createStructG(0),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructG{}, privateStruct),
},
wantEqual: true,
+ reason: "unexported fields of both ParentStructG and privateStruct are allowed",
}, {
- label: label + "ParentStructG",
+ label: label + "/ParentStructG/Inequal",
x: createStructG(0),
y: createStructG(1),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructG{}, privateStruct),
},
wantEqual: false,
+ reason: "the two values differ on some fields",
}, {
- label: label + "ParentStructH",
+ label: label + "/ParentStructH/EqualNil",
x: ts.ParentStructH{},
y: ts.ParentStructH{},
wantEqual: true,
+ reason: "PublicStruct is not compared because the pointer is nil",
}, {
- label: label + "ParentStructH",
+ label: label + "/ParentStructH/PanicUnexported1",
x: createStructH(0),
y: createStructH(0),
wantPanic: "cannot handle unexported field",
+ reason: "PublicStruct has unexported fields",
}, {
- label: label + "ParentStructH",
+ label: label + "/ParentStructH/Ignored",
x: ts.ParentStructH{},
y: ts.ParentStructH{},
opts: []cmp.Option{
cmpopts.IgnoreUnexported(ts.ParentStructH{}),
},
wantEqual: true,
+ reason: "unexported fields of ParentStructH are ignored (it has none)",
}, {
- label: label + "ParentStructH",
+ label: label + "/ParentStructH/PanicUnexported2",
x: createStructH(0),
y: createStructH(0),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructH{}),
},
wantPanic: "cannot handle unexported field",
+ reason: "PublicStruct also has unexported fields",
}, {
- label: label + "ParentStructH",
+ label: label + "/ParentStructH/Equal",
x: createStructH(0),
y: createStructH(0),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructH{}, ts.PublicStruct{}),
},
wantEqual: true,
+ reason: "unexported fields of both ParentStructH and PublicStruct are allowed",
}, {
- label: label + "ParentStructH",
+ label: label + "/ParentStructH/Inequal",
x: createStructH(0),
y: createStructH(1),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructH{}, ts.PublicStruct{}),
},
wantEqual: false,
+ reason: "the two values differ on some fields",
}, {
- label: label + "ParentStructI",
+ label: label + "/ParentStructI/PanicUnexported1",
x: ts.ParentStructI{},
y: ts.ParentStructI{},
wantPanic: wantPanicNotGo110("cannot handle unexported field"),
wantEqual: !flags.AtLeastGo110,
+ reason: "ParentStructI has unexported fields",
}, {
- label: label + "ParentStructI",
+ label: label + "/ParentStructI/Ignored1",
x: ts.ParentStructI{},
y: ts.ParentStructI{},
opts: []cmp.Option{
cmpopts.IgnoreUnexported(ts.ParentStructI{}),
},
wantEqual: true,
+ reason: "unexported fields of ParentStructI are ignored",
}, {
- label: label + "ParentStructI",
+ label: label + "/ParentStructI/PanicUnexported2",
x: createStructI(0),
y: createStructI(0),
opts: []cmp.Option{
cmpopts.IgnoreUnexported(ts.ParentStructI{}),
},
wantPanic: "cannot handle unexported field",
+ reason: "PublicStruct and privateStruct also has unexported fields",
}, {
- label: label + "ParentStructI",
+ label: label + "/ParentStructI/Ignored2",
x: createStructI(0),
y: createStructI(0),
opts: []cmp.Option{
cmpopts.IgnoreUnexported(ts.ParentStructI{}, ts.PublicStruct{}),
},
wantEqual: true,
+ reason: "unexported fields of ParentStructI and PublicStruct are ignored",
}, {
- label: label + "ParentStructI",
+ label: label + "/ParentStructI/PanicUnexported3",
x: createStructI(0),
y: createStructI(0),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructI{}),
},
wantPanic: "cannot handle unexported field",
+ reason: "PublicStruct and privateStruct also has unexported fields",
}, {
- label: label + "ParentStructI",
+ label: label + "/ParentStructI/Equal",
x: createStructI(0),
y: createStructI(0),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructI{}, ts.PublicStruct{}, privateStruct),
},
wantEqual: true,
+ reason: "unexported fields of both ParentStructI, PublicStruct, and privateStruct are allowed",
}, {
- label: label + "ParentStructI",
+ label: label + "/ParentStructI/Inequal",
x: createStructI(0),
y: createStructI(1),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructI{}, ts.PublicStruct{}, privateStruct),
},
wantEqual: false,
+ reason: "the two values differ on some fields",
}, {
- label: label + "ParentStructJ",
+ label: label + "/ParentStructJ/PanicUnexported1",
x: ts.ParentStructJ{},
y: ts.ParentStructJ{},
wantPanic: "cannot handle unexported field",
+ reason: "ParentStructJ has unexported fields",
}, {
- label: label + "ParentStructJ",
+ label: label + "/ParentStructJ/PanicUnexported2",
x: ts.ParentStructJ{},
y: ts.ParentStructJ{},
opts: []cmp.Option{
cmpopts.IgnoreUnexported(ts.ParentStructJ{}),
},
wantPanic: "cannot handle unexported field",
+ reason: "PublicStruct and privateStruct also has unexported fields",
}, {
- label: label + "ParentStructJ",
+ label: label + "/ParentStructJ/Ignored",
x: ts.ParentStructJ{},
y: ts.ParentStructJ{},
opts: []cmp.Option{
cmpopts.IgnoreUnexported(ts.ParentStructJ{}, ts.PublicStruct{}),
},
wantEqual: true,
+ reason: "unexported fields of ParentStructJ and PublicStruct are ignored",
}, {
- label: label + "ParentStructJ",
+ label: label + "/ParentStructJ/PanicUnexported3",
x: createStructJ(0),
y: createStructJ(0),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructJ{}, ts.PublicStruct{}),
},
wantPanic: "cannot handle unexported field",
+ reason: "privateStruct also has unexported fields",
}, {
- label: label + "ParentStructJ",
+ label: label + "/ParentStructJ/Equal",
x: createStructJ(0),
y: createStructJ(0),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructJ{}, ts.PublicStruct{}, privateStruct),
},
wantEqual: true,
+ reason: "unexported fields of both ParentStructJ, PublicStruct, and privateStruct are allowed",
}, {
- label: label + "ParentStructJ",
+ label: label + "/ParentStructJ/Inequal",
x: createStructJ(0),
y: createStructJ(1),
opts: []cmp.Option{
cmp.AllowUnexported(ts.ParentStructJ{}, ts.PublicStruct{}, privateStruct),
},
wantEqual: false,
+ reason: "the two values differ on some fields",
}}
}
func methodTests() []test {
- const label = "EqualMethod/"
+ const label = "EqualMethod"
// A common mistake that the Equal method is on a pointer receiver,
// but only a non-pointer value is present in the struct.
// A transform can be used to forcibly reference the value.
- derefTransform := cmp.FilterPath(func(p cmp.Path) bool {
+ addrTransform := cmp.FilterPath(func(p cmp.Path) bool {
if len(p) == 0 {
return false
}
@@ -1744,7 +1853,7 @@ func methodTests() []test {
tf.In(0).AssignableTo(tf.In(1)) && tf.Out(0) == reflect.TypeOf(true)
}
return false
- }, cmp.Transformer("Ref", func(x interface{}) interface{} {
+ }, cmp.Transformer("Addr", func(x interface{}) interface{} {
v := reflect.ValueOf(x)
vp := reflect.New(v.Type())
vp.Elem().Set(v)
@@ -1755,284 +1864,338 @@ func methodTests() []test {
// returns true, while the underlying data are fundamentally different.
// Since the method should be called, these are expected to be equal.
return []test{{
- label: label + "StructA",
+ label: label + "/StructA/ValueEqual",
x: ts.StructA{X: "NotEqual"},
y: ts.StructA{X: "not_equal"},
wantEqual: true,
+ reason: "Equal method on StructA value called",
}, {
- label: label + "StructA",
+ label: label + "/StructA/PointerEqual",
x: &ts.StructA{X: "NotEqual"},
y: &ts.StructA{X: "not_equal"},
wantEqual: true,
+ reason: "Equal method on StructA pointer called",
}, {
- label: label + "StructB",
+ label: label + "/StructB/ValueInequal",
x: ts.StructB{X: "NotEqual"},
y: ts.StructB{X: "not_equal"},
wantEqual: false,
+ reason: "Equal method on StructB value not called",
}, {
- label: label + "StructB",
+ label: label + "/StructB/ValueAddrEqual",
x: ts.StructB{X: "NotEqual"},
y: ts.StructB{X: "not_equal"},
- opts: []cmp.Option{derefTransform},
+ opts: []cmp.Option{addrTransform},
wantEqual: true,
+ reason: "Equal method on StructB pointer called due to shallow copy transform",
}, {
- label: label + "StructB",
+ label: label + "/StructB/PointerEqual",
x: &ts.StructB{X: "NotEqual"},
y: &ts.StructB{X: "not_equal"},
wantEqual: true,
+ reason: "Equal method on StructB pointer called",
}, {
- label: label + "StructC",
+ label: label + "/StructC/ValueEqual",
x: ts.StructC{X: "NotEqual"},
y: ts.StructC{X: "not_equal"},
wantEqual: true,
+ reason: "Equal method on StructC value called",
}, {
- label: label + "StructC",
+ label: label + "/StructC/PointerEqual",
x: &ts.StructC{X: "NotEqual"},
y: &ts.StructC{X: "not_equal"},
wantEqual: true,
+ reason: "Equal method on StructC pointer called",
}, {
- label: label + "StructD",
+ label: label + "/StructD/ValueInequal",
x: ts.StructD{X: "NotEqual"},
y: ts.StructD{X: "not_equal"},
wantEqual: false,
+ reason: "Equal method on StructD value not called",
}, {
- label: label + "StructD",
+ label: label + "/StructD/ValueAddrEqual",
x: ts.StructD{X: "NotEqual"},
y: ts.StructD{X: "not_equal"},
- opts: []cmp.Option{derefTransform},
+ opts: []cmp.Option{addrTransform},
wantEqual: true,
+ reason: "Equal method on StructD pointer called due to shallow copy transform",
}, {
- label: label + "StructD",
+ label: label + "/StructD/PointerEqual",
x: &ts.StructD{X: "NotEqual"},
y: &ts.StructD{X: "not_equal"},
wantEqual: true,
+ reason: "Equal method on StructD pointer called",
}, {
- label: label + "StructE",
+ label: label + "/StructE/ValueInequal",
x: ts.StructE{X: "NotEqual"},
y: ts.StructE{X: "not_equal"},
wantEqual: false,
+ reason: "Equal method on StructE value not called",
}, {
- label: label + "StructE",
+ label: label + "/StructE/ValueAddrEqual",
x: ts.StructE{X: "NotEqual"},
y: ts.StructE{X: "not_equal"},
- opts: []cmp.Option{derefTransform},
+ opts: []cmp.Option{addrTransform},
wantEqual: true,
+ reason: "Equal method on StructE pointer called due to shallow copy transform",
}, {
- label: label + "StructE",
+ label: label + "/StructE/PointerEqual",
x: &ts.StructE{X: "NotEqual"},
y: &ts.StructE{X: "not_equal"},
wantEqual: true,
+ reason: "Equal method on StructE pointer called",
}, {
- label: label + "StructF",
+ label: label + "/StructF/ValueInequal",
x: ts.StructF{X: "NotEqual"},
y: ts.StructF{X: "not_equal"},
wantEqual: false,
+ reason: "Equal method on StructF value not called",
}, {
- label: label + "StructF",
+ label: label + "/StructF/PointerEqual",
x: &ts.StructF{X: "NotEqual"},
y: &ts.StructF{X: "not_equal"},
wantEqual: true,
+ reason: "Equal method on StructF pointer called",
}, {
- label: label + "StructA1",
+ label: label + "/StructA1/ValueEqual",
x: ts.StructA1{StructA: ts.StructA{X: "NotEqual"}, X: "equal"},
y: ts.StructA1{StructA: ts.StructA{X: "not_equal"}, X: "equal"},
wantEqual: true,
+ reason: "Equal method on StructA value called with equal X field",
}, {
- label: label + "StructA1",
+ label: label + "/StructA1/ValueInequal",
x: ts.StructA1{StructA: ts.StructA{X: "NotEqual"}, X: "NotEqual"},
y: ts.StructA1{StructA: ts.StructA{X: "not_equal"}, X: "not_equal"},
wantEqual: false,
+ reason: "Equal method on StructA value called, but inequal X field",
}, {
- label: label + "StructA1",
+ label: label + "/StructA1/PointerEqual",
x: &ts.StructA1{StructA: ts.StructA{X: "NotEqual"}, X: "equal"},
y: &ts.StructA1{StructA: ts.StructA{X: "not_equal"}, X: "equal"},
wantEqual: true,
+ reason: "Equal method on StructA value called with equal X field",
}, {
- label: label + "StructA1",
+ label: label + "/StructA1/PointerInequal",
x: &ts.StructA1{StructA: ts.StructA{X: "NotEqual"}, X: "NotEqual"},
y: &ts.StructA1{StructA: ts.StructA{X: "not_equal"}, X: "not_equal"},
wantEqual: false,
+ reason: "Equal method on StructA value called, but inequal X field",
}, {
- label: label + "StructB1",
+ label: label + "/StructB1/ValueEqual",
x: ts.StructB1{StructB: ts.StructB{X: "NotEqual"}, X: "equal"},
y: ts.StructB1{StructB: ts.StructB{X: "not_equal"}, X: "equal"},
- opts: []cmp.Option{derefTransform},
+ opts: []cmp.Option{addrTransform},
wantEqual: true,
+ reason: "Equal method on StructB pointer called due to shallow copy transform with equal X field",
}, {
- label: label + "StructB1",
+ label: label + "/StructB1/ValueInequal",
x: ts.StructB1{StructB: ts.StructB{X: "NotEqual"}, X: "NotEqual"},
y: ts.StructB1{StructB: ts.StructB{X: "not_equal"}, X: "not_equal"},
- opts: []cmp.Option{derefTransform},
+ opts: []cmp.Option{addrTransform},
wantEqual: false,
+ reason: "Equal method on StructB pointer called due to shallow copy transform, but inequal X field",
}, {
- label: label + "StructB1",
+ label: label + "/StructB1/PointerEqual",
x: &ts.StructB1{StructB: ts.StructB{X: "NotEqual"}, X: "equal"},
y: &ts.StructB1{StructB: ts.StructB{X: "not_equal"}, X: "equal"},
- opts: []cmp.Option{derefTransform},
+ opts: []cmp.Option{addrTransform},
wantEqual: true,
+ reason: "Equal method on StructB pointer called due to shallow copy transform with equal X field",
}, {
- label: label + "StructB1",
+ label: label + "/StructB1/PointerInequal",
x: &ts.StructB1{StructB: ts.StructB{X: "NotEqual"}, X: "NotEqual"},
y: &ts.StructB1{StructB: ts.StructB{X: "not_equal"}, X: "not_equal"},
- opts: []cmp.Option{derefTransform},
+ opts: []cmp.Option{addrTransform},
wantEqual: false,
+ reason: "Equal method on StructB pointer called due to shallow copy transform, but inequal X field",
}, {
- label: label + "StructC1",
+ label: label + "/StructC1/ValueEqual",
x: ts.StructC1{StructC: ts.StructC{X: "NotEqual"}, X: "NotEqual"},
y: ts.StructC1{StructC: ts.StructC{X: "not_equal"}, X: "not_equal"},
wantEqual: true,
+ reason: "Equal method on StructC1 value called",
}, {
- label: label + "StructC1",
+ label: label + "/StructC1/PointerEqual",
x: &ts.StructC1{StructC: ts.StructC{X: "NotEqual"}, X: "NotEqual"},
y: &ts.StructC1{StructC: ts.StructC{X: "not_equal"}, X: "not_equal"},
wantEqual: true,
+ reason: "Equal method on StructC1 pointer called",
}, {
- label: label + "StructD1",
+ label: label + "/StructD1/ValueInequal",
x: ts.StructD1{StructD: ts.StructD{X: "NotEqual"}, X: "NotEqual"},
y: ts.StructD1{StructD: ts.StructD{X: "not_equal"}, X: "not_equal"},
wantEqual: false,
+ reason: "Equal method on StructD1 value not called",
}, {
- label: label + "StructD1",
+ label: label + "/StructD1/PointerAddrEqual",
x: ts.StructD1{StructD: ts.StructD{X: "NotEqual"}, X: "NotEqual"},
y: ts.StructD1{StructD: ts.StructD{X: "not_equal"}, X: "not_equal"},
- opts: []cmp.Option{derefTransform},
+ opts: []cmp.Option{addrTransform},
wantEqual: true,
+ reason: "Equal method on StructD1 pointer called due to shallow copy transform",
}, {
- label: label + "StructD1",
+ label: label + "/StructD1/PointerEqual",
x: &ts.StructD1{StructD: ts.StructD{X: "NotEqual"}, X: "NotEqual"},
y: &ts.StructD1{StructD: ts.StructD{X: "not_equal"}, X: "not_equal"},
wantEqual: true,
+ reason: "Equal method on StructD1 pointer called",
}, {
- label: label + "StructE1",
+ label: label + "/StructE1/ValueInequal",
x: ts.StructE1{StructE: ts.StructE{X: "NotEqual"}, X: "NotEqual"},
y: ts.StructE1{StructE: ts.StructE{X: "not_equal"}, X: "not_equal"},
wantEqual: false,
+ reason: "Equal method on StructE1 value not called",
}, {
- label: label + "StructE1",
+ label: label + "/StructE1/ValueAddrEqual",
x: ts.StructE1{StructE: ts.StructE{X: "NotEqual"}, X: "NotEqual"},
y: ts.StructE1{StructE: ts.StructE{X: "not_equal"}, X: "not_equal"},
- opts: []cmp.Option{derefTransform},
+ opts: []cmp.Option{addrTransform},
wantEqual: true,
+ reason: "Equal method on StructE1 pointer called due to shallow copy transform",
}, {
- label: label + "StructE1",
+ label: label + "/StructE1/PointerEqual",
x: &ts.StructE1{StructE: ts.StructE{X: "NotEqual"}, X: "NotEqual"},
y: &ts.StructE1{StructE: ts.StructE{X: "not_equal"}, X: "not_equal"},
wantEqual: true,
+ reason: "Equal method on StructE1 pointer called",
}, {
- label: label + "StructF1",
+ label: label + "/StructF1/ValueInequal",
x: ts.StructF1{StructF: ts.StructF{X: "NotEqual"}, X: "NotEqual"},
y: ts.StructF1{StructF: ts.StructF{X: "not_equal"}, X: "not_equal"},
wantEqual: false,
+ reason: "Equal method on StructF1 value not called",
}, {
- label: label + "StructF1",
+ label: label + "/StructF1/PointerEqual",
x: &ts.StructF1{StructF: ts.StructF{X: "NotEqual"}, X: "NotEqual"},
y: &ts.StructF1{StructF: ts.StructF{X: "not_equal"}, X: "not_equal"},
wantEqual: true,
+ reason: "Equal method on StructF1 pointer called",
}, {
- label: label + "StructA2",
+ label: label + "/StructA2/ValueEqual",
x: ts.StructA2{StructA: &ts.StructA{X: "NotEqual"}, X: "equal"},
y: ts.StructA2{StructA: &ts.StructA{X: "not_equal"}, X: "equal"},
wantEqual: true,
+ reason: "Equal method on StructA pointer called with equal X field",
}, {
- label: label + "StructA2",
+ label: label + "/StructA2/ValueInequal",
x: ts.StructA2{StructA: &ts.StructA{X: "NotEqual"}, X: "NotEqual"},
y: ts.StructA2{StructA: &ts.StructA{X: "not_equal"}, X: "not_equal"},
wantEqual: false,
+ reason: "Equal method on StructA pointer called, but inequal X field",
}, {
- label: label + "StructA2",
+ label: label + "/StructA2/PointerEqual",
x: &ts.StructA2{StructA: &ts.StructA{X: "NotEqual"}, X: "equal"},
y: &ts.StructA2{StructA: &ts.StructA{X: "not_equal"}, X: "equal"},
wantEqual: true,
+ reason: "Equal method on StructA pointer called with equal X field",
}, {
- label: label + "StructA2",
+ label: label + "/StructA2/PointerInequal",
x: &ts.StructA2{StructA: &ts.StructA{X: "NotEqual"}, X: "NotEqual"},
y: &ts.StructA2{StructA: &ts.StructA{X: "not_equal"}, X: "not_equal"},
wantEqual: false,
+ reason: "Equal method on StructA pointer called, but inequal X field",
}, {
- label: label + "StructB2",
+ label: label + "/StructB2/ValueEqual",
x: ts.StructB2{StructB: &ts.StructB{X: "NotEqual"}, X: "equal"},
y: ts.StructB2{StructB: &ts.StructB{X: "not_equal"}, X: "equal"},
wantEqual: true,
+ reason: "Equal method on StructB pointer called with equal X field",
}, {
- label: label + "StructB2",
+ label: label + "/StructB2/ValueInequal",
x: ts.StructB2{StructB: &ts.StructB{X: "NotEqual"}, X: "NotEqual"},
y: ts.StructB2{StructB: &ts.StructB{X: "not_equal"}, X: "not_equal"},
wantEqual: false,
+ reason: "Equal method on StructB pointer called, but inequal X field",
}, {
- label: label + "StructB2",
+ label: label + "/StructB2/PointerEqual",
x: &ts.StructB2{StructB: &ts.StructB{X: "NotEqual"}, X: "equal"},
y: &ts.StructB2{StructB: &ts.StructB{X: "not_equal"}, X: "equal"},
wantEqual: true,
+ reason: "Equal method on StructB pointer called with equal X field",
}, {
- label: label + "StructB2",
+ label: label + "/StructB2/PointerInequal",
x: &ts.StructB2{StructB: &ts.StructB{X: "NotEqual"}, X: "NotEqual"},
y: &ts.StructB2{StructB: &ts.StructB{X: "not_equal"}, X: "not_equal"},
wantEqual: false,
+ reason: "Equal method on StructB pointer called, but inequal X field",
}, {
- label: label + "StructC2",
+ label: label + "/StructC2/ValueEqual",
x: ts.StructC2{StructC: &ts.StructC{X: "NotEqual"}, X: "NotEqual"},
y: ts.StructC2{StructC: &ts.StructC{X: "not_equal"}, X: "not_equal"},
wantEqual: true,
+ reason: "Equal method called on StructC2 value due to forwarded StructC pointer",
}, {
- label: label + "StructC2",
+ label: label + "/StructC2/PointerEqual",
x: &ts.StructC2{StructC: &ts.StructC{X: "NotEqual"}, X: "NotEqual"},
y: &ts.StructC2{StructC: &ts.StructC{X: "not_equal"}, X: "not_equal"},
wantEqual: true,
+ reason: "Equal method called on StructC2 pointer due to forwarded StructC pointer",
}, {
- label: label + "StructD2",
+ label: label + "/StructD2/ValueEqual",
x: ts.StructD2{StructD: &ts.StructD{X: "NotEqual"}, X: "NotEqual"},
y: ts.StructD2{StructD: &ts.StructD{X: "not_equal"}, X: "not_equal"},
wantEqual: true,
+ reason: "Equal method called on StructD2 value due to forwarded StructD pointer",
}, {
- label: label + "StructD2",
+ label: label + "/StructD2/PointerEqual",
x: &ts.StructD2{StructD: &ts.StructD{X: "NotEqual"}, X: "NotEqual"},
y: &ts.StructD2{StructD: &ts.StructD{X: "not_equal"}, X: "not_equal"},
wantEqual: true,
+ reason: "Equal method called on StructD2 pointer due to forwarded StructD pointer",
}, {
- label: label + "StructE2",
+ label: label + "/StructE2/ValueEqual",
x: ts.StructE2{StructE: &ts.StructE{X: "NotEqual"}, X: "NotEqual"},
y: ts.StructE2{StructE: &ts.StructE{X: "not_equal"}, X: "not_equal"},
wantEqual: true,
+ reason: "Equal method called on StructE2 value due to forwarded StructE pointer",
}, {
- label: label + "StructE2",
+ label: label + "/StructE2/PointerEqual",
x: &ts.StructE2{StructE: &ts.StructE{X: "NotEqual"}, X: "NotEqual"},
y: &ts.StructE2{StructE: &ts.StructE{X: "not_equal"}, X: "not_equal"},
wantEqual: true,
+ reason: "Equal method called on StructE2 pointer due to forwarded StructE pointer",
}, {
- label: label + "StructF2",
+ label: label + "/StructF2/ValueEqual",
x: ts.StructF2{StructF: &ts.StructF{X: "NotEqual"}, X: "NotEqual"},
y: ts.StructF2{StructF: &ts.StructF{X: "not_equal"}, X: "not_equal"},
wantEqual: true,
+ reason: "Equal method called on StructF2 value due to forwarded StructF pointer",
}, {
- label: label + "StructF2",
+ label: label + "/StructF2/PointerEqual",
x: &ts.StructF2{StructF: &ts.StructF{X: "NotEqual"}, X: "NotEqual"},
y: &ts.StructF2{StructF: &ts.StructF{X: "not_equal"}, X: "not_equal"},
wantEqual: true,
+ reason: "Equal method called on StructF2 pointer due to forwarded StructF pointer",
}, {
- label: label + "StructNo",
+ label: label + "/StructNo/Inequal",
x: ts.StructNo{X: "NotEqual"},
y: ts.StructNo{X: "not_equal"},
wantEqual: false,
+ reason: "Equal method not called since StructNo is not assignable to InterfaceA",
}, {
- label: label + "AssignA",
+ label: label + "/AssignA/Equal",
x: ts.AssignA(func() int { return 0 }),
y: ts.AssignA(func() int { return 1 }),
wantEqual: true,
+ reason: "Equal method called since named func is assignable to unnamed func",
}, {
- label: label + "AssignB",
+ label: label + "/AssignB/Equal",
x: ts.AssignB(struct{ A int }{0}),
y: ts.AssignB(struct{ A int }{1}),
wantEqual: true,
+ reason: "Equal method called since named struct is assignable to unnamed struct",
}, {
- label: label + "AssignC",
+ label: label + "/AssignC/Equal",
x: ts.AssignC(make(chan bool)),
y: ts.AssignC(make(chan bool)),
wantEqual: true,
+ reason: "Equal method called since named channel is assignable to unnamed channel",
}, {
- label: label + "AssignD",
+ label: label + "/AssignD/Equal",
x: ts.AssignD(make(chan bool)),
y: ts.AssignD(make(chan bool)),
wantEqual: true,
+ reason: "Equal method called since named channel is assignable to unnamed channel",
}}
}
@@ -2117,10 +2280,12 @@ func cycleTests() []test {
var tests []test
type XY struct{ x, y interface{} }
for _, tt := range []struct {
+ label string
in XY
wantEqual bool
reason string
}{{
+ label: "PointersEqual",
in: func() XY {
x := new(P)
*x = x
@@ -2129,7 +2294,9 @@ func cycleTests() []test {
return XY{x, y}
}(),
wantEqual: true,
+ reason: "equal pair of single-node pointers",
}, {
+ label: "PointersInequal",
in: func() XY {
x := new(P)
*x = x
@@ -2139,7 +2306,9 @@ func cycleTests() []test {
return XY{x, y1}
}(),
wantEqual: false,
+ reason: "inequal pair of single-node and double-node pointers",
}, {
+ label: "SlicesEqual",
in: func() XY {
x := S{nil}
x[0] = x
@@ -2148,7 +2317,9 @@ func cycleTests() []test {
return XY{x, y}
}(),
wantEqual: true,
+ reason: "equal pair of single-node slices",
}, {
+ label: "SlicesInequal",
in: func() XY {
x := S{nil}
x[0] = x
@@ -2158,7 +2329,9 @@ func cycleTests() []test {
return XY{x, y1}
}(),
wantEqual: false,
+ reason: "inequal pair of single-node and double node slices",
}, {
+ label: "MapsEqual",
in: func() XY {
x := M{0: nil}
x[0] = x
@@ -2167,7 +2340,9 @@ func cycleTests() []test {
return XY{x, y}
}(),
wantEqual: true,
+ reason: "equal pair of single-node maps",
}, {
+ label: "MapsInequal",
in: func() XY {
x := M{0: nil}
x[0] = x
@@ -2177,10 +2352,14 @@ func cycleTests() []test {
return XY{x, y1}
}(),
wantEqual: false,
+ reason: "inequal pair of single-node and double-node maps",
}, {
+ label: "GraphEqual",
in: XY{makeGraph(), makeGraph()},
wantEqual: true,
+ reason: "graphs are equal since they have identical forms",
}, {
+ label: "GraphInequalZeroed",
in: func() XY {
x := makeGraph()
y := makeGraph()
@@ -2190,7 +2369,9 @@ func cycleTests() []test {
return XY{x, y}
}(),
wantEqual: false,
+ reason: "graphs are inequal because the ID fields are different",
}, {
+ label: "GraphInequalStruct",
in: func() XY {
x := makeGraph()
y := makeGraph()
@@ -2201,9 +2382,10 @@ func cycleTests() []test {
return XY{x, y}
}(),
wantEqual: false,
+ reason: "graphs are inequal because they differ on a map element",
}} {
tests = append(tests, test{
- label: label,
+ label: label + "/" + tt.label,
x: tt.in.x,
y: tt.in.y,
wantEqual: tt.wantEqual,
@@ -2273,7 +2455,7 @@ func project1Tests() []test {
}
return []test{{
- label: label,
+ label: label + "/PanicUnexported",
x: ts.Eagle{Slaps: []ts.Slap{{
Args: &pb.MetaData{Stringer: pb.Stringer{X: "metadata"}},
}}},
@@ -2281,8 +2463,9 @@ func project1Tests() []test {
Args: &pb.MetaData{Stringer: pb.Stringer{X: "metadata"}},
}}},
wantPanic: "cannot handle unexported field",
+ reason: "struct contains unexported fields",
}, {
- label: label,
+ label: label + "/ProtoEqual",
x: ts.Eagle{Slaps: []ts.Slap{{
Args: &pb.MetaData{Stringer: pb.Stringer{X: "metadata"}},
}}},
@@ -2291,8 +2474,9 @@ func project1Tests() []test {
}}},
opts: []cmp.Option{cmp.Comparer(pb.Equal)},
wantEqual: true,
+ reason: "simulated protobuf messages contain the same values",
}, {
- label: label,
+ label: label + "/ProtoInequal",
x: ts.Eagle{Slaps: []ts.Slap{{}, {}, {}, {}, {
Args: &pb.MetaData{Stringer: pb.Stringer{X: "metadata"}},
}}},
@@ -2301,14 +2485,16 @@ func project1Tests() []test {
}}},
opts: []cmp.Option{cmp.Comparer(pb.Equal)},
wantEqual: false,
+ reason: "simulated protobuf messages contain different values",
}, {
- label: label,
+ label: label + "/Equal",
x: createEagle(),
y: createEagle(),
opts: []cmp.Option{ignoreUnexported, cmp.Comparer(pb.Equal)},
wantEqual: true,
+ reason: "equal because values are the same",
}, {
- label: label,
+ label: label + "/Inequal",
x: func() ts.Eagle {
eg := createEagle()
eg.Dreamers[1].Animal[0].(ts.Goat).Immutable.ID = "southbay2"
@@ -2324,6 +2510,7 @@ func project1Tests() []test {
}(),
opts: []cmp.Option{ignoreUnexported, cmp.Comparer(pb.Equal)},
wantEqual: false,
+ reason: "inequal because some values are different",
}}
}
@@ -2383,18 +2570,20 @@ func project2Tests() []test {
}
return []test{{
- label: label,
+ label: label + "/PanicUnexported",
x: createBatch(),
y: createBatch(),
wantPanic: "cannot handle unexported field",
+ reason: "struct contains unexported fields",
}, {
- label: label,
+ label: label + "/Equal",
x: createBatch(),
y: createBatch(),
opts: []cmp.Option{cmp.Comparer(pb.Equal), sortGerms, equalDish},
wantEqual: true,
+ reason: "equal because identical values are compared",
}, {
- label: label,
+ label: label + "/InequalOrder",
x: createBatch(),
y: func() ts.GermBatch {
gb := createBatch()
@@ -2404,8 +2593,9 @@ func project2Tests() []test {
}(),
opts: []cmp.Option{cmp.Comparer(pb.Equal), equalDish},
wantEqual: false,
+ reason: "inequal because slice contains elements in differing order",
}, {
- label: label,
+ label: label + "/EqualOrder",
x: createBatch(),
y: func() ts.GermBatch {
gb := createBatch()
@@ -2415,8 +2605,9 @@ func project2Tests() []test {
}(),
opts: []cmp.Option{cmp.Comparer(pb.Equal), sortGerms, equalDish},
wantEqual: true,
+ reason: "equal because unordered slice is sorted using transformer",
}, {
- label: label,
+ label: label + "/Inequal",
x: func() ts.GermBatch {
gb := createBatch()
delete(gb.DirtyGerms, 17)
@@ -2431,6 +2622,7 @@ func project2Tests() []test {
}(),
opts: []cmp.Option{cmp.Comparer(pb.Equal), sortGerms, equalDish},
wantEqual: false,
+ reason: "inequal because some values are different",
}}
}
@@ -2468,24 +2660,27 @@ func project3Tests() []test {
}
return []test{{
- label: label,
+ label: label + "/PanicUnexported1",
x: createDirt(),
y: createDirt(),
wantPanic: "cannot handle unexported field",
+ reason: "struct contains unexported fields",
}, {
- label: label,
+ label: label + "/PanicUnexported2",
x: createDirt(),
y: createDirt(),
opts: []cmp.Option{allowVisibility, ignoreLocker, cmp.Comparer(pb.Equal), equalTable},
wantPanic: "cannot handle unexported field",
+ reason: "struct contains references to simulated protobuf types with unexported fields",
}, {
- label: label,
+ label: label + "/Equal",
x: createDirt(),
y: createDirt(),
opts: []cmp.Option{allowVisibility, transformProtos, ignoreLocker, cmp.Comparer(pb.Equal), equalTable},
wantEqual: true,
+ reason: "transformer used to create reference to protobuf message so it works with pb.Equal",
}, {
- label: label,
+ label: label + "/Inequal",
x: func() ts.Dirt {
d := createDirt()
d.SetTable(ts.CreateMockTable([]string{"a", "c"}))
@@ -2502,6 +2697,7 @@ func project3Tests() []test {
}(),
opts: []cmp.Option{allowVisibility, transformProtos, ignoreLocker, cmp.Comparer(pb.Equal), equalTable},
wantEqual: false,
+ reason: "inequal because some values are different",
}}
}
@@ -2544,24 +2740,27 @@ func project4Tests() []test {
}
return []test{{
- label: label,
+ label: label + "/PanicUnexported1",
x: createCartel(),
y: createCartel(),
wantPanic: "cannot handle unexported field",
+ reason: "struct contains unexported fields",
}, {
- label: label,
+ label: label + "/PanicUnexported2",
x: createCartel(),
y: createCartel(),
opts: []cmp.Option{allowVisibility, cmp.Comparer(pb.Equal)},
wantPanic: "cannot handle unexported field",
+ reason: "struct contains references to simulated protobuf types with unexported fields",
}, {
- label: label,
+ label: label + "/Equal",
x: createCartel(),
y: createCartel(),
opts: []cmp.Option{allowVisibility, transformProtos, cmp.Comparer(pb.Equal)},
wantEqual: true,
+ reason: "transformer used to create reference to protobuf message so it works with pb.Equal",
}, {
- label: label,
+ label: label + "/Inequal",
x: func() ts.Cartel {
d := createCartel()
var p1, p2 ts.Poison
@@ -2581,6 +2780,7 @@ func project4Tests() []test {
}(),
opts: []cmp.Option{allowVisibility, transformProtos, cmp.Comparer(pb.Equal)},
wantEqual: false,
+ reason: "inequal because some values are different",
}}
}
diff --git a/cmp/testdata/diffs b/cmp/testdata/diffs
index c161591..baec97d 100644
--- a/cmp/testdata/diffs
+++ b/cmp/testdata/diffs
@@ -1,54 +1,54 @@
-<<< TestDiff/Comparer#09
+<<< TestDiff/Comparer/StructInequal
struct{ A int; B int; C int }{
A: 1,
B: 2,
- C: 3,
+ C: 4,
}
->>> TestDiff/Comparer#09
-<<< TestDiff/Comparer#12
+>>> TestDiff/Comparer/StructInequal
+<<< TestDiff/Comparer/PointerStructInequal
&struct{ A *int }{
- A: &4,
+ A: &5,
}
->>> TestDiff/Comparer#12
-<<< TestDiff/Comparer#16
+>>> TestDiff/Comparer/PointerStructInequal
+<<< TestDiff/Comparer/StructNestedPointerInequal
&struct{ R *bytes.Buffer }{
- R: s"",
+ R: nil,
}
->>> TestDiff/Comparer#16
-<<< TestDiff/Comparer#23
+>>> TestDiff/Comparer/StructNestedPointerInequal
+<<< TestDiff/Comparer/RegexpInequal
[]*regexp.Regexp{
nil,
- s"a*b*c*",
+ s"a*b*d*",
}
->>> TestDiff/Comparer#23
-<<< TestDiff/Comparer#25
+>>> TestDiff/Comparer/RegexpInequal
+<<< TestDiff/Comparer/TriplePointerInequal
&&&int(
- 0,
+ 1,
)
->>> TestDiff/Comparer#25
-<<< TestDiff/Comparer#28
+>>> TestDiff/Comparer/TriplePointerInequal
+<<< TestDiff/Comparer/StringerInequal
struct{ fmt.Stringer }(
- s"hello",
+ s"hello2",
)
->>> TestDiff/Comparer#28
-<<< TestDiff/Comparer#29
+>>> 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,
}
->>> TestDiff/Comparer#29
-<<< TestDiff/Comparer#30
+>>> TestDiff/Comparer/DifferingHash
+<<< TestDiff/Comparer/NilStringer
interface{}(
- &fmt.Stringer(nil),
)
->>> TestDiff/Comparer#30
-<<< TestDiff/Comparer#31
+>>> TestDiff/Comparer/NilStringer
+<<< TestDiff/Comparer/TarHeaders
[]cmp_test.tarHeader{
{
... // 4 identical fields
@@ -101,8 +101,8 @@
... // 6 identical fields
},
}
->>> TestDiff/Comparer#31
-<<< TestDiff/Comparer#36
+>>> TestDiff/Comparer/TarHeaders
+<<< TestDiff/Comparer/IrreflexiveComparison
[]int{
- Inverse(λ, float64(NaN)),
+ Inverse(λ, float64(NaN)),
@@ -125,19 +125,19 @@
- Inverse(λ, float64(NaN)),
+ Inverse(λ, float64(NaN)),
}
->>> TestDiff/Comparer#36
-<<< TestDiff/Comparer#37
+>>> TestDiff/Comparer/IrreflexiveComparison
+<<< TestDiff/Comparer/StringerMapKey
map[*testprotos.Stringer]*testprotos.Stringer(
- {s"hello": s"world"},
+ nil,
)
->>> TestDiff/Comparer#37
-<<< TestDiff/Comparer#38
+>>> TestDiff/Comparer/StringerMapKey
+<<< TestDiff/Comparer/StringerBacktick
interface{}(
- []*testprotos.Stringer{s`multi\nline\nline\nline`},
)
->>> TestDiff/Comparer#38
-<<< TestDiff/Comparer#42
+>>> TestDiff/Comparer/StringerBacktick
+<<< TestDiff/Comparer/DynamicMap
[]interface{}{
map[string]interface{}{
"avg": float64(0.278),
@@ -152,14 +152,14 @@
"name": string("Sammy Sosa"),
},
}
->>> TestDiff/Comparer#42
-<<< TestDiff/Comparer#43
+>>> TestDiff/Comparer/DynamicMap
+<<< TestDiff/Comparer/MapKeyPointer
map[*int]string{
- &⟪0xdeadf00f⟫0: "hello",
+ &⟪0xdeadf00f⟫0: "world",
}
->>> TestDiff/Comparer#43
-<<< TestDiff/Comparer#44
+>>> TestDiff/Comparer/MapKeyPointer
+<<< TestDiff/Comparer/IgnoreSliceElements
[2][]int{
{..., 1, 2, 3, ...},
{
@@ -169,8 +169,8 @@
... // 3 ignored elements
},
}
->>> TestDiff/Comparer#44
-<<< TestDiff/Comparer#45
+>>> TestDiff/Comparer/IgnoreSliceElements
+<<< TestDiff/Comparer/IgnoreMapEntries
[2]map[string]int{
{"KEEP3": 3, "keep1": 1, "keep2": 2, ...},
{
@@ -179,14 +179,14 @@
+ "keep2": 2,
},
}
->>> TestDiff/Comparer#45
-<<< TestDiff/Transformer
+>>> TestDiff/Comparer/IgnoreMapEntries
+<<< TestDiff/Transformer/Uints
uint8(Inverse(λ, uint16(Inverse(λ, uint32(Inverse(λ, uint64(
- 0,
+ 1,
)))))))
->>> TestDiff/Transformer
-<<< TestDiff/Transformer#02
+>>> TestDiff/Transformer/Uints
+<<< TestDiff/Transformer/Filtered
[]int{
Inverse(λ, int64(0)),
- Inverse(λ, int64(-5)),
@@ -195,14 +195,14 @@
- Inverse(λ, int64(-1)),
+ Inverse(λ, int64(-5)),
}
->>> TestDiff/Transformer#02
-<<< TestDiff/Transformer#03
+>>> TestDiff/Transformer/Filtered
+<<< TestDiff/Transformer/DisjointOutput
int(Inverse(λ, interface{}(
- string("zero"),
+ float64(1),
)))
->>> TestDiff/Transformer#03
-<<< TestDiff/Transformer#04
+>>> TestDiff/Transformer/DisjointOutput
+<<< TestDiff/Transformer/JSON
string(Inverse(ParseJSON, map[string]interface{}{
"address": map[string]interface{}{
- "city": string("Los Angeles"),
@@ -228,8 +228,8 @@
},
+ "spouse": nil,
}))
->>> TestDiff/Transformer#04
-<<< TestDiff/Transformer#05
+>>> TestDiff/Transformer/JSON
+<<< TestDiff/Transformer/AcyclicString
cmp_test.StringBytes{
String: Inverse(SplitString, []string{
"some",
@@ -251,7 +251,7 @@
},
})),
}
->>> TestDiff/Transformer#05
+>>> TestDiff/Transformer/AcyclicString
<<< TestDiff/Reporter/AmbiguousType
interface{}(
- "github.com/google/go-cmp/cmp/internal/teststructs/foo1".Bar{},
@@ -327,12 +327,12 @@
- s"hello": "goodbye",
}
>>> TestDiff/Reporter/NonAmbiguousStringerMapKey
-<<< TestDiff//InvalidUTF8
+<<< TestDiff/Reporter/InvalidUTF8
interface{}(
- cmp_test.MyString("\xed\xa0\x80"),
)
->>> TestDiff//InvalidUTF8
-<<< TestDiff/Reporter
+>>> TestDiff/Reporter/InvalidUTF8
+<<< TestDiff/Reporter/UnbatchedSlice
cmp_test.MyComposite{
... // 3 identical fields
BytesB: nil,
@@ -350,8 +350,8 @@
IntsC: nil,
... // 6 identical fields
}
->>> TestDiff/Reporter
-<<< TestDiff/Reporter#01
+>>> TestDiff/Reporter/UnbatchedSlice
+<<< TestDiff/Reporter/BatchedSlice
cmp_test.MyComposite{
... // 3 identical fields
BytesB: nil,
@@ -367,7 +367,7 @@
IntsC: nil,
... // 6 identical fields
}
->>> TestDiff/Reporter#01
+>>> TestDiff/Reporter/BatchedSlice
<<< TestDiff/Reporter/BatchedWithComparer
cmp_test.MyComposite{
StringA: "",
@@ -389,7 +389,7 @@
- cmp_test.MyComposite{IntsA: []int8{0, 1, 2, 3, 4, 5, 6, 7, ...}},
)
>>> TestDiff/Reporter/BatchedLong
-<<< TestDiff/Reporter#02
+<<< TestDiff/Reporter/BatchedNamedAndUnnamed
cmp_test.MyComposite{
StringA: "",
StringB: "",
@@ -442,8 +442,8 @@
+ 9.5, 8.5, 7.5,
},
}
->>> TestDiff/Reporter#02
-<<< TestDiff/Reporter#03
+>>> TestDiff/Reporter/BatchedNamedAndUnnamed
+<<< TestDiff/Reporter/BinaryHexdump
cmp_test.MyComposite{
StringA: "",
StringB: "",
@@ -464,8 +464,8 @@
BytesC: nil,
... // 9 identical fields
}
->>> TestDiff/Reporter#03
-<<< TestDiff/Reporter#04
+>>> TestDiff/Reporter/BinaryHexdump
+<<< TestDiff/Reporter/StringHexdump
cmp_test.MyComposite{
StringA: "",
StringB: cmp_test.MyString{
@@ -489,8 +489,8 @@
BytesB: nil,
... // 10 identical fields
}
->>> TestDiff/Reporter#04
-<<< TestDiff/Reporter#05
+>>> TestDiff/Reporter/StringHexdump
+<<< TestDiff/Reporter/BinaryString
cmp_test.MyComposite{
StringA: "",
StringB: "",
@@ -507,7 +507,7 @@
BytesC: nil,
... // 9 identical fields
}
->>> TestDiff/Reporter#05
+>>> TestDiff/Reporter/BinaryString
<<< TestDiff/Reporter/TripleQuote
cmp_test.MyComposite{
StringA: (
@@ -875,7 +875,7 @@
... // 12 identical and 10 modified elements
}
>>> TestDiff/Reporter/LimitMaximumSliceDiffs
-<<< TestDiff/Reporter#06
+<<< TestDiff/Reporter/MultilineString
cmp_test.MyComposite{
StringA: (
"""
@@ -902,8 +902,8 @@
BytesA: nil,
... // 11 identical fields
}
->>> TestDiff/Reporter#06
-<<< TestDiff/Reporter#07
+>>> TestDiff/Reporter/MultilineString
+<<< TestDiff/Reporter/Slices
cmp_test.MyComposite{
StringA: "",
StringB: "",
@@ -932,8 +932,8 @@
- FloatsC: cmp_test.MyFloats{7.5, 8.5, 9.5},
+ FloatsC: nil,
}
->>> TestDiff/Reporter#07
-<<< TestDiff/Reporter#08
+>>> TestDiff/Reporter/Slices
+<<< TestDiff/Reporter/EmptySlices
cmp_test.MyComposite{
StringA: "",
StringB: "",
@@ -962,8 +962,8 @@
- FloatsC: cmp_test.MyFloats{},
+ FloatsC: nil,
}
->>> TestDiff/Reporter#08
-<<< TestDiff/EmbeddedStruct/ParentStructA#04
+>>> TestDiff/Reporter/EmptySlices
+<<< TestDiff/EmbeddedStruct/ParentStructA/Inequal
teststructs.ParentStructA{
privateStruct: teststructs.privateStruct{
- Public: 1,
@@ -972,8 +972,8 @@
+ private: 3,
},
}
->>> TestDiff/EmbeddedStruct/ParentStructA#04
-<<< TestDiff/EmbeddedStruct/ParentStructB#04
+>>> TestDiff/EmbeddedStruct/ParentStructA/Inequal
+<<< TestDiff/EmbeddedStruct/ParentStructB/Inequal
teststructs.ParentStructB{
PublicStruct: teststructs.PublicStruct{
- Public: 1,
@@ -982,8 +982,8 @@
+ private: 3,
},
}
->>> TestDiff/EmbeddedStruct/ParentStructB#04
-<<< TestDiff/EmbeddedStruct/ParentStructC#04
+>>> TestDiff/EmbeddedStruct/ParentStructB/Inequal
+<<< TestDiff/EmbeddedStruct/ParentStructC/Inequal
teststructs.ParentStructC{
privateStruct: teststructs.privateStruct{
- Public: 1,
@@ -996,8 +996,8 @@
- private: 4,
+ private: 5,
}
->>> TestDiff/EmbeddedStruct/ParentStructC#04
-<<< TestDiff/EmbeddedStruct/ParentStructD#04
+>>> TestDiff/EmbeddedStruct/ParentStructC/Inequal
+<<< TestDiff/EmbeddedStruct/ParentStructD/Inequal
teststructs.ParentStructD{
PublicStruct: teststructs.PublicStruct{
- Public: 1,
@@ -1010,8 +1010,8 @@
- private: 4,
+ private: 5,
}
->>> TestDiff/EmbeddedStruct/ParentStructD#04
-<<< TestDiff/EmbeddedStruct/ParentStructE#05
+>>> TestDiff/EmbeddedStruct/ParentStructD/Inequal
+<<< TestDiff/EmbeddedStruct/ParentStructE/Inequal
teststructs.ParentStructE{
privateStruct: teststructs.privateStruct{
- Public: 1,
@@ -1026,8 +1026,8 @@
+ private: 5,
},
}
->>> TestDiff/EmbeddedStruct/ParentStructE#05
-<<< TestDiff/EmbeddedStruct/ParentStructF#05
+>>> TestDiff/EmbeddedStruct/ParentStructE/Inequal
+<<< TestDiff/EmbeddedStruct/ParentStructF/Inequal
teststructs.ParentStructF{
privateStruct: teststructs.privateStruct{
- Public: 1,
@@ -1046,8 +1046,8 @@
- private: 6,
+ private: 7,
}
->>> TestDiff/EmbeddedStruct/ParentStructF#05
-<<< TestDiff/EmbeddedStruct/ParentStructG#04
+>>> TestDiff/EmbeddedStruct/ParentStructF/Inequal
+<<< TestDiff/EmbeddedStruct/ParentStructG/Inequal
&teststructs.ParentStructG{
privateStruct: &teststructs.privateStruct{
- Public: 1,
@@ -1056,8 +1056,8 @@
+ private: 3,
},
}
->>> TestDiff/EmbeddedStruct/ParentStructG#04
-<<< TestDiff/EmbeddedStruct/ParentStructH#05
+>>> TestDiff/EmbeddedStruct/ParentStructG/Inequal
+<<< TestDiff/EmbeddedStruct/ParentStructH/Inequal
&teststructs.ParentStructH{
PublicStruct: &teststructs.PublicStruct{
- Public: 1,
@@ -1066,8 +1066,8 @@
+ private: 3,
},
}
->>> TestDiff/EmbeddedStruct/ParentStructH#05
-<<< TestDiff/EmbeddedStruct/ParentStructI#06
+>>> TestDiff/EmbeddedStruct/ParentStructH/Inequal
+<<< TestDiff/EmbeddedStruct/ParentStructI/Inequal
&teststructs.ParentStructI{
privateStruct: &teststructs.privateStruct{
- Public: 1,
@@ -1082,8 +1082,8 @@
+ private: 5,
},
}
->>> TestDiff/EmbeddedStruct/ParentStructI#06
-<<< TestDiff/EmbeddedStruct/ParentStructJ#05
+>>> TestDiff/EmbeddedStruct/ParentStructI/Inequal
+<<< TestDiff/EmbeddedStruct/ParentStructJ/Inequal
&teststructs.ParentStructJ{
privateStruct: &teststructs.privateStruct{
- Public: 1,
@@ -1110,136 +1110,136 @@
+ private: 7,
},
}
->>> TestDiff/EmbeddedStruct/ParentStructJ#05
-<<< TestDiff/EqualMethod/StructB
+>>> TestDiff/EmbeddedStruct/ParentStructJ/Inequal
+<<< TestDiff/EqualMethod/StructB/ValueInequal
teststructs.StructB{
- X: "NotEqual",
+ X: "not_equal",
}
->>> TestDiff/EqualMethod/StructB
-<<< TestDiff/EqualMethod/StructD
+>>> TestDiff/EqualMethod/StructB/ValueInequal
+<<< TestDiff/EqualMethod/StructD/ValueInequal
teststructs.StructD{
- X: "NotEqual",
+ X: "not_equal",
}
->>> TestDiff/EqualMethod/StructD
-<<< TestDiff/EqualMethod/StructE
+>>> TestDiff/EqualMethod/StructD/ValueInequal
+<<< TestDiff/EqualMethod/StructE/ValueInequal
teststructs.StructE{
- X: "NotEqual",
+ X: "not_equal",
}
->>> TestDiff/EqualMethod/StructE
-<<< TestDiff/EqualMethod/StructF
+>>> TestDiff/EqualMethod/StructE/ValueInequal
+<<< TestDiff/EqualMethod/StructF/ValueInequal
teststructs.StructF{
- X: "NotEqual",
+ X: "not_equal",
}
->>> TestDiff/EqualMethod/StructF
-<<< TestDiff/EqualMethod/StructA1#01
+>>> TestDiff/EqualMethod/StructF/ValueInequal
+<<< TestDiff/EqualMethod/StructA1/ValueInequal
teststructs.StructA1{
StructA: {X: "NotEqual"},
- X: "NotEqual",
+ X: "not_equal",
}
->>> TestDiff/EqualMethod/StructA1#01
-<<< TestDiff/EqualMethod/StructA1#03
+>>> TestDiff/EqualMethod/StructA1/ValueInequal
+<<< TestDiff/EqualMethod/StructA1/PointerInequal
&teststructs.StructA1{
StructA: {X: "NotEqual"},
- X: "NotEqual",
+ X: "not_equal",
}
->>> TestDiff/EqualMethod/StructA1#03
-<<< TestDiff/EqualMethod/StructB1#01
+>>> TestDiff/EqualMethod/StructA1/PointerInequal
+<<< TestDiff/EqualMethod/StructB1/ValueInequal
teststructs.StructB1{
- StructB: Inverse(Ref, &teststructs.StructB{X: "NotEqual"}),
+ StructB: Inverse(Addr, &teststructs.StructB{X: "NotEqual"}),
- X: "NotEqual",
+ X: "not_equal",
}
->>> TestDiff/EqualMethod/StructB1#01
-<<< TestDiff/EqualMethod/StructB1#03
+>>> TestDiff/EqualMethod/StructB1/ValueInequal
+<<< TestDiff/EqualMethod/StructB1/PointerInequal
&teststructs.StructB1{
- StructB: Inverse(Ref, &teststructs.StructB{X: "NotEqual"}),
+ StructB: Inverse(Addr, &teststructs.StructB{X: "NotEqual"}),
- X: "NotEqual",
+ X: "not_equal",
}
->>> TestDiff/EqualMethod/StructB1#03
-<<< TestDiff/EqualMethod/StructD1
+>>> TestDiff/EqualMethod/StructB1/PointerInequal
+<<< TestDiff/EqualMethod/StructD1/ValueInequal
teststructs.StructD1{
- StructD: teststructs.StructD{X: "NotEqual"},
+ StructD: teststructs.StructD{X: "not_equal"},
- X: "NotEqual",
+ X: "not_equal",
}
->>> TestDiff/EqualMethod/StructD1
-<<< TestDiff/EqualMethod/StructE1
+>>> TestDiff/EqualMethod/StructD1/ValueInequal
+<<< TestDiff/EqualMethod/StructE1/ValueInequal
teststructs.StructE1{
- StructE: teststructs.StructE{X: "NotEqual"},
+ StructE: teststructs.StructE{X: "not_equal"},
- X: "NotEqual",
+ X: "not_equal",
}
->>> TestDiff/EqualMethod/StructE1
-<<< TestDiff/EqualMethod/StructF1
+>>> TestDiff/EqualMethod/StructE1/ValueInequal
+<<< TestDiff/EqualMethod/StructF1/ValueInequal
teststructs.StructF1{
- StructF: teststructs.StructF{X: "NotEqual"},
+ StructF: teststructs.StructF{X: "not_equal"},
- X: "NotEqual",
+ X: "not_equal",
}
->>> TestDiff/EqualMethod/StructF1
-<<< TestDiff/EqualMethod/StructA2#01
+>>> TestDiff/EqualMethod/StructF1/ValueInequal
+<<< TestDiff/EqualMethod/StructA2/ValueInequal
teststructs.StructA2{
StructA: &{X: "NotEqual"},
- X: "NotEqual",
+ X: "not_equal",
}
->>> TestDiff/EqualMethod/StructA2#01
-<<< TestDiff/EqualMethod/StructA2#03
+>>> TestDiff/EqualMethod/StructA2/ValueInequal
+<<< TestDiff/EqualMethod/StructA2/PointerInequal
&teststructs.StructA2{
StructA: &{X: "NotEqual"},
- X: "NotEqual",
+ X: "not_equal",
}
->>> TestDiff/EqualMethod/StructA2#03
-<<< TestDiff/EqualMethod/StructB2#01
+>>> TestDiff/EqualMethod/StructA2/PointerInequal
+<<< TestDiff/EqualMethod/StructB2/ValueInequal
teststructs.StructB2{
StructB: &{X: "NotEqual"},
- X: "NotEqual",
+ X: "not_equal",
}
->>> TestDiff/EqualMethod/StructB2#01
-<<< TestDiff/EqualMethod/StructB2#03
+>>> TestDiff/EqualMethod/StructB2/ValueInequal
+<<< TestDiff/EqualMethod/StructB2/PointerInequal
&teststructs.StructB2{
StructB: &{X: "NotEqual"},
- X: "NotEqual",
+ X: "not_equal",
}
->>> TestDiff/EqualMethod/StructB2#03
-<<< TestDiff/EqualMethod/StructNo
+>>> TestDiff/EqualMethod/StructB2/PointerInequal
+<<< TestDiff/EqualMethod/StructNo/Inequal
teststructs.StructNo{
- X: "NotEqual",
+ X: "not_equal",
}
->>> TestDiff/EqualMethod/StructNo
-<<< TestDiff/Cycle#01
+>>> TestDiff/EqualMethod/StructNo/Inequal
+<<< TestDiff/Cycle/PointersInequal
&&cmp_test.P(
- &⟪0xdeadf00f⟫,
+ &&⟪0xdeadf00f⟫,
)
->>> TestDiff/Cycle#01
-<<< TestDiff/Cycle#03
+>>> TestDiff/Cycle/PointersInequal
+<<< TestDiff/Cycle/SlicesInequal
cmp_test.S{
- {{{*(*cmp_test.S)(⟪0xdeadf00f⟫)}}},
+ {{{{*(*cmp_test.S)(⟪0xdeadf00f⟫)}}}},
}
->>> TestDiff/Cycle#03
-<<< TestDiff/Cycle#05
+>>> TestDiff/Cycle/SlicesInequal
+<<< TestDiff/Cycle/MapsInequal
cmp_test.M{
- 0: {0: ⟪0xdeadf00f⟫},
+ 0: {0: {0: ⟪0xdeadf00f⟫}},
}
->>> TestDiff/Cycle#05
-<<< TestDiff/Cycle#07
+>>> TestDiff/Cycle/MapsInequal
+<<< TestDiff/Cycle/GraphInequalZeroed
map[string]*cmp_test.CycleAlpha{
"Bar": &{
Name: "Bar",
@@ -1352,8 +1352,8 @@
},
},
}
->>> TestDiff/Cycle#07
-<<< TestDiff/Cycle#08
+>>> TestDiff/Cycle/GraphInequalZeroed
+<<< TestDiff/Cycle/GraphInequalStruct
map[string]*cmp_test.CycleAlpha{
"Bar": &{
Name: "Bar",
@@ -1437,8 +1437,8 @@
},
"Foo": &{Name: "Foo", Bravos: {"FooBravo": &{ID: 101, Name: "FooBravo", Mods: 100, Alphas: {"Foo": &{Name: "Foo", Bravos: {...}}}}}},
}
->>> TestDiff/Cycle#08
-<<< TestDiff/Project1#02
+>>> TestDiff/Cycle/GraphInequalStruct
+<<< TestDiff/Project1/ProtoInequal
teststructs.Eagle{
... // 4 identical fields
Dreamers: nil,
@@ -1462,8 +1462,8 @@
PrankRating: "",
... // 2 identical fields
}
->>> TestDiff/Project1#02
-<<< TestDiff/Project1#04
+>>> TestDiff/Project1/ProtoInequal
+<<< TestDiff/Project1/Inequal
teststructs.Eagle{
... // 2 identical fields
Desc: "some description",
@@ -1535,8 +1535,8 @@
PrankRating: "",
... // 2 identical fields
}
->>> TestDiff/Project1#04
-<<< TestDiff/Project2#02
+>>> TestDiff/Project1/Inequal
+<<< TestDiff/Project2/InequalOrder
teststructs.GermBatch{
DirtyGerms: map[int32][]*testprotos.Germ{
17: {s"germ1"},
@@ -1551,8 +1551,8 @@
GermMap: {13: s"germ13", 21: s"germ21"},
... // 7 identical fields
}
->>> TestDiff/Project2#02
-<<< TestDiff/Project2#04
+>>> TestDiff/Project2/InequalOrder
+<<< TestDiff/Project2/Inequal
teststructs.GermBatch{
DirtyGerms: map[int32][]*testprotos.Germ{
+ 17: {s"germ1"},
@@ -1578,8 +1578,8 @@
TotalDirtyGerms: 0,
InfectedAt: s"2009-11-10 23:00:00 +0000 UTC",
}
->>> TestDiff/Project2#04
-<<< TestDiff/Project3#03
+>>> TestDiff/Project2/Inequal
+<<< TestDiff/Project3/Inequal
teststructs.Dirt{
- table: &teststructs.MockTable{state: []string{"a", "c"}},
+ table: &teststructs.MockTable{state: []string{"a", "b", "c"}},
@@ -1597,8 +1597,8 @@
lastTime: 54321,
... // 1 ignored field
}
->>> TestDiff/Project3#03
-<<< TestDiff/Project4#03
+>>> TestDiff/Project3/Inequal
+<<< TestDiff/Project4/Inequal
teststructs.Cartel{
Headquarter: teststructs.Headquarter{
id: 5,
@@ -1639,4 +1639,4 @@
- &{poisonType: 2, manufacturer: "acme2"},
},
}
->>> TestDiff/Project4#03
+>>> TestDiff/Project4/Inequal