blob: 5b3376b69de643c208c54526e6ff645b21c73e52 [file] [log] [blame]
Joe Tsaid8881392019-06-06 13:01:53 -07001// 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
Damien Neil5c5b5312019-05-14 12:44:37 -07005package prototext_test
Herbie Ong800c9902018-12-06 15:28:53 -08006
7import (
8 "testing"
9
Damien Neil5c5b5312019-05-14 12:44:37 -070010 "google.golang.org/protobuf/encoding/prototext"
Damien Neile89e6242019-05-13 23:55:40 -070011 "google.golang.org/protobuf/internal/impl"
12 pimpl "google.golang.org/protobuf/internal/impl"
13 "google.golang.org/protobuf/internal/scalar"
14 "google.golang.org/protobuf/proto"
15 preg "google.golang.org/protobuf/reflect/protoregistry"
Herbie Ong800c9902018-12-06 15:28:53 -080016
Damien Neile89e6242019-05-13 23:55:40 -070017 "google.golang.org/protobuf/encoding/testprotos/pb2"
Joe Tsaia95b29f2019-05-16 12:47:20 -070018 "google.golang.org/protobuf/types/known/anypb"
19 "google.golang.org/protobuf/types/known/durationpb"
20 "google.golang.org/protobuf/types/known/emptypb"
21 "google.golang.org/protobuf/types/known/structpb"
22 "google.golang.org/protobuf/types/known/timestamppb"
23 "google.golang.org/protobuf/types/known/wrapperspb"
Herbie Ong800c9902018-12-06 15:28:53 -080024)
25
26func TestRoundTrip(t *testing.T) {
27 tests := []struct {
Herbie Ong66c365c2019-01-04 14:08:41 -080028 desc string
29 resolver *preg.Types
30 message proto.Message
Herbie Ong800c9902018-12-06 15:28:53 -080031 }{{
32 desc: "well-known type fields set to empty messages",
33 message: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -070034 OptBool: &wrapperspb.BoolValue{},
35 OptInt32: &wrapperspb.Int32Value{},
36 OptInt64: &wrapperspb.Int64Value{},
37 OptUint32: &wrapperspb.UInt32Value{},
38 OptUint64: &wrapperspb.UInt64Value{},
39 OptFloat: &wrapperspb.FloatValue{},
40 OptDouble: &wrapperspb.DoubleValue{},
41 OptString: &wrapperspb.StringValue{},
42 OptBytes: &wrapperspb.BytesValue{},
43 OptDuration: &durationpb.Duration{},
44 OptTimestamp: &timestamppb.Timestamp{},
45 OptStruct: &structpb.Struct{},
46 OptList: &structpb.ListValue{},
47 OptValue: &structpb.Value{},
48 OptEmpty: &emptypb.Empty{},
49 OptAny: &anypb.Any{},
Herbie Ong800c9902018-12-06 15:28:53 -080050 },
51 }, {
52 desc: "well-known type scalar fields",
53 message: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -070054 OptBool: &wrapperspb.BoolValue{
Herbie Ong800c9902018-12-06 15:28:53 -080055 Value: true,
56 },
Joe Tsaia95b29f2019-05-16 12:47:20 -070057 OptInt32: &wrapperspb.Int32Value{
Herbie Ong800c9902018-12-06 15:28:53 -080058 Value: -42,
59 },
Joe Tsaia95b29f2019-05-16 12:47:20 -070060 OptInt64: &wrapperspb.Int64Value{
Herbie Ong800c9902018-12-06 15:28:53 -080061 Value: -42,
62 },
Joe Tsaia95b29f2019-05-16 12:47:20 -070063 OptUint32: &wrapperspb.UInt32Value{
Herbie Ong800c9902018-12-06 15:28:53 -080064 Value: 0xff,
65 },
Joe Tsaia95b29f2019-05-16 12:47:20 -070066 OptUint64: &wrapperspb.UInt64Value{
Herbie Ong800c9902018-12-06 15:28:53 -080067 Value: 0xffff,
68 },
Joe Tsaia95b29f2019-05-16 12:47:20 -070069 OptFloat: &wrapperspb.FloatValue{
Herbie Ong800c9902018-12-06 15:28:53 -080070 Value: 1.234,
71 },
Joe Tsaia95b29f2019-05-16 12:47:20 -070072 OptDouble: &wrapperspb.DoubleValue{
Herbie Ong800c9902018-12-06 15:28:53 -080073 Value: 1.23e308,
74 },
Joe Tsaia95b29f2019-05-16 12:47:20 -070075 OptString: &wrapperspb.StringValue{
Herbie Ong800c9902018-12-06 15:28:53 -080076 Value: "谷歌",
77 },
Joe Tsaia95b29f2019-05-16 12:47:20 -070078 OptBytes: &wrapperspb.BytesValue{
Herbie Ong800c9902018-12-06 15:28:53 -080079 Value: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
80 },
81 },
82 }, {
83 desc: "well-known type time-related fields",
84 message: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -070085 OptDuration: &durationpb.Duration{
Herbie Ong800c9902018-12-06 15:28:53 -080086 Seconds: -3600,
87 Nanos: -123,
88 },
Joe Tsaia95b29f2019-05-16 12:47:20 -070089 OptTimestamp: &timestamppb.Timestamp{
Herbie Ong800c9902018-12-06 15:28:53 -080090 Seconds: 1257894000,
91 Nanos: 123,
92 },
93 },
94 }, {
Herbie Ong66c365c2019-01-04 14:08:41 -080095 desc: "Struct field and different Value types",
Herbie Ong800c9902018-12-06 15:28:53 -080096 message: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -070097 OptStruct: &structpb.Struct{
98 Fields: map[string]*structpb.Value{
99 "bool": &structpb.Value{
100 Kind: &structpb.Value_BoolValue{
Herbie Ong800c9902018-12-06 15:28:53 -0800101 BoolValue: true,
102 },
103 },
Joe Tsaia95b29f2019-05-16 12:47:20 -0700104 "double": &structpb.Value{
105 Kind: &structpb.Value_NumberValue{
Herbie Ong800c9902018-12-06 15:28:53 -0800106 NumberValue: 3.1415,
107 },
108 },
Joe Tsaia95b29f2019-05-16 12:47:20 -0700109 "null": &structpb.Value{
110 Kind: &structpb.Value_NullValue{
111 NullValue: structpb.NullValue_NULL_VALUE,
Herbie Ong800c9902018-12-06 15:28:53 -0800112 },
113 },
Joe Tsaia95b29f2019-05-16 12:47:20 -0700114 "string": &structpb.Value{
115 Kind: &structpb.Value_StringValue{
Herbie Ong800c9902018-12-06 15:28:53 -0800116 StringValue: "string",
117 },
118 },
Joe Tsaia95b29f2019-05-16 12:47:20 -0700119 "struct": &structpb.Value{
120 Kind: &structpb.Value_StructValue{
121 StructValue: &structpb.Struct{
122 Fields: map[string]*structpb.Value{
123 "bool": &structpb.Value{
124 Kind: &structpb.Value_BoolValue{
Herbie Ong800c9902018-12-06 15:28:53 -0800125 BoolValue: false,
126 },
127 },
128 },
129 },
130 },
131 },
Joe Tsaia95b29f2019-05-16 12:47:20 -0700132 "list": &structpb.Value{
133 Kind: &structpb.Value_ListValue{
134 ListValue: &structpb.ListValue{
135 Values: []*structpb.Value{
Herbie Ong800c9902018-12-06 15:28:53 -0800136 {
Joe Tsaia95b29f2019-05-16 12:47:20 -0700137 Kind: &structpb.Value_BoolValue{
Herbie Ong800c9902018-12-06 15:28:53 -0800138 BoolValue: false,
139 },
140 },
141 {
Joe Tsaia95b29f2019-05-16 12:47:20 -0700142 Kind: &structpb.Value_StringValue{
Herbie Ong800c9902018-12-06 15:28:53 -0800143 StringValue: "hello",
144 },
145 },
146 },
147 },
148 },
149 },
150 },
151 },
152 },
Herbie Ong66c365c2019-01-04 14:08:41 -0800153 }, {
154 desc: "Any field without registered type",
155 resolver: preg.NewTypes(),
156 message: func() proto.Message {
157 m := &pb2.Nested{
158 OptString: scalar.String("embedded inside Any"),
159 OptNested: &pb2.Nested{
160 OptString: scalar.String("inception"),
161 },
162 }
Herbie Ong4d1c3be2019-03-15 18:22:36 -0700163 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
Herbie Ong66c365c2019-01-04 14:08:41 -0800164 if err != nil {
165 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
166 }
167 return &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -0700168 OptAny: &anypb.Any{
Joe Tsai0fc49f82019-05-01 12:29:25 -0700169 TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
Herbie Ong66c365c2019-01-04 14:08:41 -0800170 Value: b,
171 },
172 }
173 }(),
174 }, {
175 desc: "Any field with registered type",
Joe Tsai0fc49f82019-05-01 12:29:25 -0700176 resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
177 message: func() *pb2.KnownTypes {
Herbie Ong66c365c2019-01-04 14:08:41 -0800178 m := &pb2.Nested{
179 OptString: scalar.String("embedded inside Any"),
180 OptNested: &pb2.Nested{
181 OptString: scalar.String("inception"),
182 },
183 }
Herbie Ong4d1c3be2019-03-15 18:22:36 -0700184 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
Herbie Ong66c365c2019-01-04 14:08:41 -0800185 if err != nil {
186 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
187 }
188 return &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -0700189 OptAny: &anypb.Any{
Joe Tsai0fc49f82019-05-01 12:29:25 -0700190 TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
Herbie Ong66c365c2019-01-04 14:08:41 -0800191 Value: b,
192 },
193 }
194 }(),
195 }, {
196 desc: "Any field containing Any message",
197 resolver: func() *preg.Types {
Joe Tsai0fc49f82019-05-01 12:29:25 -0700198 mt1 := impl.Export{}.MessageTypeOf(&pb2.Nested{})
Joe Tsaia95b29f2019-05-16 12:47:20 -0700199 mt2 := impl.Export{}.MessageTypeOf(&anypb.Any{})
Herbie Ong66c365c2019-01-04 14:08:41 -0800200 return preg.NewTypes(mt1, mt2)
201 }(),
Joe Tsai0fc49f82019-05-01 12:29:25 -0700202 message: func() *pb2.KnownTypes {
Herbie Ong66c365c2019-01-04 14:08:41 -0800203 m1 := &pb2.Nested{
204 OptString: scalar.String("message inside Any of another Any field"),
205 }
Herbie Ong4d1c3be2019-03-15 18:22:36 -0700206 b1, err := proto.MarshalOptions{Deterministic: true}.Marshal(m1)
Herbie Ong66c365c2019-01-04 14:08:41 -0800207 if err != nil {
208 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
209 }
Joe Tsaia95b29f2019-05-16 12:47:20 -0700210 m2 := &anypb.Any{
Herbie Ong66c365c2019-01-04 14:08:41 -0800211 TypeUrl: "pb2.Nested",
212 Value: b1,
213 }
Herbie Ong4d1c3be2019-03-15 18:22:36 -0700214 b2, err := proto.MarshalOptions{Deterministic: true}.Marshal(m2)
Herbie Ong66c365c2019-01-04 14:08:41 -0800215 if err != nil {
216 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
217 }
218 return &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -0700219 OptAny: &anypb.Any{
Herbie Ong66c365c2019-01-04 14:08:41 -0800220 TypeUrl: "google.protobuf.Any",
221 Value: b2,
222 },
223 }
224 }(),
Herbie Ong800c9902018-12-06 15:28:53 -0800225 }}
226
227 for _, tt := range tests {
228 tt := tt
229 t.Run(tt.desc, func(t *testing.T) {
230 t.Parallel()
Damien Neil5c5b5312019-05-14 12:44:37 -0700231 b, err := prototext.MarshalOptions{Resolver: tt.resolver}.Marshal(tt.message)
Herbie Ong800c9902018-12-06 15:28:53 -0800232 if err != nil {
233 t.Errorf("Marshal() returned error: %v\n\n", err)
234 }
Joe Tsai0fc49f82019-05-01 12:29:25 -0700235
236 gotMessage := new(pb2.KnownTypes)
Joe Tsaicdb77732019-05-14 16:05:06 -0700237 err = prototext.UnmarshalOptions{Resolver: tt.resolver}.Unmarshal(b, gotMessage)
Herbie Ong800c9902018-12-06 15:28:53 -0800238 if err != nil {
239 t.Errorf("Unmarshal() returned error: %v\n\n", err)
240 }
Herbie Ong66c365c2019-01-04 14:08:41 -0800241
Joe Tsai8d30bbe2019-05-16 15:53:25 -0700242 if !proto.Equal(gotMessage, tt.message) {
Herbie Ong70651952018-12-13 14:19:50 -0800243 t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", gotMessage, tt.message)
244 }
Herbie Ong800c9902018-12-06 15:28:53 -0800245 })
246 }
247}