...

Source file src/google.golang.org/protobuf/encoding/prototext/other_test.go

Documentation: google.golang.org/protobuf/encoding/prototext

     1  // Copyright 2019 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package prototext_test
     6  
     7  import (
     8  	"testing"
     9  
    10  	"google.golang.org/protobuf/encoding/prototext"
    11  	"google.golang.org/protobuf/proto"
    12  	"google.golang.org/protobuf/reflect/protoregistry"
    13  
    14  	pb2 "google.golang.org/protobuf/internal/testprotos/textpb2"
    15  	"google.golang.org/protobuf/types/known/anypb"
    16  	"google.golang.org/protobuf/types/known/durationpb"
    17  	"google.golang.org/protobuf/types/known/emptypb"
    18  	"google.golang.org/protobuf/types/known/structpb"
    19  	"google.golang.org/protobuf/types/known/timestamppb"
    20  	"google.golang.org/protobuf/types/known/wrapperspb"
    21  )
    22  
    23  func TestRoundTrip(t *testing.T) {
    24  	tests := []struct {
    25  		desc     string
    26  		resolver *protoregistry.Types
    27  		message  proto.Message
    28  	}{{
    29  		desc: "well-known type fields set to empty messages",
    30  		message: &pb2.KnownTypes{
    31  			OptBool:      &wrapperspb.BoolValue{},
    32  			OptInt32:     &wrapperspb.Int32Value{},
    33  			OptInt64:     &wrapperspb.Int64Value{},
    34  			OptUint32:    &wrapperspb.UInt32Value{},
    35  			OptUint64:    &wrapperspb.UInt64Value{},
    36  			OptFloat:     &wrapperspb.FloatValue{},
    37  			OptDouble:    &wrapperspb.DoubleValue{},
    38  			OptString:    &wrapperspb.StringValue{},
    39  			OptBytes:     &wrapperspb.BytesValue{},
    40  			OptDuration:  &durationpb.Duration{},
    41  			OptTimestamp: &timestamppb.Timestamp{},
    42  			OptStruct:    &structpb.Struct{},
    43  			OptList:      &structpb.ListValue{},
    44  			OptValue:     &structpb.Value{},
    45  			OptEmpty:     &emptypb.Empty{},
    46  			OptAny:       &anypb.Any{},
    47  		},
    48  	}, {
    49  		desc: "well-known type scalar fields",
    50  		message: &pb2.KnownTypes{
    51  			OptBool: &wrapperspb.BoolValue{
    52  				Value: true,
    53  			},
    54  			OptInt32: &wrapperspb.Int32Value{
    55  				Value: -42,
    56  			},
    57  			OptInt64: &wrapperspb.Int64Value{
    58  				Value: -42,
    59  			},
    60  			OptUint32: &wrapperspb.UInt32Value{
    61  				Value: 0xff,
    62  			},
    63  			OptUint64: &wrapperspb.UInt64Value{
    64  				Value: 0xffff,
    65  			},
    66  			OptFloat: &wrapperspb.FloatValue{
    67  				Value: 1.234,
    68  			},
    69  			OptDouble: &wrapperspb.DoubleValue{
    70  				Value: 1.23e308,
    71  			},
    72  			OptString: &wrapperspb.StringValue{
    73  				Value: "谷歌",
    74  			},
    75  			OptBytes: &wrapperspb.BytesValue{
    76  				Value: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
    77  			},
    78  		},
    79  	}, {
    80  		desc: "well-known type time-related fields",
    81  		message: &pb2.KnownTypes{
    82  			OptDuration: &durationpb.Duration{
    83  				Seconds: -3600,
    84  				Nanos:   -123,
    85  			},
    86  			OptTimestamp: &timestamppb.Timestamp{
    87  				Seconds: 1257894000,
    88  				Nanos:   123,
    89  			},
    90  		},
    91  	}, {
    92  		desc: "Struct field and different Value types",
    93  		message: &pb2.KnownTypes{
    94  			OptStruct: &structpb.Struct{
    95  				Fields: map[string]*structpb.Value{
    96  					"bool": &structpb.Value{
    97  						Kind: &structpb.Value_BoolValue{
    98  							BoolValue: true,
    99  						},
   100  					},
   101  					"double": &structpb.Value{
   102  						Kind: &structpb.Value_NumberValue{
   103  							NumberValue: 3.1415,
   104  						},
   105  					},
   106  					"null": &structpb.Value{
   107  						Kind: &structpb.Value_NullValue{
   108  							NullValue: structpb.NullValue_NULL_VALUE,
   109  						},
   110  					},
   111  					"string": &structpb.Value{
   112  						Kind: &structpb.Value_StringValue{
   113  							StringValue: "string",
   114  						},
   115  					},
   116  					"struct": &structpb.Value{
   117  						Kind: &structpb.Value_StructValue{
   118  							StructValue: &structpb.Struct{
   119  								Fields: map[string]*structpb.Value{
   120  									"bool": &structpb.Value{
   121  										Kind: &structpb.Value_BoolValue{
   122  											BoolValue: false,
   123  										},
   124  									},
   125  								},
   126  							},
   127  						},
   128  					},
   129  					"list": &structpb.Value{
   130  						Kind: &structpb.Value_ListValue{
   131  							ListValue: &structpb.ListValue{
   132  								Values: []*structpb.Value{
   133  									{
   134  										Kind: &structpb.Value_BoolValue{
   135  											BoolValue: false,
   136  										},
   137  									},
   138  									{
   139  										Kind: &structpb.Value_StringValue{
   140  											StringValue: "hello",
   141  										},
   142  									},
   143  								},
   144  							},
   145  						},
   146  					},
   147  				},
   148  			},
   149  		},
   150  	}, {
   151  		desc:     "Any field without registered type",
   152  		resolver: new(protoregistry.Types),
   153  		message: func() proto.Message {
   154  			m := &pb2.Nested{
   155  				OptString: proto.String("embedded inside Any"),
   156  				OptNested: &pb2.Nested{
   157  					OptString: proto.String("inception"),
   158  				},
   159  			}
   160  			b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
   161  			if err != nil {
   162  				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
   163  			}
   164  			return &pb2.KnownTypes{
   165  				OptAny: &anypb.Any{
   166  					TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
   167  					Value:   b,
   168  				},
   169  			}
   170  		}(),
   171  	}, {
   172  		desc: "Any field with registered type",
   173  		message: func() *pb2.KnownTypes {
   174  			m := &pb2.Nested{
   175  				OptString: proto.String("embedded inside Any"),
   176  				OptNested: &pb2.Nested{
   177  					OptString: proto.String("inception"),
   178  				},
   179  			}
   180  			b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
   181  			if err != nil {
   182  				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
   183  			}
   184  			return &pb2.KnownTypes{
   185  				OptAny: &anypb.Any{
   186  					TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
   187  					Value:   b,
   188  				},
   189  			}
   190  		}(),
   191  	}, {
   192  		desc: "Any field containing Any message",
   193  		message: func() *pb2.KnownTypes {
   194  			m1 := &pb2.Nested{
   195  				OptString: proto.String("message inside Any of another Any field"),
   196  			}
   197  			b1, err := proto.MarshalOptions{Deterministic: true}.Marshal(m1)
   198  			if err != nil {
   199  				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
   200  			}
   201  			m2 := &anypb.Any{
   202  				TypeUrl: "pb2.Nested",
   203  				Value:   b1,
   204  			}
   205  			b2, err := proto.MarshalOptions{Deterministic: true}.Marshal(m2)
   206  			if err != nil {
   207  				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
   208  			}
   209  			return &pb2.KnownTypes{
   210  				OptAny: &anypb.Any{
   211  					TypeUrl: "google.protobuf.Any",
   212  					Value:   b2,
   213  				},
   214  			}
   215  		}(),
   216  	}}
   217  
   218  	for _, tt := range tests {
   219  		tt := tt
   220  		t.Run(tt.desc, func(t *testing.T) {
   221  			t.Parallel()
   222  			b, err := prototext.MarshalOptions{Resolver: tt.resolver}.Marshal(tt.message)
   223  			if err != nil {
   224  				t.Errorf("Marshal() returned error: %v\n\n", err)
   225  			}
   226  
   227  			gotMessage := new(pb2.KnownTypes)
   228  			err = prototext.UnmarshalOptions{Resolver: tt.resolver}.Unmarshal(b, gotMessage)
   229  			if err != nil {
   230  				t.Errorf("Unmarshal() returned error: %v\n\n", err)
   231  			}
   232  
   233  			if !proto.Equal(gotMessage, tt.message) {
   234  				t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", gotMessage, tt.message)
   235  			}
   236  		})
   237  	}
   238  }
   239  

View as plain text