blob: e9f3898ee878ba93d342052cc12bf30b816da5cb [file] [log] [blame]
// Copyright 2020 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/proto"
testpb "google.golang.org/protobuf/internal/testprotos/test"
textpb "google.golang.org/protobuf/internal/testprotos/textpb2"
anypb "google.golang.org/protobuf/types/known/anypb"
wrapperspb "google.golang.org/protobuf/types/known/wrapperspb"
)
func TestReflect(t *testing.T) {
optMsg := &testpb.TestAllTypes{
OptionalInt32: proto.Int32(-32),
OptionalInt64: proto.Int64(-64),
OptionalUint32: proto.Uint32(32),
OptionalUint64: proto.Uint64(64),
OptionalFloat: proto.Float32(32.32),
OptionalDouble: proto.Float64(64.64),
OptionalBool: proto.Bool(true),
OptionalString: proto.String("string"),
OptionalBytes: []byte("bytes"),
OptionalNestedMessage: &testpb.TestAllTypes_NestedMessage{A: proto.Int32(-32)},
OptionalNestedEnum: testpb.TestAllTypes_NEG.Enum(),
}
repMsg := &testpb.TestAllTypes{
RepeatedInt32: []int32{-32, +32},
RepeatedInt64: []int64{-64, +64},
RepeatedUint32: []uint32{0, 32},
RepeatedUint64: []uint64{0, 64},
RepeatedFloat: []float32{-32.32, +32.32},
RepeatedDouble: []float64{-64.64, +64.64},
RepeatedBool: []bool{false, true},
RepeatedString: []string{"hello", "goodbye"},
RepeatedBytes: [][]byte{[]byte("hello"), []byte("goodbye")},
RepeatedNestedMessage: []*testpb.TestAllTypes_NestedMessage{{A: proto.Int32(-32)}, {A: proto.Int32(+32)}},
RepeatedNestedEnum: []testpb.TestAllTypes_NestedEnum{testpb.TestAllTypes_FOO, testpb.TestAllTypes_NEG},
}
mapMsg := &testpb.TestAllTypes{
MapInt32Int32: map[int32]int32{-1: -32, +1: +32},
MapInt64Int64: map[int64]int64{-1: -32, +1: +64},
MapUint32Uint32: map[uint32]uint32{0: 0, 1: 32},
MapUint64Uint64: map[uint64]uint64{0: 0, 1: 64},
MapInt32Float: map[int32]float32{-1: -32.32, +1: +32.32},
MapInt32Double: map[int32]float64{-1: -64.64, +1: +64.64},
MapBoolBool: map[bool]bool{false: true, true: false},
MapStringString: map[string]string{"k1": "v1", "k2": "v2"},
MapStringBytes: map[string][]byte{"k1": []byte("v1"), "k2": []byte("v2")},
MapStringNestedMessage: map[string]*testpb.TestAllTypes_NestedMessage{"k1": {A: proto.Int32(-32)}, "k2": {A: proto.Int32(+32)}},
MapStringNestedEnum: map[string]testpb.TestAllTypes_NestedEnum{"k1": testpb.TestAllTypes_FOO, "k2": testpb.TestAllTypes_NEG},
}
tests := []proto.Message{
optMsg,
repMsg,
mapMsg,
&testpb.TestAllTypes{
OneofField: &testpb.TestAllTypes_OneofUint32{32},
},
&testpb.TestAllTypes{
OneofField: &testpb.TestAllTypes_OneofUint64{64},
},
&testpb.TestAllTypes{
OneofField: &testpb.TestAllTypes_OneofFloat{32.32},
},
&testpb.TestAllTypes{
OneofField: &testpb.TestAllTypes_OneofDouble{64.64},
},
&testpb.TestAllTypes{
OneofField: &testpb.TestAllTypes_OneofBool{true},
},
&testpb.TestAllTypes{
OneofField: &testpb.TestAllTypes_OneofString{"string"},
},
&testpb.TestAllTypes{
OneofField: &testpb.TestAllTypes_OneofBytes{[]byte("bytes")},
},
&testpb.TestAllTypes{
OneofField: &testpb.TestAllTypes_OneofNestedMessage{&testpb.TestAllTypes_NestedMessage{A: proto.Int32(-32)}},
},
&testpb.TestAllTypes{
OneofField: &testpb.TestAllTypes_OneofEnum{testpb.TestAllTypes_NEG},
},
&textpb.KnownTypes{
OptBool: &wrapperspb.BoolValue{Value: true},
OptInt32: &wrapperspb.Int32Value{Value: -32},
OptInt64: &wrapperspb.Int64Value{Value: -64},
OptUint32: &wrapperspb.UInt32Value{Value: +32},
OptUint64: &wrapperspb.UInt64Value{Value: +64},
OptFloat: &wrapperspb.FloatValue{Value: 32.32},
OptDouble: &wrapperspb.DoubleValue{Value: 64.64},
OptString: &wrapperspb.StringValue{Value: "string"},
OptBytes: &wrapperspb.BytesValue{Value: []byte("bytes")},
},
&textpb.KnownTypes{
OptAny: &anypb.Any{
TypeUrl: "google.golang.org/goproto.proto.test.TestAllTypes",
Value: func() []byte {
b1, _ := proto.MarshalOptions{Deterministic: true}.Marshal(optMsg)
b2, _ := proto.MarshalOptions{Deterministic: true}.Marshal(repMsg)
b3, _ := proto.MarshalOptions{Deterministic: true}.Marshal(mapMsg)
return append(append(append([]byte(nil), b1...), b2...), b3...)
}(),
},
},
&textpb.KnownTypes{
OptAny: &anypb.Any{
TypeUrl: "unknown_type",
Value: []byte("invalid_value"),
},
},
}
for _, src := range tests {
dst := src.ProtoReflect().Type().New().Interface()
proto.Merge(dst, transformMessage(src.ProtoReflect()))
if diff := cmp.Diff(src, dst, Transform()); diff != "" {
t.Errorf("Merge mismatch (-want +got):\n%s", diff)
}
}
}