blob: 0ae4ba6d60bf2f6d80b6c6f09bcf2f42d6dd2424 [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/proto"
12 preg "google.golang.org/protobuf/reflect/protoregistry"
Herbie Ong800c9902018-12-06 15:28:53 -080013
Damien Neile89e6242019-05-13 23:55:40 -070014 "google.golang.org/protobuf/encoding/testprotos/pb2"
Joe Tsaia95b29f2019-05-16 12:47:20 -070015 "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"
Herbie Ong800c9902018-12-06 15:28:53 -080021)
22
23func TestRoundTrip(t *testing.T) {
24 tests := []struct {
Herbie Ong66c365c2019-01-04 14:08:41 -080025 desc string
26 resolver *preg.Types
27 message proto.Message
Herbie Ong800c9902018-12-06 15:28:53 -080028 }{{
29 desc: "well-known type fields set to empty messages",
30 message: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -070031 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{},
Herbie Ong800c9902018-12-06 15:28:53 -080047 },
48 }, {
49 desc: "well-known type scalar fields",
50 message: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -070051 OptBool: &wrapperspb.BoolValue{
Herbie Ong800c9902018-12-06 15:28:53 -080052 Value: true,
53 },
Joe Tsaia95b29f2019-05-16 12:47:20 -070054 OptInt32: &wrapperspb.Int32Value{
Herbie Ong800c9902018-12-06 15:28:53 -080055 Value: -42,
56 },
Joe Tsaia95b29f2019-05-16 12:47:20 -070057 OptInt64: &wrapperspb.Int64Value{
Herbie Ong800c9902018-12-06 15:28:53 -080058 Value: -42,
59 },
Joe Tsaia95b29f2019-05-16 12:47:20 -070060 OptUint32: &wrapperspb.UInt32Value{
Herbie Ong800c9902018-12-06 15:28:53 -080061 Value: 0xff,
62 },
Joe Tsaia95b29f2019-05-16 12:47:20 -070063 OptUint64: &wrapperspb.UInt64Value{
Herbie Ong800c9902018-12-06 15:28:53 -080064 Value: 0xffff,
65 },
Joe Tsaia95b29f2019-05-16 12:47:20 -070066 OptFloat: &wrapperspb.FloatValue{
Herbie Ong800c9902018-12-06 15:28:53 -080067 Value: 1.234,
68 },
Joe Tsaia95b29f2019-05-16 12:47:20 -070069 OptDouble: &wrapperspb.DoubleValue{
Herbie Ong800c9902018-12-06 15:28:53 -080070 Value: 1.23e308,
71 },
Joe Tsaia95b29f2019-05-16 12:47:20 -070072 OptString: &wrapperspb.StringValue{
Herbie Ong800c9902018-12-06 15:28:53 -080073 Value: "谷歌",
74 },
Joe Tsaia95b29f2019-05-16 12:47:20 -070075 OptBytes: &wrapperspb.BytesValue{
Herbie Ong800c9902018-12-06 15:28:53 -080076 Value: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
77 },
78 },
79 }, {
80 desc: "well-known type time-related fields",
81 message: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -070082 OptDuration: &durationpb.Duration{
Herbie Ong800c9902018-12-06 15:28:53 -080083 Seconds: -3600,
84 Nanos: -123,
85 },
Joe Tsaia95b29f2019-05-16 12:47:20 -070086 OptTimestamp: &timestamppb.Timestamp{
Herbie Ong800c9902018-12-06 15:28:53 -080087 Seconds: 1257894000,
88 Nanos: 123,
89 },
90 },
91 }, {
Herbie Ong66c365c2019-01-04 14:08:41 -080092 desc: "Struct field and different Value types",
Herbie Ong800c9902018-12-06 15:28:53 -080093 message: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -070094 OptStruct: &structpb.Struct{
95 Fields: map[string]*structpb.Value{
96 "bool": &structpb.Value{
97 Kind: &structpb.Value_BoolValue{
Herbie Ong800c9902018-12-06 15:28:53 -080098 BoolValue: true,
99 },
100 },
Joe Tsaia95b29f2019-05-16 12:47:20 -0700101 "double": &structpb.Value{
102 Kind: &structpb.Value_NumberValue{
Herbie Ong800c9902018-12-06 15:28:53 -0800103 NumberValue: 3.1415,
104 },
105 },
Joe Tsaia95b29f2019-05-16 12:47:20 -0700106 "null": &structpb.Value{
107 Kind: &structpb.Value_NullValue{
108 NullValue: structpb.NullValue_NULL_VALUE,
Herbie Ong800c9902018-12-06 15:28:53 -0800109 },
110 },
Joe Tsaia95b29f2019-05-16 12:47:20 -0700111 "string": &structpb.Value{
112 Kind: &structpb.Value_StringValue{
Herbie Ong800c9902018-12-06 15:28:53 -0800113 StringValue: "string",
114 },
115 },
Joe Tsaia95b29f2019-05-16 12:47:20 -0700116 "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{
Herbie Ong800c9902018-12-06 15:28:53 -0800122 BoolValue: false,
123 },
124 },
125 },
126 },
127 },
128 },
Joe Tsaia95b29f2019-05-16 12:47:20 -0700129 "list": &structpb.Value{
130 Kind: &structpb.Value_ListValue{
131 ListValue: &structpb.ListValue{
132 Values: []*structpb.Value{
Herbie Ong800c9902018-12-06 15:28:53 -0800133 {
Joe Tsaia95b29f2019-05-16 12:47:20 -0700134 Kind: &structpb.Value_BoolValue{
Herbie Ong800c9902018-12-06 15:28:53 -0800135 BoolValue: false,
136 },
137 },
138 {
Joe Tsaia95b29f2019-05-16 12:47:20 -0700139 Kind: &structpb.Value_StringValue{
Herbie Ong800c9902018-12-06 15:28:53 -0800140 StringValue: "hello",
141 },
142 },
143 },
144 },
145 },
146 },
147 },
148 },
149 },
Herbie Ong66c365c2019-01-04 14:08:41 -0800150 }, {
151 desc: "Any field without registered type",
Damien Neilc1507ac2019-10-08 13:24:16 -0700152 resolver: new(preg.Types),
Herbie Ong66c365c2019-01-04 14:08:41 -0800153 message: func() proto.Message {
154 m := &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700155 OptString: proto.String("embedded inside Any"),
Herbie Ong66c365c2019-01-04 14:08:41 -0800156 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700157 OptString: proto.String("inception"),
Herbie Ong66c365c2019-01-04 14:08:41 -0800158 },
159 }
Herbie Ong4d1c3be2019-03-15 18:22:36 -0700160 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
Herbie Ong66c365c2019-01-04 14:08:41 -0800161 if err != nil {
162 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
163 }
164 return &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -0700165 OptAny: &anypb.Any{
Joe Tsai0fc49f82019-05-01 12:29:25 -0700166 TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
Herbie Ong66c365c2019-01-04 14:08:41 -0800167 Value: b,
168 },
169 }
170 }(),
171 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -0700172 desc: "Any field with registered type",
Joe Tsai0fc49f82019-05-01 12:29:25 -0700173 message: func() *pb2.KnownTypes {
Herbie Ong66c365c2019-01-04 14:08:41 -0800174 m := &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700175 OptString: proto.String("embedded inside Any"),
Herbie Ong66c365c2019-01-04 14:08:41 -0800176 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700177 OptString: proto.String("inception"),
Herbie Ong66c365c2019-01-04 14:08:41 -0800178 },
179 }
Herbie Ong4d1c3be2019-03-15 18:22:36 -0700180 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
Herbie Ong66c365c2019-01-04 14:08:41 -0800181 if err != nil {
182 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
183 }
184 return &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -0700185 OptAny: &anypb.Any{
Joe Tsai0fc49f82019-05-01 12:29:25 -0700186 TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
Herbie Ong66c365c2019-01-04 14:08:41 -0800187 Value: b,
188 },
189 }
190 }(),
191 }, {
192 desc: "Any field containing Any message",
Joe Tsai0fc49f82019-05-01 12:29:25 -0700193 message: func() *pb2.KnownTypes {
Herbie Ong66c365c2019-01-04 14:08:41 -0800194 m1 := &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700195 OptString: proto.String("message inside Any of another Any field"),
Herbie Ong66c365c2019-01-04 14:08:41 -0800196 }
Herbie Ong4d1c3be2019-03-15 18:22:36 -0700197 b1, err := proto.MarshalOptions{Deterministic: true}.Marshal(m1)
Herbie Ong66c365c2019-01-04 14:08:41 -0800198 if err != nil {
199 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
200 }
Joe Tsaia95b29f2019-05-16 12:47:20 -0700201 m2 := &anypb.Any{
Herbie Ong66c365c2019-01-04 14:08:41 -0800202 TypeUrl: "pb2.Nested",
203 Value: b1,
204 }
Herbie Ong4d1c3be2019-03-15 18:22:36 -0700205 b2, err := proto.MarshalOptions{Deterministic: true}.Marshal(m2)
Herbie Ong66c365c2019-01-04 14:08:41 -0800206 if err != nil {
207 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
208 }
209 return &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -0700210 OptAny: &anypb.Any{
Herbie Ong66c365c2019-01-04 14:08:41 -0800211 TypeUrl: "google.protobuf.Any",
212 Value: b2,
213 },
214 }
215 }(),
Herbie Ong800c9902018-12-06 15:28:53 -0800216 }}
217
218 for _, tt := range tests {
219 tt := tt
220 t.Run(tt.desc, func(t *testing.T) {
221 t.Parallel()
Damien Neil5c5b5312019-05-14 12:44:37 -0700222 b, err := prototext.MarshalOptions{Resolver: tt.resolver}.Marshal(tt.message)
Herbie Ong800c9902018-12-06 15:28:53 -0800223 if err != nil {
224 t.Errorf("Marshal() returned error: %v\n\n", err)
225 }
Joe Tsai0fc49f82019-05-01 12:29:25 -0700226
227 gotMessage := new(pb2.KnownTypes)
Joe Tsaicdb77732019-05-14 16:05:06 -0700228 err = prototext.UnmarshalOptions{Resolver: tt.resolver}.Unmarshal(b, gotMessage)
Herbie Ong800c9902018-12-06 15:28:53 -0800229 if err != nil {
230 t.Errorf("Unmarshal() returned error: %v\n\n", err)
231 }
Herbie Ong66c365c2019-01-04 14:08:41 -0800232
Joe Tsai8d30bbe2019-05-16 15:53:25 -0700233 if !proto.Equal(gotMessage, tt.message) {
Herbie Ong70651952018-12-13 14:19:50 -0800234 t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", gotMessage, tt.message)
235 }
Herbie Ong800c9902018-12-06 15:28:53 -0800236 })
237 }
238}