mirror of
https://github.com/protocolbuffers/protobuf-go.git
synced 2025-01-17 01:12:51 +00:00
d025c95110
The proto package tests often test several variations of messages with a similar shape. For example, most tests are performed with a proto2 message with a regular field, a proto2 message with an extension field, and a proto3 message. Add a protobuild package which can initialize all these variations from a single template. For example, these three messages: &testpb.TestAllTypes{OptionalInt32: proto.Int32(1)} &test3pb.TestAllTypes{OptionalInt32: 1} m := &testpb.TestAllExtensions{} proto.SetExtension(m, &testpb.E_OptionalInt32, 1) can all be constructed from the template: protobuild.Message{"optional_int32": 1} This reduces redundancy in tests and will make it more practical to test alternative code generators. Change-Id: I3245a4bf74ee1bce957bc772fed513d427720677 Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/217457 Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
576 lines
21 KiB
Go
576 lines
21 KiB
Go
// 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.
|
|
|
|
package protocmp
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
|
|
"google.golang.org/protobuf/internal/encoding/pack"
|
|
testpb "google.golang.org/protobuf/internal/testprotos/test"
|
|
"google.golang.org/protobuf/proto"
|
|
"google.golang.org/protobuf/reflect/protoreflect"
|
|
"google.golang.org/protobuf/types/dynamicpb"
|
|
)
|
|
|
|
func TestEqual(t *testing.T) {
|
|
type test struct {
|
|
x, y interface{}
|
|
opts cmp.Options
|
|
want bool
|
|
}
|
|
var tests []test
|
|
|
|
allTypesDesc := (*testpb.TestAllTypes)(nil).ProtoReflect().Descriptor()
|
|
|
|
// Test nil and empty messages of differing types.
|
|
tests = append(tests, []test{{
|
|
x: (*testpb.TestAllTypes)(nil),
|
|
y: (*testpb.TestAllTypes)(nil),
|
|
opts: cmp.Options{Transform()},
|
|
want: true,
|
|
}, {
|
|
x: (*testpb.TestAllTypes)(nil),
|
|
y: new(testpb.TestAllTypes),
|
|
opts: cmp.Options{Transform()},
|
|
want: false,
|
|
}, {
|
|
x: (*testpb.TestAllTypes)(nil),
|
|
y: dynamicpb.NewMessage(allTypesDesc),
|
|
opts: cmp.Options{Transform()},
|
|
want: false,
|
|
}, {
|
|
x: (*testpb.TestAllTypes)(nil),
|
|
y: new(testpb.TestAllTypes),
|
|
opts: cmp.Options{Transform(), IgnoreEmptyMessages()},
|
|
want: true,
|
|
}, {
|
|
x: (*testpb.TestAllTypes)(nil),
|
|
y: dynamicpb.NewMessage(allTypesDesc),
|
|
opts: cmp.Options{Transform(), IgnoreEmptyMessages()},
|
|
want: true,
|
|
}, {
|
|
x: new(testpb.TestAllTypes),
|
|
y: new(testpb.TestAllTypes),
|
|
opts: cmp.Options{Transform()},
|
|
want: true,
|
|
}, {
|
|
x: new(testpb.TestAllTypes),
|
|
y: dynamicpb.NewMessage(allTypesDesc),
|
|
opts: cmp.Options{Transform()},
|
|
want: true,
|
|
}, {
|
|
x: new(testpb.TestAllTypes),
|
|
y: new(testpb.TestAllExtensions),
|
|
opts: cmp.Options{Transform()},
|
|
want: false,
|
|
}, {
|
|
x: struct{ I interface{} }{(*testpb.TestAllTypes)(nil)},
|
|
y: struct{ I interface{} }{(*testpb.TestAllTypes)(nil)},
|
|
opts: cmp.Options{Transform()},
|
|
want: true,
|
|
}, {
|
|
x: struct{ I interface{} }{(*testpb.TestAllTypes)(nil)},
|
|
y: struct{ I interface{} }{new(testpb.TestAllTypes)},
|
|
opts: cmp.Options{Transform()},
|
|
want: false,
|
|
}, {
|
|
x: struct{ I interface{} }{(*testpb.TestAllTypes)(nil)},
|
|
y: struct{ I interface{} }{dynamicpb.NewMessage(allTypesDesc)},
|
|
opts: cmp.Options{Transform()},
|
|
want: false,
|
|
}, {
|
|
x: struct{ I interface{} }{(*testpb.TestAllTypes)(nil)},
|
|
y: struct{ I interface{} }{new(testpb.TestAllTypes)},
|
|
opts: cmp.Options{Transform(), IgnoreEmptyMessages()},
|
|
want: true,
|
|
}, {
|
|
x: struct{ I interface{} }{(*testpb.TestAllTypes)(nil)},
|
|
y: struct{ I interface{} }{dynamicpb.NewMessage(allTypesDesc)},
|
|
opts: cmp.Options{Transform(), IgnoreEmptyMessages()},
|
|
want: true,
|
|
}, {
|
|
x: struct{ I interface{} }{new(testpb.TestAllTypes)},
|
|
y: struct{ I interface{} }{new(testpb.TestAllTypes)},
|
|
opts: cmp.Options{Transform()},
|
|
want: true,
|
|
}, {
|
|
x: struct{ I interface{} }{new(testpb.TestAllTypes)},
|
|
y: struct{ I interface{} }{dynamicpb.NewMessage(allTypesDesc)},
|
|
opts: cmp.Options{Transform()},
|
|
want: true,
|
|
}, {
|
|
x: struct{ M proto.Message }{(*testpb.TestAllTypes)(nil)},
|
|
y: struct{ M proto.Message }{(*testpb.TestAllTypes)(nil)},
|
|
opts: cmp.Options{Transform()},
|
|
want: true,
|
|
}, {
|
|
x: struct{ M proto.Message }{(*testpb.TestAllTypes)(nil)},
|
|
y: struct{ M proto.Message }{new(testpb.TestAllTypes)},
|
|
opts: cmp.Options{Transform()},
|
|
want: false,
|
|
}, {
|
|
x: struct{ M proto.Message }{(*testpb.TestAllTypes)(nil)},
|
|
y: struct{ M proto.Message }{dynamicpb.NewMessage(allTypesDesc)},
|
|
opts: cmp.Options{Transform()},
|
|
want: false,
|
|
}, {
|
|
x: struct{ M proto.Message }{(*testpb.TestAllTypes)(nil)},
|
|
y: struct{ M proto.Message }{new(testpb.TestAllTypes)},
|
|
opts: cmp.Options{Transform(), IgnoreEmptyMessages()},
|
|
want: true,
|
|
}, {
|
|
x: struct{ M proto.Message }{(*testpb.TestAllTypes)(nil)},
|
|
y: struct{ M proto.Message }{dynamicpb.NewMessage(allTypesDesc)},
|
|
opts: cmp.Options{Transform(), IgnoreEmptyMessages()},
|
|
want: true,
|
|
}, {
|
|
x: struct{ M proto.Message }{new(testpb.TestAllTypes)},
|
|
y: struct{ M proto.Message }{new(testpb.TestAllTypes)},
|
|
opts: cmp.Options{Transform()},
|
|
want: true,
|
|
}, {
|
|
x: struct{ M proto.Message }{new(testpb.TestAllTypes)},
|
|
y: struct{ M proto.Message }{dynamicpb.NewMessage(allTypesDesc)},
|
|
opts: cmp.Options{Transform()},
|
|
want: true,
|
|
}}...)
|
|
|
|
// Test IgnoreUnknown.
|
|
raw := pack.Message{
|
|
pack.Tag{1, pack.BytesType}, pack.String("Hello, goodbye!"),
|
|
}.Marshal()
|
|
tests = append(tests, []test{{
|
|
x: apply(&testpb.TestAllTypes{OptionalSint64: proto.Int64(5)}, setUnknown{raw}),
|
|
y: &testpb.TestAllTypes{OptionalSint64: proto.Int64(5)},
|
|
opts: cmp.Options{Transform()},
|
|
want: false,
|
|
}, {
|
|
x: apply(&testpb.TestAllTypes{OptionalSint64: proto.Int64(5)}, setUnknown{raw}),
|
|
y: &testpb.TestAllTypes{OptionalSint64: proto.Int64(5)},
|
|
opts: cmp.Options{Transform(), IgnoreUnknown()},
|
|
want: true,
|
|
}, {
|
|
x: apply(&testpb.TestAllTypes{OptionalSint64: proto.Int64(5)}, setUnknown{raw}),
|
|
y: &testpb.TestAllTypes{OptionalSint64: proto.Int64(6)},
|
|
opts: cmp.Options{Transform(), IgnoreUnknown()},
|
|
want: false,
|
|
}, {
|
|
x: apply(&testpb.TestAllTypes{OptionalSint64: proto.Int64(5)}, setUnknown{raw}),
|
|
y: apply(dynamicpb.NewMessage(allTypesDesc), setField{6, int64(5)}),
|
|
opts: cmp.Options{Transform()},
|
|
want: false,
|
|
}, {
|
|
x: apply(&testpb.TestAllTypes{OptionalSint64: proto.Int64(5)}, setUnknown{raw}),
|
|
y: apply(dynamicpb.NewMessage(allTypesDesc), setField{6, int64(5)}),
|
|
opts: cmp.Options{Transform(), IgnoreUnknown()},
|
|
want: true,
|
|
}}...)
|
|
|
|
// Test IgnoreDefaultScalars.
|
|
tests = append(tests, []test{{
|
|
x: &testpb.TestAllTypes{
|
|
DefaultInt32: proto.Int32(81),
|
|
DefaultUint32: proto.Uint32(83),
|
|
DefaultFloat: proto.Float32(91.5),
|
|
DefaultBool: proto.Bool(true),
|
|
DefaultBytes: []byte("world"),
|
|
},
|
|
y: &testpb.TestAllTypes{
|
|
DefaultInt64: proto.Int64(82),
|
|
DefaultUint64: proto.Uint64(84),
|
|
DefaultDouble: proto.Float64(92e3),
|
|
DefaultString: proto.String("hello"),
|
|
DefaultForeignEnum: testpb.ForeignEnum_FOREIGN_BAR.Enum(),
|
|
},
|
|
opts: cmp.Options{Transform()},
|
|
want: false,
|
|
}, {
|
|
x: &testpb.TestAllTypes{
|
|
DefaultInt32: proto.Int32(81),
|
|
DefaultUint32: proto.Uint32(83),
|
|
DefaultFloat: proto.Float32(91.5),
|
|
DefaultBool: proto.Bool(true),
|
|
DefaultBytes: []byte("world"),
|
|
},
|
|
y: &testpb.TestAllTypes{
|
|
DefaultInt64: proto.Int64(82),
|
|
DefaultUint64: proto.Uint64(84),
|
|
DefaultDouble: proto.Float64(92e3),
|
|
DefaultString: proto.String("hello"),
|
|
DefaultForeignEnum: testpb.ForeignEnum_FOREIGN_BAR.Enum(),
|
|
},
|
|
opts: cmp.Options{Transform(), IgnoreDefaultScalars()},
|
|
want: true,
|
|
}, {
|
|
x: &testpb.TestAllTypes{
|
|
OptionalInt32: proto.Int32(81),
|
|
OptionalUint32: proto.Uint32(83),
|
|
OptionalFloat: proto.Float32(91.5),
|
|
OptionalBool: proto.Bool(true),
|
|
OptionalBytes: []byte("world"),
|
|
},
|
|
y: &testpb.TestAllTypes{
|
|
OptionalInt64: proto.Int64(82),
|
|
OptionalUint64: proto.Uint64(84),
|
|
OptionalDouble: proto.Float64(92e3),
|
|
OptionalString: proto.String("hello"),
|
|
OptionalForeignEnum: testpb.ForeignEnum_FOREIGN_BAR.Enum(),
|
|
},
|
|
opts: cmp.Options{Transform(), IgnoreDefaultScalars()},
|
|
want: false,
|
|
}, {
|
|
x: &testpb.TestAllTypes{
|
|
OptionalInt32: proto.Int32(0),
|
|
OptionalUint32: proto.Uint32(0),
|
|
OptionalFloat: proto.Float32(0),
|
|
OptionalBool: proto.Bool(false),
|
|
OptionalBytes: []byte(""),
|
|
},
|
|
y: &testpb.TestAllTypes{
|
|
OptionalInt64: proto.Int64(0),
|
|
OptionalUint64: proto.Uint64(0),
|
|
OptionalDouble: proto.Float64(0),
|
|
OptionalString: proto.String(""),
|
|
OptionalForeignEnum: testpb.ForeignEnum_FOREIGN_FOO.Enum(),
|
|
},
|
|
opts: cmp.Options{Transform(), IgnoreDefaultScalars()},
|
|
want: true,
|
|
}, {
|
|
x: apply(new(testpb.TestAllExtensions),
|
|
setExtension{testpb.E_DefaultInt32, int32(81)},
|
|
setExtension{testpb.E_DefaultUint32, uint32(83)},
|
|
setExtension{testpb.E_DefaultFloat, float32(91.5)},
|
|
setExtension{testpb.E_DefaultBool, bool(true)},
|
|
setExtension{testpb.E_DefaultBytes, []byte("world")}),
|
|
y: apply(new(testpb.TestAllExtensions),
|
|
setExtension{testpb.E_DefaultInt64, int64(82)},
|
|
setExtension{testpb.E_DefaultUint64, uint64(84)},
|
|
setExtension{testpb.E_DefaultDouble, float64(92e3)},
|
|
setExtension{testpb.E_DefaultString, string("hello")}),
|
|
opts: cmp.Options{Transform()},
|
|
want: false,
|
|
}, {
|
|
x: apply(new(testpb.TestAllExtensions),
|
|
setExtension{testpb.E_DefaultInt32, int32(81)},
|
|
setExtension{testpb.E_DefaultUint32, uint32(83)},
|
|
setExtension{testpb.E_DefaultFloat, float32(91.5)},
|
|
setExtension{testpb.E_DefaultBool, bool(true)},
|
|
setExtension{testpb.E_DefaultBytes, []byte("world")}),
|
|
y: apply(new(testpb.TestAllExtensions),
|
|
setExtension{testpb.E_DefaultInt64, int64(82)},
|
|
setExtension{testpb.E_DefaultUint64, uint64(84)},
|
|
setExtension{testpb.E_DefaultDouble, float64(92e3)},
|
|
setExtension{testpb.E_DefaultString, string("hello")}),
|
|
opts: cmp.Options{Transform(), IgnoreDefaultScalars()},
|
|
want: true,
|
|
}, {
|
|
x: apply(new(testpb.TestAllExtensions),
|
|
setExtension{testpb.E_OptionalInt32, int32(0)},
|
|
setExtension{testpb.E_OptionalUint32, uint32(0)},
|
|
setExtension{testpb.E_OptionalFloat, float32(0)},
|
|
setExtension{testpb.E_OptionalBool, bool(false)},
|
|
setExtension{testpb.E_OptionalBytes, []byte("")}),
|
|
y: apply(new(testpb.TestAllExtensions),
|
|
setExtension{testpb.E_OptionalInt64, int64(0)},
|
|
setExtension{testpb.E_OptionalUint64, uint64(0)},
|
|
setExtension{testpb.E_OptionalDouble, float64(0)},
|
|
setExtension{testpb.E_OptionalString, string("")}),
|
|
opts: cmp.Options{Transform()},
|
|
want: false,
|
|
}, {
|
|
x: apply(new(testpb.TestAllExtensions),
|
|
setExtension{testpb.E_OptionalInt32, int32(0)},
|
|
setExtension{testpb.E_OptionalUint32, uint32(0)},
|
|
setExtension{testpb.E_OptionalFloat, float32(0)},
|
|
setExtension{testpb.E_OptionalBool, bool(false)},
|
|
setExtension{testpb.E_OptionalBytes, []byte("")}),
|
|
y: apply(new(testpb.TestAllExtensions),
|
|
setExtension{testpb.E_OptionalInt64, int64(0)},
|
|
setExtension{testpb.E_OptionalUint64, uint64(0)},
|
|
setExtension{testpb.E_OptionalDouble, float64(0)},
|
|
setExtension{testpb.E_OptionalString, string("")}),
|
|
opts: cmp.Options{Transform(), IgnoreDefaultScalars()},
|
|
want: true,
|
|
}, {
|
|
x: &testpb.TestAllTypes{
|
|
DefaultFloat: proto.Float32(91.6),
|
|
},
|
|
y: &testpb.TestAllTypes{},
|
|
opts: cmp.Options{Transform(), IgnoreDefaultScalars()},
|
|
want: false,
|
|
}, {
|
|
x: &testpb.TestAllTypes{
|
|
OptionalForeignMessage: &testpb.ForeignMessage{},
|
|
},
|
|
y: &testpb.TestAllTypes{},
|
|
opts: cmp.Options{Transform(), IgnoreDefaultScalars()},
|
|
want: false,
|
|
}}...)
|
|
|
|
// Test IgnoreEmptyMessages.
|
|
tests = append(tests, []test{{
|
|
x: []*testpb.TestAllTypes{nil, {}, {OptionalInt32: proto.Int32(5)}},
|
|
y: []*testpb.TestAllTypes{nil, {}, {OptionalInt32: proto.Int32(5)}},
|
|
opts: cmp.Options{Transform()},
|
|
want: true,
|
|
}, {
|
|
x: []*testpb.TestAllTypes{nil, {}, {OptionalInt32: proto.Int32(5)}},
|
|
y: []*testpb.TestAllTypes{{OptionalInt32: proto.Int32(5)}},
|
|
opts: cmp.Options{Transform(), IgnoreEmptyMessages()},
|
|
want: false,
|
|
}, {
|
|
x: &testpb.TestAllTypes{OptionalForeignMessage: &testpb.ForeignMessage{}},
|
|
y: &testpb.TestAllTypes{OptionalForeignMessage: nil},
|
|
opts: cmp.Options{Transform()},
|
|
want: false,
|
|
}, {
|
|
x: &testpb.TestAllTypes{OptionalForeignMessage: &testpb.ForeignMessage{}},
|
|
y: &testpb.TestAllTypes{OptionalForeignMessage: nil},
|
|
opts: cmp.Options{Transform(), IgnoreEmptyMessages()},
|
|
want: true,
|
|
}, {
|
|
x: &testpb.TestAllTypes{OptionalForeignMessage: &testpb.ForeignMessage{C: proto.Int32(5)}},
|
|
y: &testpb.TestAllTypes{OptionalForeignMessage: nil},
|
|
opts: cmp.Options{Transform(), IgnoreEmptyMessages()},
|
|
want: false,
|
|
}, {
|
|
x: &testpb.TestAllTypes{RepeatedForeignMessage: []*testpb.ForeignMessage{}},
|
|
y: &testpb.TestAllTypes{RepeatedForeignMessage: nil},
|
|
opts: cmp.Options{Transform()},
|
|
want: true,
|
|
}, {
|
|
x: &testpb.TestAllTypes{RepeatedForeignMessage: []*testpb.ForeignMessage{nil, {}}},
|
|
y: &testpb.TestAllTypes{RepeatedForeignMessage: nil},
|
|
opts: cmp.Options{Transform()},
|
|
want: false,
|
|
}, {
|
|
x: &testpb.TestAllTypes{RepeatedForeignMessage: []*testpb.ForeignMessage{nil, {}}},
|
|
y: &testpb.TestAllTypes{RepeatedForeignMessage: nil},
|
|
opts: cmp.Options{Transform(), IgnoreEmptyMessages()},
|
|
want: true,
|
|
}, {
|
|
x: &testpb.TestAllTypes{RepeatedForeignMessage: []*testpb.ForeignMessage{nil, {C: proto.Int32(5)}, {}}},
|
|
y: &testpb.TestAllTypes{RepeatedForeignMessage: nil},
|
|
opts: cmp.Options{Transform(), IgnoreEmptyMessages()},
|
|
want: false,
|
|
}, {
|
|
x: &testpb.TestAllTypes{RepeatedForeignMessage: []*testpb.ForeignMessage{nil, {C: proto.Int32(5)}, {}}},
|
|
y: &testpb.TestAllTypes{RepeatedForeignMessage: []*testpb.ForeignMessage{{}, {}, nil, {}, {C: proto.Int32(5)}, {}}},
|
|
opts: cmp.Options{Transform()},
|
|
want: false,
|
|
}, {
|
|
x: &testpb.TestAllTypes{RepeatedForeignMessage: []*testpb.ForeignMessage{nil, {C: proto.Int32(5)}, {}}},
|
|
y: &testpb.TestAllTypes{RepeatedForeignMessage: []*testpb.ForeignMessage{{}, {}, nil, {}, {C: proto.Int32(5)}, {}}},
|
|
opts: cmp.Options{Transform(), IgnoreEmptyMessages()},
|
|
want: true,
|
|
|
|
// TODO
|
|
}, {
|
|
x: &testpb.TestAllTypes{MapStringNestedMessage: map[string]*testpb.TestAllTypes_NestedMessage{}},
|
|
y: &testpb.TestAllTypes{MapStringNestedMessage: nil},
|
|
opts: cmp.Options{Transform()},
|
|
want: true,
|
|
}, {
|
|
x: &testpb.TestAllTypes{MapStringNestedMessage: map[string]*testpb.TestAllTypes_NestedMessage{"1": nil, "2": {}}},
|
|
y: &testpb.TestAllTypes{MapStringNestedMessage: nil},
|
|
opts: cmp.Options{Transform()},
|
|
want: false,
|
|
}, {
|
|
x: &testpb.TestAllTypes{MapStringNestedMessage: map[string]*testpb.TestAllTypes_NestedMessage{"1": nil, "2": {}}},
|
|
y: &testpb.TestAllTypes{MapStringNestedMessage: nil},
|
|
opts: cmp.Options{Transform(), IgnoreEmptyMessages()},
|
|
want: true,
|
|
}, {
|
|
x: &testpb.TestAllTypes{MapStringNestedMessage: map[string]*testpb.TestAllTypes_NestedMessage{"1": nil, "2": {A: proto.Int32(5)}, "3": {}}},
|
|
y: &testpb.TestAllTypes{MapStringNestedMessage: nil},
|
|
opts: cmp.Options{Transform(), IgnoreEmptyMessages()},
|
|
want: false,
|
|
}, {
|
|
x: &testpb.TestAllTypes{MapStringNestedMessage: map[string]*testpb.TestAllTypes_NestedMessage{"1": nil, "2": {A: proto.Int32(5)}, "3": {}}},
|
|
y: &testpb.TestAllTypes{MapStringNestedMessage: map[string]*testpb.TestAllTypes_NestedMessage{"1": {}, "1a": {}, "1b": nil, "2": {A: proto.Int32(5)}, "4": {}}},
|
|
opts: cmp.Options{Transform()},
|
|
want: false,
|
|
}, {
|
|
x: &testpb.TestAllTypes{MapStringNestedMessage: map[string]*testpb.TestAllTypes_NestedMessage{"1": nil, "2": {A: proto.Int32(5)}, "3": {}}},
|
|
y: &testpb.TestAllTypes{MapStringNestedMessage: map[string]*testpb.TestAllTypes_NestedMessage{"1": {}, "1a": {}, "1b": nil, "2": {A: proto.Int32(5)}, "4": {}}},
|
|
opts: cmp.Options{Transform(), IgnoreEmptyMessages()},
|
|
want: true,
|
|
}}...)
|
|
|
|
// Test IgnoreEnums and IgnoreMessages.
|
|
tests = append(tests, []test{{
|
|
x: &testpb.TestAllTypes{
|
|
OptionalNestedMessage: &testpb.TestAllTypes_NestedMessage{A: proto.Int32(1)},
|
|
RepeatedNestedMessage: []*testpb.TestAllTypes_NestedMessage{{A: proto.Int32(2)}},
|
|
MapStringNestedMessage: map[string]*testpb.TestAllTypes_NestedMessage{"3": {A: proto.Int32(3)}},
|
|
},
|
|
y: &testpb.TestAllTypes{},
|
|
opts: cmp.Options{Transform()},
|
|
want: false,
|
|
}, {
|
|
x: &testpb.TestAllTypes{
|
|
OptionalNestedMessage: &testpb.TestAllTypes_NestedMessage{A: proto.Int32(1)},
|
|
RepeatedNestedMessage: []*testpb.TestAllTypes_NestedMessage{{A: proto.Int32(2)}},
|
|
MapStringNestedMessage: map[string]*testpb.TestAllTypes_NestedMessage{"3": {A: proto.Int32(3)}},
|
|
},
|
|
y: &testpb.TestAllTypes{},
|
|
opts: cmp.Options{Transform(), IgnoreMessages(&testpb.TestAllTypes{})},
|
|
want: true,
|
|
}, {
|
|
x: &testpb.TestAllTypes{
|
|
OptionalNestedEnum: testpb.TestAllTypes_FOO.Enum(),
|
|
RepeatedNestedEnum: []testpb.TestAllTypes_NestedEnum{testpb.TestAllTypes_BAR},
|
|
MapStringNestedEnum: map[string]testpb.TestAllTypes_NestedEnum{"baz": testpb.TestAllTypes_BAZ},
|
|
},
|
|
y: &testpb.TestAllTypes{},
|
|
opts: cmp.Options{Transform()},
|
|
want: false,
|
|
}, {
|
|
x: &testpb.TestAllTypes{
|
|
OptionalNestedEnum: testpb.TestAllTypes_FOO.Enum(),
|
|
RepeatedNestedEnum: []testpb.TestAllTypes_NestedEnum{testpb.TestAllTypes_BAR},
|
|
MapStringNestedEnum: map[string]testpb.TestAllTypes_NestedEnum{"baz": testpb.TestAllTypes_BAZ},
|
|
},
|
|
y: &testpb.TestAllTypes{},
|
|
opts: cmp.Options{Transform(), IgnoreEnums(testpb.TestAllTypes_NestedEnum(0))},
|
|
want: true,
|
|
}, {
|
|
x: &testpb.TestAllTypes{
|
|
OptionalNestedEnum: testpb.TestAllTypes_FOO.Enum(),
|
|
RepeatedNestedEnum: []testpb.TestAllTypes_NestedEnum{testpb.TestAllTypes_BAR},
|
|
MapStringNestedEnum: map[string]testpb.TestAllTypes_NestedEnum{"baz": testpb.TestAllTypes_BAZ},
|
|
|
|
OptionalNestedMessage: &testpb.TestAllTypes_NestedMessage{A: proto.Int32(1)},
|
|
RepeatedNestedMessage: []*testpb.TestAllTypes_NestedMessage{{A: proto.Int32(2)}},
|
|
MapStringNestedMessage: map[string]*testpb.TestAllTypes_NestedMessage{"3": {A: proto.Int32(3)}},
|
|
},
|
|
y: &testpb.TestAllTypes{},
|
|
opts: cmp.Options{Transform(),
|
|
IgnoreMessages(&testpb.TestAllExtensions{}),
|
|
IgnoreEnums(testpb.ForeignEnum(0)),
|
|
},
|
|
want: false,
|
|
}}...)
|
|
|
|
// Test IgnoreFields and IgnoreOneofs.
|
|
tests = append(tests, []test{{
|
|
x: &testpb.TestAllTypes{OptionalInt32: proto.Int32(5)},
|
|
y: &testpb.TestAllTypes{OptionalInt32: proto.Int32(6)},
|
|
opts: cmp.Options{Transform()},
|
|
want: false,
|
|
}, {
|
|
x: &testpb.TestAllTypes{OptionalInt32: proto.Int32(5)},
|
|
y: &testpb.TestAllTypes{},
|
|
opts: cmp.Options{Transform(),
|
|
IgnoreFields(&testpb.TestAllTypes{}, "optional_int32")},
|
|
want: true,
|
|
}, {
|
|
x: &testpb.TestAllTypes{OptionalInt32: proto.Int32(5)},
|
|
y: &testpb.TestAllTypes{OptionalInt32: proto.Int32(6)},
|
|
opts: cmp.Options{Transform(),
|
|
IgnoreFields(&testpb.TestAllTypes{}, "optional_int32")},
|
|
want: true,
|
|
}, {
|
|
x: &testpb.TestAllTypes{OptionalInt32: proto.Int32(5)},
|
|
y: &testpb.TestAllTypes{OptionalInt32: proto.Int32(6)},
|
|
opts: cmp.Options{Transform(),
|
|
IgnoreFields(&testpb.TestAllTypes{}, "optional_int64")},
|
|
want: false,
|
|
}, {
|
|
x: &testpb.TestAllTypes{OneofField: &testpb.TestAllTypes_OneofUint32{5}},
|
|
y: &testpb.TestAllTypes{OneofField: &testpb.TestAllTypes_OneofString{"5"}},
|
|
opts: cmp.Options{Transform()},
|
|
want: false,
|
|
}, {
|
|
x: &testpb.TestAllTypes{OneofField: &testpb.TestAllTypes_OneofUint32{5}},
|
|
y: &testpb.TestAllTypes{OneofField: &testpb.TestAllTypes_OneofString{"5"}},
|
|
opts: cmp.Options{Transform(),
|
|
IgnoreFields(&testpb.TestAllTypes{}, "oneof_uint32"),
|
|
IgnoreFields(&testpb.TestAllTypes{}, "oneof_string")},
|
|
want: true,
|
|
}, {
|
|
x: &testpb.TestAllTypes{OneofField: &testpb.TestAllTypes_OneofUint32{5}},
|
|
y: &testpb.TestAllTypes{OneofField: &testpb.TestAllTypes_OneofString{"5"}},
|
|
opts: cmp.Options{Transform(),
|
|
IgnoreOneofs(&testpb.TestAllTypes{}, "oneof_field")},
|
|
want: true,
|
|
}, {
|
|
x: apply(new(testpb.TestAllExtensions),
|
|
setExtension{testpb.E_OptionalString, "hello"}),
|
|
y: apply(new(testpb.TestAllExtensions),
|
|
setExtension{testpb.E_OptionalString, "goodbye"}),
|
|
opts: cmp.Options{Transform()},
|
|
want: false,
|
|
}, {
|
|
x: apply(new(testpb.TestAllExtensions),
|
|
setExtension{testpb.E_OptionalString, "hello"}),
|
|
y: new(testpb.TestAllExtensions),
|
|
opts: cmp.Options{Transform(),
|
|
IgnoreDescriptors(testpb.E_OptionalString.TypeDescriptor())},
|
|
want: true,
|
|
}, {
|
|
x: apply(new(testpb.TestAllExtensions),
|
|
setExtension{testpb.E_OptionalString, "hello"}),
|
|
y: apply(new(testpb.TestAllExtensions),
|
|
setExtension{testpb.E_OptionalString, "goodbye"}),
|
|
opts: cmp.Options{Transform(),
|
|
IgnoreDescriptors(testpb.E_OptionalString.TypeDescriptor())},
|
|
want: true,
|
|
}, {
|
|
x: apply(new(testpb.TestAllExtensions),
|
|
setExtension{testpb.E_OptionalString, "hello"}),
|
|
y: apply(new(testpb.TestAllExtensions),
|
|
setExtension{testpb.E_OptionalString, "goodbye"}),
|
|
opts: cmp.Options{Transform(),
|
|
IgnoreDescriptors(testpb.E_OptionalInt32.TypeDescriptor())},
|
|
want: false,
|
|
}}...)
|
|
|
|
for _, tt := range tests {
|
|
t.Run("", func(t *testing.T) {
|
|
got := cmp.Equal(tt.x, tt.y, tt.opts)
|
|
if got != tt.want {
|
|
if !got {
|
|
t.Errorf("cmp.Equal = false, want true; diff:\n%v", cmp.Diff(tt.x, tt.y, tt.opts))
|
|
} else {
|
|
t.Errorf("cmp.Equal = true, want false")
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
type setField struct {
|
|
num protoreflect.FieldNumber
|
|
val interface{}
|
|
}
|
|
type setUnknown struct {
|
|
raw protoreflect.RawFields
|
|
}
|
|
type setExtension struct {
|
|
typ protoreflect.ExtensionType
|
|
val interface{}
|
|
}
|
|
|
|
// apply applies a sequence of mutating operations to m.
|
|
func apply(m proto.Message, ops ...interface{}) proto.Message {
|
|
mr := m.ProtoReflect()
|
|
md := mr.Descriptor()
|
|
for _, op := range ops {
|
|
switch op := op.(type) {
|
|
case setField:
|
|
fd := md.Fields().ByNumber(op.num)
|
|
mr.Set(fd, protoreflect.ValueOf(op.val))
|
|
case setUnknown:
|
|
mr.SetUnknown(op.raw)
|
|
case setExtension:
|
|
mr.Set(op.typ.TypeDescriptor(), protoreflect.ValueOf(op.val))
|
|
}
|
|
}
|
|
return m
|
|
}
|