blob: 5b9ee38a70438ead312a18e0e61be16ae43a9a18 [file] [log] [blame]
Herbie Ongcddf8192018-11-28 18:25:20 -08001// Copyright 2018 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
5package textpb_test
6
7import (
Herbie Onga94f78c2019-01-03 15:39:58 -08008 "encoding/hex"
Herbie Ongcddf8192018-11-28 18:25:20 -08009 "math"
10 "strings"
11 "testing"
12
13 "github.com/golang/protobuf/v2/encoding/textpb"
Herbie Ongcddf8192018-11-28 18:25:20 -080014 "github.com/golang/protobuf/v2/internal/detrand"
Herbie Ong20a1d312018-12-11 21:08:58 -080015 "github.com/golang/protobuf/v2/internal/encoding/pack"
Herbie Ongcf253082018-12-17 17:13:07 -080016 "github.com/golang/protobuf/v2/internal/encoding/wire"
Herbie Ongcddf8192018-11-28 18:25:20 -080017 "github.com/golang/protobuf/v2/internal/scalar"
18 "github.com/golang/protobuf/v2/proto"
Herbie Ongf42b55f2019-01-02 15:46:07 -080019 preg "github.com/golang/protobuf/v2/reflect/protoregistry"
Joe Tsai4fddeba2019-03-20 18:29:32 -070020 "github.com/golang/protobuf/v2/runtime/protoiface"
Herbie Ongcddf8192018-11-28 18:25:20 -080021 "github.com/google/go-cmp/cmp"
22 "github.com/google/go-cmp/cmp/cmpopts"
23
Herbie Ong8170d692019-02-13 14:13:21 -080024 "github.com/golang/protobuf/v2/encoding/testprotos/pb2"
25 "github.com/golang/protobuf/v2/encoding/testprotos/pb3"
Joe Tsai19058432019-02-27 21:46:29 -080026 knownpb "github.com/golang/protobuf/v2/types/known"
Herbie Ongcddf8192018-11-28 18:25:20 -080027)
28
29func init() {
30 // Disable detrand to enable direct comparisons on outputs.
31 detrand.Disable()
32}
33
Herbie Ongcddf8192018-11-28 18:25:20 -080034// splitLines is a cmpopts.Option for comparing strings with line breaks.
35var splitLines = cmpopts.AcyclicTransformer("SplitLines", func(s string) []string {
36 return strings.Split(s, "\n")
37})
38
Herbie Ong800c9902018-12-06 15:28:53 -080039func pb2Enum(i int32) *pb2.Enum {
40 p := new(pb2.Enum)
41 *p = pb2.Enum(i)
42 return p
43}
44
45func pb2Enums_NestedEnum(i int32) *pb2.Enums_NestedEnum {
46 p := new(pb2.Enums_NestedEnum)
47 *p = pb2.Enums_NestedEnum(i)
48 return p
49}
50
Joe Tsai4fddeba2019-03-20 18:29:32 -070051func setExtension(m proto.Message, xd *protoiface.ExtensionDescV1, val interface{}) {
Herbie Ongcf253082018-12-17 17:13:07 -080052 knownFields := m.ProtoReflect().KnownFields()
53 extTypes := knownFields.ExtensionTypes()
Joe Tsaiafb455e2019-03-14 16:08:22 -070054 extTypes.Register(xd.Type)
Herbie Ongcf253082018-12-17 17:13:07 -080055 if val == nil {
56 return
57 }
Joe Tsaiafb455e2019-03-14 16:08:22 -070058 pval := xd.Type.ValueOf(val)
Herbie Ongcf253082018-12-17 17:13:07 -080059 knownFields.Set(wire.Number(xd.Field), pval)
60}
61
Herbie Onga94f78c2019-01-03 15:39:58 -080062// dhex decodes a hex-string and returns the bytes and panics if s is invalid.
63func dhex(s string) []byte {
64 b, err := hex.DecodeString(s)
65 if err != nil {
66 panic(err)
67 }
68 return b
69}
70
Herbie Ongcddf8192018-11-28 18:25:20 -080071func TestMarshal(t *testing.T) {
72 tests := []struct {
73 desc string
Herbie Ongf42b55f2019-01-02 15:46:07 -080074 mo textpb.MarshalOptions
Herbie Ong70651952018-12-13 14:19:50 -080075 input proto.Message
Herbie Ongcddf8192018-11-28 18:25:20 -080076 want string
Herbie Ong300cff02019-03-20 18:05:16 -070077 wantErr bool // TODO: Verify error message content.
Herbie Ongcddf8192018-11-28 18:25:20 -080078 }{{
Herbie Ong8170d692019-02-13 14:13:21 -080079 desc: "proto2 optional scalars not set",
Herbie Ong800c9902018-12-06 15:28:53 -080080 input: &pb2.Scalars{},
Herbie Ongcddf8192018-11-28 18:25:20 -080081 want: "\n",
82 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080083 desc: "proto3 scalars not set",
Herbie Ong800c9902018-12-06 15:28:53 -080084 input: &pb3.Scalars{},
Herbie Ongcddf8192018-11-28 18:25:20 -080085 want: "\n",
86 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080087 desc: "proto2 optional scalars set to zero values",
Herbie Ong800c9902018-12-06 15:28:53 -080088 input: &pb2.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -080089 OptBool: scalar.Bool(false),
90 OptInt32: scalar.Int32(0),
91 OptInt64: scalar.Int64(0),
92 OptUint32: scalar.Uint32(0),
93 OptUint64: scalar.Uint64(0),
94 OptSint32: scalar.Int32(0),
95 OptSint64: scalar.Int64(0),
96 OptFixed32: scalar.Uint32(0),
97 OptFixed64: scalar.Uint64(0),
98 OptSfixed32: scalar.Int32(0),
99 OptSfixed64: scalar.Int64(0),
100 OptFloat: scalar.Float32(0),
101 OptDouble: scalar.Float64(0),
102 OptBytes: []byte{},
103 OptString: scalar.String(""),
Herbie Ong800c9902018-12-06 15:28:53 -0800104 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800105 want: `opt_bool: false
106opt_int32: 0
107opt_int64: 0
108opt_uint32: 0
109opt_uint64: 0
110opt_sint32: 0
111opt_sint64: 0
112opt_fixed32: 0
113opt_fixed64: 0
114opt_sfixed32: 0
115opt_sfixed64: 0
116opt_float: 0
117opt_double: 0
118opt_bytes: ""
119opt_string: ""
120`,
121 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800122 desc: "proto3 scalars set to zero values",
Herbie Ong800c9902018-12-06 15:28:53 -0800123 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800124 SBool: false,
125 SInt32: 0,
126 SInt64: 0,
127 SUint32: 0,
128 SUint64: 0,
129 SSint32: 0,
130 SSint64: 0,
131 SFixed32: 0,
132 SFixed64: 0,
133 SSfixed32: 0,
134 SSfixed64: 0,
135 SFloat: 0,
136 SDouble: 0,
137 SBytes: []byte{},
138 SString: "",
Herbie Ong800c9902018-12-06 15:28:53 -0800139 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800140 want: "\n",
141 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800142 desc: "proto2 optional scalars set to some values",
Herbie Ong800c9902018-12-06 15:28:53 -0800143 input: &pb2.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800144 OptBool: scalar.Bool(true),
145 OptInt32: scalar.Int32(0xff),
146 OptInt64: scalar.Int64(0xdeadbeef),
147 OptUint32: scalar.Uint32(47),
148 OptUint64: scalar.Uint64(0xdeadbeef),
149 OptSint32: scalar.Int32(-1001),
150 OptSint64: scalar.Int64(-0xffff),
151 OptFixed64: scalar.Uint64(64),
152 OptSfixed32: scalar.Int32(-32),
Herbie Ong84f09602019-01-17 19:31:47 -0800153 OptFloat: scalar.Float32(1.02),
154 OptDouble: scalar.Float64(1.0199999809265137),
Herbie Ong8170d692019-02-13 14:13:21 -0800155 OptBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
156 OptString: scalar.String("谷歌"),
Herbie Ong800c9902018-12-06 15:28:53 -0800157 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800158 want: `opt_bool: true
159opt_int32: 255
160opt_int64: 3735928559
161opt_uint32: 47
162opt_uint64: 3735928559
163opt_sint32: -1001
164opt_sint64: -65535
165opt_fixed64: 64
166opt_sfixed32: -32
Herbie Ong84f09602019-01-17 19:31:47 -0800167opt_float: 1.02
168opt_double: 1.0199999809265137
Herbie Ongcddf8192018-11-28 18:25:20 -0800169opt_bytes: "谷歌"
170opt_string: "谷歌"
171`,
172 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800173 desc: "float nan",
Herbie Ong800c9902018-12-06 15:28:53 -0800174 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800175 SFloat: float32(math.NaN()),
Herbie Ong800c9902018-12-06 15:28:53 -0800176 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800177 want: "s_float: nan\n",
178 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800179 desc: "float positive infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800180 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800181 SFloat: float32(math.Inf(1)),
Herbie Ong800c9902018-12-06 15:28:53 -0800182 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800183 want: "s_float: inf\n",
184 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800185 desc: "float negative infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800186 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800187 SFloat: float32(math.Inf(-1)),
Herbie Ong800c9902018-12-06 15:28:53 -0800188 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800189 want: "s_float: -inf\n",
190 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800191 desc: "double nan",
Herbie Ong800c9902018-12-06 15:28:53 -0800192 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800193 SDouble: math.NaN(),
Herbie Ong800c9902018-12-06 15:28:53 -0800194 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800195 want: "s_double: nan\n",
196 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800197 desc: "double positive infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800198 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800199 SDouble: math.Inf(1),
Herbie Ong800c9902018-12-06 15:28:53 -0800200 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800201 want: "s_double: inf\n",
202 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800203 desc: "double negative infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800204 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800205 SDouble: math.Inf(-1),
Herbie Ong800c9902018-12-06 15:28:53 -0800206 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800207 want: "s_double: -inf\n",
208 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800209 desc: "proto2 enum not set",
210 input: &pb2.Enums{},
Herbie Ongcddf8192018-11-28 18:25:20 -0800211 want: "\n",
212 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800213 desc: "proto2 enum set to zero value",
214 input: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800215 OptEnum: pb2Enum(0),
Herbie Ong800c9902018-12-06 15:28:53 -0800216 OptNestedEnum: pb2Enums_NestedEnum(0),
217 },
Herbie Ong8170d692019-02-13 14:13:21 -0800218 want: `opt_enum: 0
Herbie Ong800c9902018-12-06 15:28:53 -0800219opt_nested_enum: 0
220`,
221 }, {
222 desc: "proto2 enum",
223 input: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800224 OptEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800225 OptNestedEnum: pb2.Enums_UNO.Enum(),
226 },
Herbie Ong8170d692019-02-13 14:13:21 -0800227 want: `opt_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800228opt_nested_enum: UNO
229`,
230 }, {
231 desc: "proto2 enum set to numeric values",
232 input: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800233 OptEnum: pb2Enum(2),
Herbie Ong800c9902018-12-06 15:28:53 -0800234 OptNestedEnum: pb2Enums_NestedEnum(2),
235 },
Herbie Ong8170d692019-02-13 14:13:21 -0800236 want: `opt_enum: TWO
Herbie Ong800c9902018-12-06 15:28:53 -0800237opt_nested_enum: DOS
238`,
239 }, {
240 desc: "proto2 enum set to unnamed numeric values",
241 input: &pb2.Enums{
242 OptEnum: pb2Enum(101),
243 OptNestedEnum: pb2Enums_NestedEnum(-101),
244 },
245 want: `opt_enum: 101
246opt_nested_enum: -101
247`,
248 }, {
249 desc: "proto3 enum not set",
250 input: &pb3.Enums{},
251 want: "\n",
252 }, {
253 desc: "proto3 enum set to zero value",
254 input: &pb3.Enums{
255 SEnum: pb3.Enum_ZERO,
256 SNestedEnum: pb3.Enums_CERO,
257 },
258 want: "\n",
259 }, {
260 desc: "proto3 enum",
261 input: &pb3.Enums{
262 SEnum: pb3.Enum_ONE,
Herbie Ong8170d692019-02-13 14:13:21 -0800263 SNestedEnum: pb3.Enums_UNO,
Herbie Ong800c9902018-12-06 15:28:53 -0800264 },
265 want: `s_enum: ONE
Herbie Ong8170d692019-02-13 14:13:21 -0800266s_nested_enum: UNO
Herbie Ong800c9902018-12-06 15:28:53 -0800267`,
268 }, {
269 desc: "proto3 enum set to numeric values",
270 input: &pb3.Enums{
271 SEnum: 2,
Herbie Ong8170d692019-02-13 14:13:21 -0800272 SNestedEnum: 2,
Herbie Ong800c9902018-12-06 15:28:53 -0800273 },
274 want: `s_enum: TWO
Herbie Ong8170d692019-02-13 14:13:21 -0800275s_nested_enum: DOS
Herbie Ong800c9902018-12-06 15:28:53 -0800276`,
277 }, {
278 desc: "proto3 enum set to unnamed numeric values",
279 input: &pb3.Enums{
280 SEnum: -47,
281 SNestedEnum: 47,
282 },
283 want: `s_enum: -47
284s_nested_enum: 47
285`,
286 }, {
287 desc: "proto2 nested message not set",
288 input: &pb2.Nests{},
289 want: "\n",
290 }, {
291 desc: "proto2 nested message set to empty",
292 input: &pb2.Nests{
293 OptNested: &pb2.Nested{},
294 Optgroup: &pb2.Nests_OptGroup{},
295 },
296 want: `opt_nested: {}
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800297OptGroup: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800298`,
299 }, {
300 desc: "proto2 nested messages",
301 input: &pb2.Nests{
302 OptNested: &pb2.Nested{
303 OptString: scalar.String("nested message"),
304 OptNested: &pb2.Nested{
305 OptString: scalar.String("another nested message"),
306 },
307 },
308 },
309 want: `opt_nested: {
310 opt_string: "nested message"
311 opt_nested: {
312 opt_string: "another nested message"
313 }
314}
315`,
316 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800317 desc: "proto2 groups",
Herbie Ong800c9902018-12-06 15:28:53 -0800318 input: &pb2.Nests{
319 Optgroup: &pb2.Nests_OptGroup{
Herbie Ong800c9902018-12-06 15:28:53 -0800320 OptString: scalar.String("inside a group"),
321 OptNested: &pb2.Nested{
322 OptString: scalar.String("nested message inside a group"),
323 },
324 Optnestedgroup: &pb2.Nests_OptGroup_OptNestedGroup{
Herbie Ong8170d692019-02-13 14:13:21 -0800325 OptFixed32: scalar.Uint32(47),
Herbie Ong800c9902018-12-06 15:28:53 -0800326 },
327 },
328 },
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800329 want: `OptGroup: {
Herbie Ong800c9902018-12-06 15:28:53 -0800330 opt_string: "inside a group"
331 opt_nested: {
332 opt_string: "nested message inside a group"
333 }
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800334 OptNestedGroup: {
Herbie Ong8170d692019-02-13 14:13:21 -0800335 opt_fixed32: 47
Herbie Ong800c9902018-12-06 15:28:53 -0800336 }
337}
338`,
339 }, {
340 desc: "proto3 nested message not set",
341 input: &pb3.Nests{},
342 want: "\n",
343 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800344 desc: "proto3 nested message set to empty",
345 input: &pb3.Nests{
346 SNested: &pb3.Nested{},
347 },
348 want: "s_nested: {}\n",
349 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800350 desc: "proto3 nested message",
351 input: &pb3.Nests{
352 SNested: &pb3.Nested{
353 SString: "nested message",
354 SNested: &pb3.Nested{
355 SString: "another nested message",
356 },
357 },
358 },
359 want: `s_nested: {
360 s_string: "nested message"
361 s_nested: {
362 s_string: "another nested message"
363 }
364}
365`,
366 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800367 desc: "oneof not set",
368 input: &pb3.Oneofs{},
Herbie Ong800c9902018-12-06 15:28:53 -0800369 want: "\n",
370 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800371 desc: "oneof set to empty string",
372 input: &pb3.Oneofs{
373 Union: &pb3.Oneofs_OneofString{},
Herbie Ong800c9902018-12-06 15:28:53 -0800374 },
Herbie Ong8170d692019-02-13 14:13:21 -0800375 want: `oneof_string: ""
376`,
Herbie Ong800c9902018-12-06 15:28:53 -0800377 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800378 desc: "oneof set to string",
379 input: &pb3.Oneofs{
380 Union: &pb3.Oneofs_OneofString{
381 OneofString: "hello",
Herbie Ong800c9902018-12-06 15:28:53 -0800382 },
383 },
Herbie Ong8170d692019-02-13 14:13:21 -0800384 want: `oneof_string: "hello"
385`,
Herbie Ong800c9902018-12-06 15:28:53 -0800386 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800387 desc: "oneof set to enum",
388 input: &pb3.Oneofs{
389 Union: &pb3.Oneofs_OneofEnum{
390 OneofEnum: pb3.Enum_ZERO,
Herbie Ong800c9902018-12-06 15:28:53 -0800391 },
392 },
Herbie Ong8170d692019-02-13 14:13:21 -0800393 want: `oneof_enum: ZERO
394`,
Herbie Ong800c9902018-12-06 15:28:53 -0800395 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800396 desc: "oneof set to empty message",
397 input: &pb3.Oneofs{
398 Union: &pb3.Oneofs_OneofNested{
399 OneofNested: &pb3.Nested{},
400 },
401 },
402 want: "oneof_nested: {}\n",
403 }, {
404 desc: "oneof set to message",
405 input: &pb3.Oneofs{
406 Union: &pb3.Oneofs_OneofNested{
407 OneofNested: &pb3.Nested{
408 SString: "nested message",
Herbie Ong800c9902018-12-06 15:28:53 -0800409 },
410 },
411 },
Herbie Ong8170d692019-02-13 14:13:21 -0800412 want: `oneof_nested: {
413 s_string: "nested message"
Herbie Ong800c9902018-12-06 15:28:53 -0800414}
415`,
416 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800417 desc: "repeated fields not set",
Herbie Ong800c9902018-12-06 15:28:53 -0800418 input: &pb2.Repeats{},
419 want: "\n",
420 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800421 desc: "repeated fields set to empty slices",
Herbie Ong800c9902018-12-06 15:28:53 -0800422 input: &pb2.Repeats{
Herbie Ongcddf8192018-11-28 18:25:20 -0800423 RptBool: []bool{},
424 RptInt32: []int32{},
425 RptInt64: []int64{},
426 RptUint32: []uint32{},
427 RptUint64: []uint64{},
428 RptFloat: []float32{},
429 RptDouble: []float64{},
430 RptBytes: [][]byte{},
Herbie Ong800c9902018-12-06 15:28:53 -0800431 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800432 want: "\n",
433 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800434 desc: "repeated fields set to some values",
Herbie Ong800c9902018-12-06 15:28:53 -0800435 input: &pb2.Repeats{
Herbie Ongcddf8192018-11-28 18:25:20 -0800436 RptBool: []bool{true, false, true, true},
437 RptInt32: []int32{1, 6, 0, 0},
438 RptInt64: []int64{-64, 47},
439 RptUint32: []uint32{0xff, 0xffff},
440 RptUint64: []uint64{0xdeadbeef},
Herbie Ong84f09602019-01-17 19:31:47 -0800441 RptFloat: []float32{float32(math.NaN()), float32(math.Inf(1)), float32(math.Inf(-1)), 1.034},
Herbie Ongcddf8192018-11-28 18:25:20 -0800442 RptDouble: []float64{math.NaN(), math.Inf(1), math.Inf(-1), 1.23e-308},
443 RptString: []string{"hello", "世界"},
444 RptBytes: [][]byte{
445 []byte("hello"),
446 []byte("\xe4\xb8\x96\xe7\x95\x8c"),
447 },
Herbie Ong800c9902018-12-06 15:28:53 -0800448 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800449 want: `rpt_bool: true
450rpt_bool: false
451rpt_bool: true
452rpt_bool: true
453rpt_int32: 1
454rpt_int32: 6
455rpt_int32: 0
456rpt_int32: 0
457rpt_int64: -64
458rpt_int64: 47
459rpt_uint32: 255
460rpt_uint32: 65535
461rpt_uint64: 3735928559
Herbie Ong84f09602019-01-17 19:31:47 -0800462rpt_float: nan
463rpt_float: inf
464rpt_float: -inf
465rpt_float: 1.034
Herbie Ongcddf8192018-11-28 18:25:20 -0800466rpt_double: nan
467rpt_double: inf
468rpt_double: -inf
469rpt_double: 1.23e-308
470rpt_string: "hello"
471rpt_string: "世界"
472rpt_bytes: "hello"
473rpt_bytes: "世界"
474`,
475 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800476 desc: "repeated enums",
Herbie Ong800c9902018-12-06 15:28:53 -0800477 input: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800478 RptEnum: []pb2.Enum{pb2.Enum_ONE, 2, pb2.Enum_TEN, 42},
Herbie Ongcddf8192018-11-28 18:25:20 -0800479 RptNestedEnum: []pb2.Enums_NestedEnum{2, 47, 10},
Herbie Ong800c9902018-12-06 15:28:53 -0800480 },
Herbie Ong8170d692019-02-13 14:13:21 -0800481 want: `rpt_enum: ONE
482rpt_enum: TWO
483rpt_enum: TEN
Herbie Ongcddf8192018-11-28 18:25:20 -0800484rpt_enum: 42
Herbie Ongcddf8192018-11-28 18:25:20 -0800485rpt_nested_enum: DOS
486rpt_nested_enum: 47
487rpt_nested_enum: DIEZ
488`,
489 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800490 desc: "repeated messages set to empty",
Herbie Ong800c9902018-12-06 15:28:53 -0800491 input: &pb2.Nests{
Herbie Ongcddf8192018-11-28 18:25:20 -0800492 RptNested: []*pb2.Nested{},
493 Rptgroup: []*pb2.Nests_RptGroup{},
Herbie Ong800c9902018-12-06 15:28:53 -0800494 },
495 want: "\n",
Herbie Ongcddf8192018-11-28 18:25:20 -0800496 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800497 desc: "repeated messages",
Herbie Ong800c9902018-12-06 15:28:53 -0800498 input: &pb2.Nests{
Herbie Ongcddf8192018-11-28 18:25:20 -0800499 RptNested: []*pb2.Nested{
500 {
501 OptString: scalar.String("repeat nested one"),
502 },
503 {
504 OptString: scalar.String("repeat nested two"),
505 OptNested: &pb2.Nested{
506 OptString: scalar.String("inside repeat nested two"),
507 },
508 },
509 {},
510 },
Herbie Ong800c9902018-12-06 15:28:53 -0800511 },
512 want: `rpt_nested: {
Herbie Ongcddf8192018-11-28 18:25:20 -0800513 opt_string: "repeat nested one"
514}
515rpt_nested: {
516 opt_string: "repeat nested two"
517 opt_nested: {
518 opt_string: "inside repeat nested two"
519 }
520}
521rpt_nested: {}
522`,
523 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800524 desc: "repeated messages contains nil value",
Herbie Ongf5db2df2019-02-07 20:17:45 -0800525 input: &pb2.Nests{
526 RptNested: []*pb2.Nested{nil, {}},
527 },
528 want: `rpt_nested: {}
529rpt_nested: {}
530`,
531 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800532 desc: "repeated groups",
Herbie Ong800c9902018-12-06 15:28:53 -0800533 input: &pb2.Nests{
Herbie Ongcddf8192018-11-28 18:25:20 -0800534 Rptgroup: []*pb2.Nests_RptGroup{
535 {
Herbie Ong8170d692019-02-13 14:13:21 -0800536 RptString: []string{"hello", "world"},
Herbie Ongcddf8192018-11-28 18:25:20 -0800537 },
538 {},
Herbie Ong8170d692019-02-13 14:13:21 -0800539 nil,
Herbie Ongcddf8192018-11-28 18:25:20 -0800540 },
Herbie Ong800c9902018-12-06 15:28:53 -0800541 },
Herbie Ongde7313b2019-01-14 19:26:50 -0800542 want: `RptGroup: {
Herbie Ong8170d692019-02-13 14:13:21 -0800543 rpt_string: "hello"
544 rpt_string: "world"
Herbie Ongcddf8192018-11-28 18:25:20 -0800545}
Herbie Ongde7313b2019-01-14 19:26:50 -0800546RptGroup: {}
Herbie Ong8170d692019-02-13 14:13:21 -0800547RptGroup: {}
Herbie Ongcddf8192018-11-28 18:25:20 -0800548`,
549 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800550 desc: "map fields not set",
551 input: &pb3.Maps{},
Herbie Ongcddf8192018-11-28 18:25:20 -0800552 want: "\n",
553 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800554 desc: "map fields set to empty",
555 input: &pb3.Maps{
556 Int32ToStr: map[int32]string{},
557 BoolToUint32: map[bool]uint32{},
558 Uint64ToEnum: map[uint64]pb3.Enum{},
559 StrToNested: map[string]*pb3.Nested{},
560 StrToOneofs: map[string]*pb3.Oneofs{},
Herbie Ong800c9902018-12-06 15:28:53 -0800561 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800562 want: "\n",
563 }, {
564 desc: "map fields 1",
Herbie Ong8170d692019-02-13 14:13:21 -0800565 input: &pb3.Maps{
Herbie Ongcddf8192018-11-28 18:25:20 -0800566 Int32ToStr: map[int32]string{
567 -101: "-101",
568 0xff: "0xff",
569 0: "zero",
570 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800571 BoolToUint32: map[bool]uint32{
572 true: 42,
573 false: 101,
574 },
Herbie Ong800c9902018-12-06 15:28:53 -0800575 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800576 want: `int32_to_str: {
577 key: -101
578 value: "-101"
579}
580int32_to_str: {
581 key: 0
582 value: "zero"
583}
584int32_to_str: {
585 key: 255
586 value: "0xff"
587}
Herbie Ongcddf8192018-11-28 18:25:20 -0800588bool_to_uint32: {
589 key: false
590 value: 101
591}
592bool_to_uint32: {
593 key: true
594 value: 42
595}
596`,
597 }, {
598 desc: "map fields 2",
Herbie Ong8170d692019-02-13 14:13:21 -0800599 input: &pb3.Maps{
600 Uint64ToEnum: map[uint64]pb3.Enum{
601 1: pb3.Enum_ONE,
602 2: pb3.Enum_TWO,
603 10: pb3.Enum_TEN,
604 47: 47,
Herbie Ongcddf8192018-11-28 18:25:20 -0800605 },
Herbie Ong800c9902018-12-06 15:28:53 -0800606 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800607 want: `uint64_to_enum: {
608 key: 1
Herbie Ong8170d692019-02-13 14:13:21 -0800609 value: ONE
Herbie Ongcddf8192018-11-28 18:25:20 -0800610}
611uint64_to_enum: {
612 key: 2
Herbie Ong8170d692019-02-13 14:13:21 -0800613 value: TWO
Herbie Ongcddf8192018-11-28 18:25:20 -0800614}
615uint64_to_enum: {
616 key: 10
Herbie Ong8170d692019-02-13 14:13:21 -0800617 value: TEN
618}
619uint64_to_enum: {
620 key: 47
621 value: 47
Herbie Ongcddf8192018-11-28 18:25:20 -0800622}
623`,
624 }, {
625 desc: "map fields 3",
Herbie Ong8170d692019-02-13 14:13:21 -0800626 input: &pb3.Maps{
627 StrToNested: map[string]*pb3.Nested{
628 "nested": &pb3.Nested{
629 SString: "nested in a map",
Herbie Ongcddf8192018-11-28 18:25:20 -0800630 },
631 },
Herbie Ong800c9902018-12-06 15:28:53 -0800632 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800633 want: `str_to_nested: {
Herbie Ong8170d692019-02-13 14:13:21 -0800634 key: "nested"
Herbie Ongcddf8192018-11-28 18:25:20 -0800635 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800636 s_string: "nested in a map"
Herbie Ongcddf8192018-11-28 18:25:20 -0800637 }
638}
639`,
640 }, {
641 desc: "map fields 4",
Herbie Ong8170d692019-02-13 14:13:21 -0800642 input: &pb3.Maps{
643 StrToOneofs: map[string]*pb3.Oneofs{
644 "string": &pb3.Oneofs{
645 Union: &pb3.Oneofs_OneofString{
646 OneofString: "hello",
Herbie Ongcddf8192018-11-28 18:25:20 -0800647 },
648 },
Herbie Ong8170d692019-02-13 14:13:21 -0800649 "nested": &pb3.Oneofs{
650 Union: &pb3.Oneofs_OneofNested{
651 OneofNested: &pb3.Nested{
652 SString: "nested oneof in map field value",
Herbie Ongcddf8192018-11-28 18:25:20 -0800653 },
654 },
655 },
656 },
Herbie Ong800c9902018-12-06 15:28:53 -0800657 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800658 want: `str_to_oneofs: {
659 key: "nested"
660 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800661 oneof_nested: {
662 s_string: "nested oneof in map field value"
Herbie Ongcddf8192018-11-28 18:25:20 -0800663 }
664 }
665}
666str_to_oneofs: {
667 key: "string"
668 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800669 oneof_string: "hello"
Herbie Ongcddf8192018-11-28 18:25:20 -0800670 }
671}
672`,
673 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800674 desc: "map field contains nil value",
675 input: &pb3.Maps{
676 StrToNested: map[string]*pb3.Nested{
Herbie Ongf5db2df2019-02-07 20:17:45 -0800677 "nil": nil,
678 },
679 },
680 want: `str_to_nested: {
681 key: "nil"
682 value: {}
683}
684`,
685 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700686 desc: "required fields not set",
Herbie Ong800c9902018-12-06 15:28:53 -0800687 input: &pb2.Requireds{},
688 want: "\n",
689 wantErr: true,
Herbie Ongcddf8192018-11-28 18:25:20 -0800690 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700691 desc: "required fields partially set",
Herbie Ong800c9902018-12-06 15:28:53 -0800692 input: &pb2.Requireds{
693 ReqBool: scalar.Bool(false),
Herbie Ong800c9902018-12-06 15:28:53 -0800694 ReqSfixed64: scalar.Int64(0xbeefcafe),
695 ReqDouble: scalar.Float64(math.NaN()),
696 ReqString: scalar.String("hello"),
Herbie Ong8170d692019-02-13 14:13:21 -0800697 ReqEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800698 },
699 want: `req_bool: false
Herbie Ong800c9902018-12-06 15:28:53 -0800700req_sfixed64: 3203386110
701req_double: nan
702req_string: "hello"
Herbie Ong8170d692019-02-13 14:13:21 -0800703req_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800704`,
705 wantErr: true,
706 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700707 desc: "required fields not set with AllowPartial",
708 mo: textpb.MarshalOptions{AllowPartial: true},
709 input: &pb2.Requireds{
710 ReqBool: scalar.Bool(false),
711 ReqSfixed64: scalar.Int64(0xbeefcafe),
712 ReqDouble: scalar.Float64(math.NaN()),
713 ReqString: scalar.String("hello"),
714 ReqEnum: pb2.Enum_ONE.Enum(),
715 },
716 want: `req_bool: false
717req_sfixed64: 3203386110
718req_double: nan
719req_string: "hello"
720req_enum: ONE
721`,
722 }, {
723 desc: "required fields all set",
Herbie Ong800c9902018-12-06 15:28:53 -0800724 input: &pb2.Requireds{
725 ReqBool: scalar.Bool(false),
Herbie Ong800c9902018-12-06 15:28:53 -0800726 ReqSfixed64: scalar.Int64(0),
Herbie Ong8170d692019-02-13 14:13:21 -0800727 ReqDouble: scalar.Float64(1.23),
Herbie Ong800c9902018-12-06 15:28:53 -0800728 ReqString: scalar.String(""),
Herbie Ong8170d692019-02-13 14:13:21 -0800729 ReqEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800730 ReqNested: &pb2.Nested{},
731 },
732 want: `req_bool: false
Herbie Ong800c9902018-12-06 15:28:53 -0800733req_sfixed64: 0
Herbie Ong8170d692019-02-13 14:13:21 -0800734req_double: 1.23
Herbie Ong800c9902018-12-06 15:28:53 -0800735req_string: ""
Herbie Ong8170d692019-02-13 14:13:21 -0800736req_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800737req_nested: {}
Herbie Ongcddf8192018-11-28 18:25:20 -0800738`,
739 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800740 desc: "indirect required field",
741 input: &pb2.IndirectRequired{
742 OptNested: &pb2.NestedWithRequired{},
743 },
744 want: "opt_nested: {}\n",
745 wantErr: true,
Herbie Ongcddf8192018-11-28 18:25:20 -0800746 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700747 desc: "indirect required field with AllowPartial",
748 mo: textpb.MarshalOptions{AllowPartial: true},
749 input: &pb2.IndirectRequired{
750 OptNested: &pb2.NestedWithRequired{},
751 },
752 want: "opt_nested: {}\n",
753 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800754 desc: "indirect required field in empty repeated",
755 input: &pb2.IndirectRequired{
756 RptNested: []*pb2.NestedWithRequired{},
757 },
758 want: "\n",
Herbie Ongcddf8192018-11-28 18:25:20 -0800759 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800760 desc: "indirect required field in repeated",
761 input: &pb2.IndirectRequired{
762 RptNested: []*pb2.NestedWithRequired{
763 &pb2.NestedWithRequired{},
Herbie Ongcddf8192018-11-28 18:25:20 -0800764 },
Herbie Ong800c9902018-12-06 15:28:53 -0800765 },
766 want: "rpt_nested: {}\n",
767 wantErr: true,
768 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700769 desc: "indirect required field in repeated with AllowPartial",
770 mo: textpb.MarshalOptions{AllowPartial: true},
771 input: &pb2.IndirectRequired{
772 RptNested: []*pb2.NestedWithRequired{
773 &pb2.NestedWithRequired{},
774 },
775 },
776 want: "rpt_nested: {}\n",
777 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800778 desc: "indirect required field in empty map",
779 input: &pb2.IndirectRequired{
780 StrToNested: map[string]*pb2.NestedWithRequired{},
781 },
782 want: "\n",
783 }, {
784 desc: "indirect required field in map",
785 input: &pb2.IndirectRequired{
786 StrToNested: map[string]*pb2.NestedWithRequired{
787 "fail": &pb2.NestedWithRequired{},
788 },
789 },
790 want: `str_to_nested: {
791 key: "fail"
792 value: {}
Herbie Ongcddf8192018-11-28 18:25:20 -0800793}
794`,
Herbie Ong800c9902018-12-06 15:28:53 -0800795 wantErr: true,
Herbie Ong20a1d312018-12-11 21:08:58 -0800796 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700797 desc: "indirect required field in map with AllowPartial",
798 mo: textpb.MarshalOptions{AllowPartial: true},
799 input: &pb2.IndirectRequired{
800 StrToNested: map[string]*pb2.NestedWithRequired{
801 "fail": &pb2.NestedWithRequired{},
802 },
803 },
804 want: `str_to_nested: {
805 key: "fail"
806 value: {}
807}
808`,
809 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800810 desc: "indirect required field in oneof",
811 input: &pb2.IndirectRequired{
812 Union: &pb2.IndirectRequired_OneofNested{
813 OneofNested: &pb2.NestedWithRequired{},
814 },
815 },
816 want: "oneof_nested: {}\n",
817 wantErr: true,
818 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700819 desc: "indirect required field in oneof with AllowPartial",
820 mo: textpb.MarshalOptions{AllowPartial: true},
821 input: &pb2.IndirectRequired{
822 Union: &pb2.IndirectRequired_OneofNested{
823 OneofNested: &pb2.NestedWithRequired{},
824 },
825 },
826 want: "oneof_nested: {}\n",
827 }, {
Herbie Ong20a1d312018-12-11 21:08:58 -0800828 desc: "unknown varint and fixed types",
829 input: &pb2.Scalars{
830 OptString: scalar.String("this message contains unknown fields"),
831 XXX_unrecognized: pack.Message{
832 pack.Tag{101, pack.VarintType}, pack.Bool(true),
833 pack.Tag{102, pack.VarintType}, pack.Varint(0xff),
834 pack.Tag{103, pack.Fixed32Type}, pack.Uint32(47),
835 pack.Tag{104, pack.Fixed64Type}, pack.Int64(0xdeadbeef),
836 }.Marshal(),
837 },
838 want: `opt_string: "this message contains unknown fields"
839101: 1
840102: 255
841103: 47
842104: 3735928559
843`,
844 }, {
845 desc: "unknown length-delimited",
846 input: &pb2.Scalars{
847 XXX_unrecognized: pack.Message{
848 pack.Tag{101, pack.BytesType}, pack.LengthPrefix{pack.Bool(true), pack.Bool(false)},
849 pack.Tag{102, pack.BytesType}, pack.String("hello world"),
850 pack.Tag{103, pack.BytesType}, pack.Bytes("\xe4\xb8\x96\xe7\x95\x8c"),
851 }.Marshal(),
852 },
853 want: `101: "\x01\x00"
854102: "hello world"
855103: "世界"
856`,
857 }, {
858 desc: "unknown group type",
859 input: &pb2.Scalars{
860 XXX_unrecognized: pack.Message{
861 pack.Tag{101, pack.StartGroupType}, pack.Tag{101, pack.EndGroupType},
862 pack.Tag{102, pack.StartGroupType},
863 pack.Tag{101, pack.VarintType}, pack.Bool(false),
864 pack.Tag{102, pack.BytesType}, pack.String("inside a group"),
865 pack.Tag{102, pack.EndGroupType},
866 }.Marshal(),
867 },
868 want: `101: {}
869102: {
870 101: 0
871 102: "inside a group"
872}
873`,
874 }, {
875 desc: "unknown unpack repeated field",
876 input: &pb2.Scalars{
877 XXX_unrecognized: pack.Message{
878 pack.Tag{101, pack.BytesType}, pack.LengthPrefix{pack.Bool(true), pack.Bool(false), pack.Bool(true)},
879 pack.Tag{102, pack.BytesType}, pack.String("hello"),
880 pack.Tag{101, pack.VarintType}, pack.Bool(true),
881 pack.Tag{102, pack.BytesType}, pack.String("世界"),
882 }.Marshal(),
883 },
884 want: `101: "\x01\x00\x01"
885101: 1
886102: "hello"
887102: "世界"
888`,
Herbie Ongcf253082018-12-17 17:13:07 -0800889 }, {
890 desc: "extensions of non-repeated fields",
891 input: func() proto.Message {
892 m := &pb2.Extensions{
893 OptString: scalar.String("non-extension field"),
894 OptBool: scalar.Bool(true),
895 OptInt32: scalar.Int32(42),
896 }
897 setExtension(m, pb2.E_OptExtBool, true)
898 setExtension(m, pb2.E_OptExtString, "extension field")
Herbie Ong8170d692019-02-13 14:13:21 -0800899 setExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
Herbie Ongcf253082018-12-17 17:13:07 -0800900 setExtension(m, pb2.E_OptExtNested, &pb2.Nested{
901 OptString: scalar.String("nested in an extension"),
902 OptNested: &pb2.Nested{
903 OptString: scalar.String("another nested in an extension"),
904 },
905 })
906 return m
907 }(),
908 want: `opt_string: "non-extension field"
909opt_bool: true
910opt_int32: 42
911[pb2.opt_ext_bool]: true
Herbie Ong8170d692019-02-13 14:13:21 -0800912[pb2.opt_ext_enum]: TEN
Herbie Ongcf253082018-12-17 17:13:07 -0800913[pb2.opt_ext_nested]: {
914 opt_string: "nested in an extension"
915 opt_nested: {
916 opt_string: "another nested in an extension"
917 }
918}
919[pb2.opt_ext_string]: "extension field"
920`,
921 }, {
Herbie Ong09b28a92019-04-03 15:42:41 -0700922 desc: "extension partial returns error",
923 input: func() proto.Message {
924 m := &pb2.Extensions{}
925 setExtension(m, pb2.E_OptExtPartial, &pb2.PartialRequired{
926 OptString: scalar.String("partial1"),
927 })
928 setExtension(m, pb2.E_ExtensionsContainer_OptExtPartial, &pb2.PartialRequired{
929 OptString: scalar.String("partial2"),
930 })
931 return m
932 }(),
933 want: `[pb2.ExtensionsContainer.opt_ext_partial]: {
934 opt_string: "partial2"
935}
936[pb2.opt_ext_partial]: {
937 opt_string: "partial1"
938}
939`,
940 wantErr: true,
941 }, {
942 desc: "extension partial with AllowPartial",
943 mo: textpb.MarshalOptions{AllowPartial: true},
944 input: func() proto.Message {
945 m := &pb2.Extensions{}
946 setExtension(m, pb2.E_OptExtPartial, &pb2.PartialRequired{
947 OptString: scalar.String("partial1"),
948 })
949 return m
950 }(),
951 want: `[pb2.opt_ext_partial]: {
952 opt_string: "partial1"
953}
954`,
955 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800956 desc: "extension message field set to nil",
Herbie Ongcf253082018-12-17 17:13:07 -0800957 input: func() proto.Message {
958 m := &pb2.Extensions{}
959 setExtension(m, pb2.E_OptExtNested, nil)
960 return m
961 }(),
962 want: "\n",
963 }, {
964 desc: "extensions of repeated fields",
965 input: func() proto.Message {
966 m := &pb2.Extensions{}
Herbie Ong8170d692019-02-13 14:13:21 -0800967 setExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
Herbie Ongcf253082018-12-17 17:13:07 -0800968 setExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
969 setExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
970 &pb2.Nested{OptString: scalar.String("one")},
971 &pb2.Nested{OptString: scalar.String("two")},
972 &pb2.Nested{OptString: scalar.String("three")},
973 })
974 return m
975 }(),
Herbie Ong8170d692019-02-13 14:13:21 -0800976 want: `[pb2.rpt_ext_enum]: TEN
Herbie Ongcf253082018-12-17 17:13:07 -0800977[pb2.rpt_ext_enum]: 101
Herbie Ong8170d692019-02-13 14:13:21 -0800978[pb2.rpt_ext_enum]: ONE
Herbie Ongcf253082018-12-17 17:13:07 -0800979[pb2.rpt_ext_fixed32]: 42
980[pb2.rpt_ext_fixed32]: 47
981[pb2.rpt_ext_nested]: {
982 opt_string: "one"
983}
984[pb2.rpt_ext_nested]: {
985 opt_string: "two"
986}
987[pb2.rpt_ext_nested]: {
988 opt_string: "three"
989}
990`,
991 }, {
992 desc: "extensions of non-repeated fields in another message",
993 input: func() proto.Message {
994 m := &pb2.Extensions{}
995 setExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
996 setExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
Herbie Ong8170d692019-02-13 14:13:21 -0800997 setExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
Herbie Ongcf253082018-12-17 17:13:07 -0800998 setExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
999 OptString: scalar.String("nested in an extension"),
1000 OptNested: &pb2.Nested{
1001 OptString: scalar.String("another nested in an extension"),
1002 },
1003 })
1004 return m
1005 }(),
1006 want: `[pb2.ExtensionsContainer.opt_ext_bool]: true
Herbie Ong8170d692019-02-13 14:13:21 -08001007[pb2.ExtensionsContainer.opt_ext_enum]: TEN
Herbie Ongcf253082018-12-17 17:13:07 -08001008[pb2.ExtensionsContainer.opt_ext_nested]: {
1009 opt_string: "nested in an extension"
1010 opt_nested: {
1011 opt_string: "another nested in an extension"
1012 }
1013}
1014[pb2.ExtensionsContainer.opt_ext_string]: "extension field"
1015`,
1016 }, {
1017 desc: "extensions of repeated fields in another message",
1018 input: func() proto.Message {
1019 m := &pb2.Extensions{
1020 OptString: scalar.String("non-extension field"),
1021 OptBool: scalar.Bool(true),
1022 OptInt32: scalar.Int32(42),
1023 }
Herbie Ong8170d692019-02-13 14:13:21 -08001024 setExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
Herbie Ongcf253082018-12-17 17:13:07 -08001025 setExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
1026 setExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
1027 &pb2.Nested{OptString: scalar.String("one")},
1028 &pb2.Nested{OptString: scalar.String("two")},
1029 &pb2.Nested{OptString: scalar.String("three")},
1030 })
1031 return m
1032 }(),
1033 want: `opt_string: "non-extension field"
1034opt_bool: true
1035opt_int32: 42
Herbie Ong8170d692019-02-13 14:13:21 -08001036[pb2.ExtensionsContainer.rpt_ext_enum]: TEN
Herbie Ongcf253082018-12-17 17:13:07 -08001037[pb2.ExtensionsContainer.rpt_ext_enum]: 101
Herbie Ong8170d692019-02-13 14:13:21 -08001038[pb2.ExtensionsContainer.rpt_ext_enum]: ONE
Herbie Ongcf253082018-12-17 17:13:07 -08001039[pb2.ExtensionsContainer.rpt_ext_nested]: {
1040 opt_string: "one"
1041}
1042[pb2.ExtensionsContainer.rpt_ext_nested]: {
1043 opt_string: "two"
1044}
1045[pb2.ExtensionsContainer.rpt_ext_nested]: {
1046 opt_string: "three"
1047}
1048[pb2.ExtensionsContainer.rpt_ext_string]: "hello"
1049[pb2.ExtensionsContainer.rpt_ext_string]: "world"
1050`,
Herbie Ong6470ea62019-01-07 18:56:57 -08001051 }, {
1052 desc: "MessageSet",
1053 input: func() proto.Message {
1054 m := &pb2.MessageSet{}
1055 setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
1056 OptString: scalar.String("a messageset extension"),
1057 })
1058 setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
1059 OptString: scalar.String("not a messageset extension"),
1060 })
1061 setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
1062 OptString: scalar.String("just a regular extension"),
1063 })
1064 return m
1065 }(),
1066 want: `[pb2.MessageSetExtension]: {
1067 opt_string: "a messageset extension"
1068}
1069[pb2.MessageSetExtension.ext_nested]: {
1070 opt_string: "just a regular extension"
1071}
1072[pb2.MessageSetExtension.not_message_set_extension]: {
1073 opt_string: "not a messageset extension"
1074}
1075`,
1076 }, {
1077 desc: "not real MessageSet 1",
1078 input: func() proto.Message {
1079 m := &pb2.FakeMessageSet{}
1080 setExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
1081 OptString: scalar.String("not a messageset extension"),
1082 })
1083 return m
1084 }(),
1085 want: `[pb2.FakeMessageSetExtension.message_set_extension]: {
1086 opt_string: "not a messageset extension"
1087}
1088`,
1089 }, {
1090 desc: "not real MessageSet 2",
1091 input: func() proto.Message {
1092 m := &pb2.MessageSet{}
1093 setExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
1094 OptString: scalar.String("another not a messageset extension"),
1095 })
1096 return m
1097 }(),
1098 want: `[pb2.message_set_extension]: {
1099 opt_string: "another not a messageset extension"
1100}
1101`,
Herbie Ongf42b55f2019-01-02 15:46:07 -08001102 }, {
Herbie Ong8170d692019-02-13 14:13:21 -08001103 desc: "Any not expanded",
Herbie Ong66c365c2019-01-04 14:08:41 -08001104 mo: textpb.MarshalOptions{
1105 Resolver: preg.NewTypes(),
1106 },
Herbie Ongf42b55f2019-01-02 15:46:07 -08001107 input: func() proto.Message {
1108 m := &pb2.Nested{
1109 OptString: scalar.String("embedded inside Any"),
1110 OptNested: &pb2.Nested{
1111 OptString: scalar.String("inception"),
1112 },
1113 }
Herbie Ong4d1c3be2019-03-15 18:22:36 -07001114 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
Herbie Ongf42b55f2019-01-02 15:46:07 -08001115 if err != nil {
1116 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1117 }
Herbie Ong300cff02019-03-20 18:05:16 -07001118 return &knownpb.Any{
Herbie Ong66c365c2019-01-04 14:08:41 -08001119 TypeUrl: "pb2.Nested",
Herbie Ongf42b55f2019-01-02 15:46:07 -08001120 Value: b,
Herbie Ong300cff02019-03-20 18:05:16 -07001121 }
Herbie Ongf42b55f2019-01-02 15:46:07 -08001122 }(),
1123 want: `type_url: "pb2.Nested"
1124value: "\n\x13embedded inside Any\x12\x0b\n\tinception"
1125`,
1126 }, {
Herbie Ong8170d692019-02-13 14:13:21 -08001127 desc: "Any expanded",
Herbie Ong66c365c2019-01-04 14:08:41 -08001128 mo: textpb.MarshalOptions{
1129 Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
1130 },
Herbie Ongf42b55f2019-01-02 15:46:07 -08001131 input: func() proto.Message {
1132 m := &pb2.Nested{
1133 OptString: scalar.String("embedded inside Any"),
1134 OptNested: &pb2.Nested{
1135 OptString: scalar.String("inception"),
1136 },
1137 }
Herbie Ong4d1c3be2019-03-15 18:22:36 -07001138 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
Herbie Ongf42b55f2019-01-02 15:46:07 -08001139 if err != nil {
1140 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1141 }
Herbie Ong300cff02019-03-20 18:05:16 -07001142 return &knownpb.Any{
Herbie Ong66c365c2019-01-04 14:08:41 -08001143 TypeUrl: "foo/pb2.Nested",
Herbie Ongf42b55f2019-01-02 15:46:07 -08001144 Value: b,
Herbie Ong300cff02019-03-20 18:05:16 -07001145 }
Herbie Ongf42b55f2019-01-02 15:46:07 -08001146 }(),
Herbie Ong66c365c2019-01-04 14:08:41 -08001147 want: `[foo/pb2.Nested]: {
Herbie Ongf42b55f2019-01-02 15:46:07 -08001148 opt_string: "embedded inside Any"
1149 opt_nested: {
1150 opt_string: "inception"
1151 }
1152}
1153`,
1154 }, {
Herbie Ong8170d692019-02-13 14:13:21 -08001155 desc: "Any expanded with missing required error",
Herbie Ong66c365c2019-01-04 14:08:41 -08001156 mo: textpb.MarshalOptions{
1157 Resolver: preg.NewTypes((&pb2.PartialRequired{}).ProtoReflect().Type()),
1158 },
Herbie Ongf42b55f2019-01-02 15:46:07 -08001159 input: func() proto.Message {
1160 m := &pb2.PartialRequired{
1161 OptString: scalar.String("embedded inside Any"),
1162 }
Damien Neil96c229a2019-04-03 12:17:24 -07001163 b, err := proto.MarshalOptions{
1164 AllowPartial: true,
1165 Deterministic: true,
1166 }.Marshal(m)
Herbie Ong300cff02019-03-20 18:05:16 -07001167 if err != nil {
Herbie Ongf42b55f2019-01-02 15:46:07 -08001168 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1169 }
Herbie Ong300cff02019-03-20 18:05:16 -07001170 return &knownpb.Any{
Herbie Ongf42b55f2019-01-02 15:46:07 -08001171 TypeUrl: string(m.ProtoReflect().Type().FullName()),
1172 Value: b,
Herbie Ong300cff02019-03-20 18:05:16 -07001173 }
Herbie Ongf42b55f2019-01-02 15:46:07 -08001174 }(),
1175 want: `[pb2.PartialRequired]: {
1176 opt_string: "embedded inside Any"
1177}
1178`,
1179 wantErr: true,
1180 }, {
Herbie Ong8170d692019-02-13 14:13:21 -08001181 desc: "Any with invalid value",
Herbie Ong66c365c2019-01-04 14:08:41 -08001182 mo: textpb.MarshalOptions{
1183 Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
1184 },
Herbie Ong300cff02019-03-20 18:05:16 -07001185 input: &knownpb.Any{
Herbie Ong66c365c2019-01-04 14:08:41 -08001186 TypeUrl: "foo/pb2.Nested",
1187 Value: dhex("80"),
Herbie Ong300cff02019-03-20 18:05:16 -07001188 },
Herbie Ong66c365c2019-01-04 14:08:41 -08001189 want: `type_url: "foo/pb2.Nested"
Herbie Onga94f78c2019-01-03 15:39:58 -08001190value: "\x80"
1191`,
Herbie Ongcddf8192018-11-28 18:25:20 -08001192 }}
1193
1194 for _, tt := range tests {
1195 tt := tt
1196 t.Run(tt.desc, func(t *testing.T) {
Herbie Ong3a385912019-03-20 14:04:24 -07001197 // Use 2-space indentation on all MarshalOptions.
1198 tt.mo.Indent = " "
Herbie Ongf42b55f2019-01-02 15:46:07 -08001199 b, err := tt.mo.Marshal(tt.input)
Herbie Ongcddf8192018-11-28 18:25:20 -08001200 if err != nil && !tt.wantErr {
Herbie Ongf42b55f2019-01-02 15:46:07 -08001201 t.Errorf("Marshal() returned error: %v\n", err)
Herbie Ongcddf8192018-11-28 18:25:20 -08001202 }
Herbie Ong800c9902018-12-06 15:28:53 -08001203 if err == nil && tt.wantErr {
Herbie Ongf42b55f2019-01-02 15:46:07 -08001204 t.Error("Marshal() got nil error, want error\n")
Herbie Ongcddf8192018-11-28 18:25:20 -08001205 }
Herbie Ong800c9902018-12-06 15:28:53 -08001206 got := string(b)
1207 if tt.want != "" && got != tt.want {
1208 t.Errorf("Marshal()\n<got>\n%v\n<want>\n%v\n", got, tt.want)
1209 if diff := cmp.Diff(tt.want, got, splitLines); diff != "" {
Herbie Ongcddf8192018-11-28 18:25:20 -08001210 t.Errorf("Marshal() diff -want +got\n%v\n", diff)
1211 }
1212 }
1213 })
1214 }
1215}