Damien Neil c1507ac678 encoding/protojson, encoding/prototext: remove most explicit registries
Change tests which use private types registries to use the global one.
Except in cases where we want to explicitly test that the private
registry is used, it's simpler to use the global registry.

Change-Id: I998fb463b6beef91c7f5ce2ca2083251ae24d1db
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/199897
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
Reviewed-by: Herbie Ong <herbie@google.com>
2019-10-09 07:10:37 +00:00

239 lines
6.2 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 prototext_test
import (
"testing"
"google.golang.org/protobuf/encoding/prototext"
"google.golang.org/protobuf/proto"
preg "google.golang.org/protobuf/reflect/protoregistry"
"google.golang.org/protobuf/encoding/testprotos/pb2"
"google.golang.org/protobuf/types/known/anypb"
"google.golang.org/protobuf/types/known/durationpb"
"google.golang.org/protobuf/types/known/emptypb"
"google.golang.org/protobuf/types/known/structpb"
"google.golang.org/protobuf/types/known/timestamppb"
"google.golang.org/protobuf/types/known/wrapperspb"
)
func TestRoundTrip(t *testing.T) {
tests := []struct {
desc string
resolver *preg.Types
message proto.Message
}{{
desc: "well-known type fields set to empty messages",
message: &pb2.KnownTypes{
OptBool: &wrapperspb.BoolValue{},
OptInt32: &wrapperspb.Int32Value{},
OptInt64: &wrapperspb.Int64Value{},
OptUint32: &wrapperspb.UInt32Value{},
OptUint64: &wrapperspb.UInt64Value{},
OptFloat: &wrapperspb.FloatValue{},
OptDouble: &wrapperspb.DoubleValue{},
OptString: &wrapperspb.StringValue{},
OptBytes: &wrapperspb.BytesValue{},
OptDuration: &durationpb.Duration{},
OptTimestamp: &timestamppb.Timestamp{},
OptStruct: &structpb.Struct{},
OptList: &structpb.ListValue{},
OptValue: &structpb.Value{},
OptEmpty: &emptypb.Empty{},
OptAny: &anypb.Any{},
},
}, {
desc: "well-known type scalar fields",
message: &pb2.KnownTypes{
OptBool: &wrapperspb.BoolValue{
Value: true,
},
OptInt32: &wrapperspb.Int32Value{
Value: -42,
},
OptInt64: &wrapperspb.Int64Value{
Value: -42,
},
OptUint32: &wrapperspb.UInt32Value{
Value: 0xff,
},
OptUint64: &wrapperspb.UInt64Value{
Value: 0xffff,
},
OptFloat: &wrapperspb.FloatValue{
Value: 1.234,
},
OptDouble: &wrapperspb.DoubleValue{
Value: 1.23e308,
},
OptString: &wrapperspb.StringValue{
Value: "谷歌",
},
OptBytes: &wrapperspb.BytesValue{
Value: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
},
},
}, {
desc: "well-known type time-related fields",
message: &pb2.KnownTypes{
OptDuration: &durationpb.Duration{
Seconds: -3600,
Nanos: -123,
},
OptTimestamp: &timestamppb.Timestamp{
Seconds: 1257894000,
Nanos: 123,
},
},
}, {
desc: "Struct field and different Value types",
message: &pb2.KnownTypes{
OptStruct: &structpb.Struct{
Fields: map[string]*structpb.Value{
"bool": &structpb.Value{
Kind: &structpb.Value_BoolValue{
BoolValue: true,
},
},
"double": &structpb.Value{
Kind: &structpb.Value_NumberValue{
NumberValue: 3.1415,
},
},
"null": &structpb.Value{
Kind: &structpb.Value_NullValue{
NullValue: structpb.NullValue_NULL_VALUE,
},
},
"string": &structpb.Value{
Kind: &structpb.Value_StringValue{
StringValue: "string",
},
},
"struct": &structpb.Value{
Kind: &structpb.Value_StructValue{
StructValue: &structpb.Struct{
Fields: map[string]*structpb.Value{
"bool": &structpb.Value{
Kind: &structpb.Value_BoolValue{
BoolValue: false,
},
},
},
},
},
},
"list": &structpb.Value{
Kind: &structpb.Value_ListValue{
ListValue: &structpb.ListValue{
Values: []*structpb.Value{
{
Kind: &structpb.Value_BoolValue{
BoolValue: false,
},
},
{
Kind: &structpb.Value_StringValue{
StringValue: "hello",
},
},
},
},
},
},
},
},
},
}, {
desc: "Any field without registered type",
resolver: new(preg.Types),
message: func() proto.Message {
m := &pb2.Nested{
OptString: proto.String("embedded inside Any"),
OptNested: &pb2.Nested{
OptString: proto.String("inception"),
},
}
b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
if err != nil {
t.Fatalf("error in binary marshaling message for Any.value: %v", err)
}
return &pb2.KnownTypes{
OptAny: &anypb.Any{
TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
Value: b,
},
}
}(),
}, {
desc: "Any field with registered type",
message: func() *pb2.KnownTypes {
m := &pb2.Nested{
OptString: proto.String("embedded inside Any"),
OptNested: &pb2.Nested{
OptString: proto.String("inception"),
},
}
b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
if err != nil {
t.Fatalf("error in binary marshaling message for Any.value: %v", err)
}
return &pb2.KnownTypes{
OptAny: &anypb.Any{
TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
Value: b,
},
}
}(),
}, {
desc: "Any field containing Any message",
message: func() *pb2.KnownTypes {
m1 := &pb2.Nested{
OptString: proto.String("message inside Any of another Any field"),
}
b1, err := proto.MarshalOptions{Deterministic: true}.Marshal(m1)
if err != nil {
t.Fatalf("error in binary marshaling message for Any.value: %v", err)
}
m2 := &anypb.Any{
TypeUrl: "pb2.Nested",
Value: b1,
}
b2, err := proto.MarshalOptions{Deterministic: true}.Marshal(m2)
if err != nil {
t.Fatalf("error in binary marshaling message for Any.value: %v", err)
}
return &pb2.KnownTypes{
OptAny: &anypb.Any{
TypeUrl: "google.protobuf.Any",
Value: b2,
},
}
}(),
}}
for _, tt := range tests {
tt := tt
t.Run(tt.desc, func(t *testing.T) {
t.Parallel()
b, err := prototext.MarshalOptions{Resolver: tt.resolver}.Marshal(tt.message)
if err != nil {
t.Errorf("Marshal() returned error: %v\n\n", err)
}
gotMessage := new(pb2.KnownTypes)
err = prototext.UnmarshalOptions{Resolver: tt.resolver}.Unmarshal(b, gotMessage)
if err != nil {
t.Errorf("Unmarshal() returned error: %v\n\n", err)
}
if !proto.Equal(gotMessage, tt.message) {
t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", gotMessage, tt.message)
}
})
}
}