blob: 36a26483a1ef67de771c04bb4d1ee68a809de035 [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
Herbie Ongf42b55f2019-01-02 15:46:07 -080013 protoV1 "github.com/golang/protobuf/proto"
Herbie Ongcf253082018-12-17 17:13:07 -080014 "github.com/golang/protobuf/protoapi"
Herbie Ongcddf8192018-11-28 18:25:20 -080015 "github.com/golang/protobuf/v2/encoding/textpb"
Herbie Ongcddf8192018-11-28 18:25:20 -080016 "github.com/golang/protobuf/v2/internal/detrand"
Herbie Ong20a1d312018-12-11 21:08:58 -080017 "github.com/golang/protobuf/v2/internal/encoding/pack"
Herbie Ongcf253082018-12-17 17:13:07 -080018 "github.com/golang/protobuf/v2/internal/encoding/wire"
Herbie Ongf42b55f2019-01-02 15:46:07 -080019 "github.com/golang/protobuf/v2/internal/impl"
Herbie Ongcf253082018-12-17 17:13:07 -080020 "github.com/golang/protobuf/v2/internal/legacy"
Herbie Ongcddf8192018-11-28 18:25:20 -080021 "github.com/golang/protobuf/v2/internal/scalar"
22 "github.com/golang/protobuf/v2/proto"
Herbie Ongf42b55f2019-01-02 15:46:07 -080023 preg "github.com/golang/protobuf/v2/reflect/protoregistry"
Herbie Ongcddf8192018-11-28 18:25:20 -080024 "github.com/google/go-cmp/cmp"
25 "github.com/google/go-cmp/cmp/cmpopts"
26
Joe Tsai08e00302018-11-26 22:32:06 -080027 // The legacy package must be imported prior to use of any legacy messages.
28 // TODO: Remove this when protoV1 registers these hooks for you.
29 _ "github.com/golang/protobuf/v2/internal/legacy"
30
Herbie Ongf42b55f2019-01-02 15:46:07 -080031 anypb "github.com/golang/protobuf/ptypes/any"
Herbie Ong8170d692019-02-13 14:13:21 -080032 "github.com/golang/protobuf/v2/encoding/testprotos/pb2"
33 "github.com/golang/protobuf/v2/encoding/testprotos/pb3"
Herbie Ongcddf8192018-11-28 18:25:20 -080034)
35
36func init() {
37 // Disable detrand to enable direct comparisons on outputs.
38 detrand.Disable()
39}
40
Herbie Ongcddf8192018-11-28 18:25:20 -080041// splitLines is a cmpopts.Option for comparing strings with line breaks.
42var splitLines = cmpopts.AcyclicTransformer("SplitLines", func(s string) []string {
43 return strings.Split(s, "\n")
44})
45
Herbie Ong800c9902018-12-06 15:28:53 -080046func pb2Enum(i int32) *pb2.Enum {
47 p := new(pb2.Enum)
48 *p = pb2.Enum(i)
49 return p
50}
51
52func pb2Enums_NestedEnum(i int32) *pb2.Enums_NestedEnum {
53 p := new(pb2.Enums_NestedEnum)
54 *p = pb2.Enums_NestedEnum(i)
55 return p
56}
57
Herbie Ongcf253082018-12-17 17:13:07 -080058func setExtension(m proto.Message, xd *protoapi.ExtensionDesc, val interface{}) {
59 xt := legacy.Export{}.ExtensionTypeFromDesc(xd)
60 knownFields := m.ProtoReflect().KnownFields()
61 extTypes := knownFields.ExtensionTypes()
62 extTypes.Register(xt)
63 if val == nil {
64 return
65 }
66 pval := xt.ValueOf(val)
67 knownFields.Set(wire.Number(xd.Field), pval)
68}
69
Herbie Ong8170d692019-02-13 14:13:21 -080070func wrapV1Message(any *anypb.Any) proto.Message {
Herbie Ong66c365c2019-01-04 14:08:41 -080071 return impl.Export{}.MessageOf(any).Interface()
72}
73
Herbie Onga94f78c2019-01-03 15:39:58 -080074// dhex decodes a hex-string and returns the bytes and panics if s is invalid.
75func dhex(s string) []byte {
76 b, err := hex.DecodeString(s)
77 if err != nil {
78 panic(err)
79 }
80 return b
81}
82
Herbie Ongcddf8192018-11-28 18:25:20 -080083func TestMarshal(t *testing.T) {
84 tests := []struct {
85 desc string
Herbie Ongf42b55f2019-01-02 15:46:07 -080086 mo textpb.MarshalOptions
Herbie Ong70651952018-12-13 14:19:50 -080087 input proto.Message
Herbie Ongcddf8192018-11-28 18:25:20 -080088 want string
89 wantErr bool
90 }{{
Herbie Ong8170d692019-02-13 14:13:21 -080091 desc: "proto2 optional scalars not set",
Herbie Ong800c9902018-12-06 15:28:53 -080092 input: &pb2.Scalars{},
Herbie Ongcddf8192018-11-28 18:25:20 -080093 want: "\n",
94 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080095 desc: "proto3 scalars not set",
Herbie Ong800c9902018-12-06 15:28:53 -080096 input: &pb3.Scalars{},
Herbie Ongcddf8192018-11-28 18:25:20 -080097 want: "\n",
98 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080099 desc: "proto2 optional scalars set to zero values",
Herbie Ong800c9902018-12-06 15:28:53 -0800100 input: &pb2.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800101 OptBool: scalar.Bool(false),
102 OptInt32: scalar.Int32(0),
103 OptInt64: scalar.Int64(0),
104 OptUint32: scalar.Uint32(0),
105 OptUint64: scalar.Uint64(0),
106 OptSint32: scalar.Int32(0),
107 OptSint64: scalar.Int64(0),
108 OptFixed32: scalar.Uint32(0),
109 OptFixed64: scalar.Uint64(0),
110 OptSfixed32: scalar.Int32(0),
111 OptSfixed64: scalar.Int64(0),
112 OptFloat: scalar.Float32(0),
113 OptDouble: scalar.Float64(0),
114 OptBytes: []byte{},
115 OptString: scalar.String(""),
Herbie Ong800c9902018-12-06 15:28:53 -0800116 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800117 want: `opt_bool: false
118opt_int32: 0
119opt_int64: 0
120opt_uint32: 0
121opt_uint64: 0
122opt_sint32: 0
123opt_sint64: 0
124opt_fixed32: 0
125opt_fixed64: 0
126opt_sfixed32: 0
127opt_sfixed64: 0
128opt_float: 0
129opt_double: 0
130opt_bytes: ""
131opt_string: ""
132`,
133 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800134 desc: "proto3 scalars set to zero values",
Herbie Ong800c9902018-12-06 15:28:53 -0800135 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800136 SBool: false,
137 SInt32: 0,
138 SInt64: 0,
139 SUint32: 0,
140 SUint64: 0,
141 SSint32: 0,
142 SSint64: 0,
143 SFixed32: 0,
144 SFixed64: 0,
145 SSfixed32: 0,
146 SSfixed64: 0,
147 SFloat: 0,
148 SDouble: 0,
149 SBytes: []byte{},
150 SString: "",
Herbie Ong800c9902018-12-06 15:28:53 -0800151 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800152 want: "\n",
153 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800154 desc: "proto2 optional scalars set to some values",
Herbie Ong800c9902018-12-06 15:28:53 -0800155 input: &pb2.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800156 OptBool: scalar.Bool(true),
157 OptInt32: scalar.Int32(0xff),
158 OptInt64: scalar.Int64(0xdeadbeef),
159 OptUint32: scalar.Uint32(47),
160 OptUint64: scalar.Uint64(0xdeadbeef),
161 OptSint32: scalar.Int32(-1001),
162 OptSint64: scalar.Int64(-0xffff),
163 OptFixed64: scalar.Uint64(64),
164 OptSfixed32: scalar.Int32(-32),
Herbie Ong84f09602019-01-17 19:31:47 -0800165 OptFloat: scalar.Float32(1.02),
166 OptDouble: scalar.Float64(1.0199999809265137),
Herbie Ong8170d692019-02-13 14:13:21 -0800167 OptBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
168 OptString: scalar.String("谷歌"),
Herbie Ong800c9902018-12-06 15:28:53 -0800169 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800170 want: `opt_bool: true
171opt_int32: 255
172opt_int64: 3735928559
173opt_uint32: 47
174opt_uint64: 3735928559
175opt_sint32: -1001
176opt_sint64: -65535
177opt_fixed64: 64
178opt_sfixed32: -32
Herbie Ong84f09602019-01-17 19:31:47 -0800179opt_float: 1.02
180opt_double: 1.0199999809265137
Herbie Ongcddf8192018-11-28 18:25:20 -0800181opt_bytes: "谷歌"
182opt_string: "谷歌"
183`,
184 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800185 desc: "float nan",
Herbie Ong800c9902018-12-06 15:28:53 -0800186 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800187 SFloat: float32(math.NaN()),
Herbie Ong800c9902018-12-06 15:28:53 -0800188 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800189 want: "s_float: nan\n",
190 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800191 desc: "float positive infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800192 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800193 SFloat: float32(math.Inf(1)),
Herbie Ong800c9902018-12-06 15:28:53 -0800194 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800195 want: "s_float: inf\n",
196 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800197 desc: "float negative infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800198 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800199 SFloat: float32(math.Inf(-1)),
Herbie Ong800c9902018-12-06 15:28:53 -0800200 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800201 want: "s_float: -inf\n",
202 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800203 desc: "double nan",
Herbie Ong800c9902018-12-06 15:28:53 -0800204 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800205 SDouble: math.NaN(),
Herbie Ong800c9902018-12-06 15:28:53 -0800206 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800207 want: "s_double: nan\n",
208 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800209 desc: "double positive infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800210 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800211 SDouble: math.Inf(1),
Herbie Ong800c9902018-12-06 15:28:53 -0800212 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800213 want: "s_double: inf\n",
214 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800215 desc: "double negative infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800216 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800217 SDouble: math.Inf(-1),
Herbie Ong800c9902018-12-06 15:28:53 -0800218 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800219 want: "s_double: -inf\n",
220 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800221 desc: "proto2 enum not set",
222 input: &pb2.Enums{},
Herbie Ongcddf8192018-11-28 18:25:20 -0800223 want: "\n",
224 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800225 desc: "proto2 enum set to zero value",
226 input: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800227 OptEnum: pb2Enum(0),
Herbie Ong800c9902018-12-06 15:28:53 -0800228 OptNestedEnum: pb2Enums_NestedEnum(0),
229 },
Herbie Ong8170d692019-02-13 14:13:21 -0800230 want: `opt_enum: 0
Herbie Ong800c9902018-12-06 15:28:53 -0800231opt_nested_enum: 0
232`,
233 }, {
234 desc: "proto2 enum",
235 input: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800236 OptEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800237 OptNestedEnum: pb2.Enums_UNO.Enum(),
238 },
Herbie Ong8170d692019-02-13 14:13:21 -0800239 want: `opt_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800240opt_nested_enum: UNO
241`,
242 }, {
243 desc: "proto2 enum set to numeric values",
244 input: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800245 OptEnum: pb2Enum(2),
Herbie Ong800c9902018-12-06 15:28:53 -0800246 OptNestedEnum: pb2Enums_NestedEnum(2),
247 },
Herbie Ong8170d692019-02-13 14:13:21 -0800248 want: `opt_enum: TWO
Herbie Ong800c9902018-12-06 15:28:53 -0800249opt_nested_enum: DOS
250`,
251 }, {
252 desc: "proto2 enum set to unnamed numeric values",
253 input: &pb2.Enums{
254 OptEnum: pb2Enum(101),
255 OptNestedEnum: pb2Enums_NestedEnum(-101),
256 },
257 want: `opt_enum: 101
258opt_nested_enum: -101
259`,
260 }, {
261 desc: "proto3 enum not set",
262 input: &pb3.Enums{},
263 want: "\n",
264 }, {
265 desc: "proto3 enum set to zero value",
266 input: &pb3.Enums{
267 SEnum: pb3.Enum_ZERO,
268 SNestedEnum: pb3.Enums_CERO,
269 },
270 want: "\n",
271 }, {
272 desc: "proto3 enum",
273 input: &pb3.Enums{
274 SEnum: pb3.Enum_ONE,
Herbie Ong8170d692019-02-13 14:13:21 -0800275 SNestedEnum: pb3.Enums_UNO,
Herbie Ong800c9902018-12-06 15:28:53 -0800276 },
277 want: `s_enum: ONE
Herbie Ong8170d692019-02-13 14:13:21 -0800278s_nested_enum: UNO
Herbie Ong800c9902018-12-06 15:28:53 -0800279`,
280 }, {
281 desc: "proto3 enum set to numeric values",
282 input: &pb3.Enums{
283 SEnum: 2,
Herbie Ong8170d692019-02-13 14:13:21 -0800284 SNestedEnum: 2,
Herbie Ong800c9902018-12-06 15:28:53 -0800285 },
286 want: `s_enum: TWO
Herbie Ong8170d692019-02-13 14:13:21 -0800287s_nested_enum: DOS
Herbie Ong800c9902018-12-06 15:28:53 -0800288`,
289 }, {
290 desc: "proto3 enum set to unnamed numeric values",
291 input: &pb3.Enums{
292 SEnum: -47,
293 SNestedEnum: 47,
294 },
295 want: `s_enum: -47
296s_nested_enum: 47
297`,
298 }, {
299 desc: "proto2 nested message not set",
300 input: &pb2.Nests{},
301 want: "\n",
302 }, {
303 desc: "proto2 nested message set to empty",
304 input: &pb2.Nests{
305 OptNested: &pb2.Nested{},
306 Optgroup: &pb2.Nests_OptGroup{},
307 },
308 want: `opt_nested: {}
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800309OptGroup: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800310`,
311 }, {
312 desc: "proto2 nested messages",
313 input: &pb2.Nests{
314 OptNested: &pb2.Nested{
315 OptString: scalar.String("nested message"),
316 OptNested: &pb2.Nested{
317 OptString: scalar.String("another nested message"),
318 },
319 },
320 },
321 want: `opt_nested: {
322 opt_string: "nested message"
323 opt_nested: {
324 opt_string: "another nested message"
325 }
326}
327`,
328 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800329 desc: "proto2 groups",
Herbie Ong800c9902018-12-06 15:28:53 -0800330 input: &pb2.Nests{
331 Optgroup: &pb2.Nests_OptGroup{
Herbie Ong800c9902018-12-06 15:28:53 -0800332 OptString: scalar.String("inside a group"),
333 OptNested: &pb2.Nested{
334 OptString: scalar.String("nested message inside a group"),
335 },
336 Optnestedgroup: &pb2.Nests_OptGroup_OptNestedGroup{
Herbie Ong8170d692019-02-13 14:13:21 -0800337 OptFixed32: scalar.Uint32(47),
Herbie Ong800c9902018-12-06 15:28:53 -0800338 },
339 },
340 },
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800341 want: `OptGroup: {
Herbie Ong800c9902018-12-06 15:28:53 -0800342 opt_string: "inside a group"
343 opt_nested: {
344 opt_string: "nested message inside a group"
345 }
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800346 OptNestedGroup: {
Herbie Ong8170d692019-02-13 14:13:21 -0800347 opt_fixed32: 47
Herbie Ong800c9902018-12-06 15:28:53 -0800348 }
349}
350`,
351 }, {
352 desc: "proto3 nested message not set",
353 input: &pb3.Nests{},
354 want: "\n",
355 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800356 desc: "proto3 nested message set to empty",
357 input: &pb3.Nests{
358 SNested: &pb3.Nested{},
359 },
360 want: "s_nested: {}\n",
361 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800362 desc: "proto3 nested message",
363 input: &pb3.Nests{
364 SNested: &pb3.Nested{
365 SString: "nested message",
366 SNested: &pb3.Nested{
367 SString: "another nested message",
368 },
369 },
370 },
371 want: `s_nested: {
372 s_string: "nested message"
373 s_nested: {
374 s_string: "another nested message"
375 }
376}
377`,
378 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800379 desc: "oneof not set",
380 input: &pb3.Oneofs{},
Herbie Ong800c9902018-12-06 15:28:53 -0800381 want: "\n",
382 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800383 desc: "oneof set to empty string",
384 input: &pb3.Oneofs{
385 Union: &pb3.Oneofs_OneofString{},
Herbie Ong800c9902018-12-06 15:28:53 -0800386 },
Herbie Ong8170d692019-02-13 14:13:21 -0800387 want: `oneof_string: ""
388`,
Herbie Ong800c9902018-12-06 15:28:53 -0800389 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800390 desc: "oneof set to string",
391 input: &pb3.Oneofs{
392 Union: &pb3.Oneofs_OneofString{
393 OneofString: "hello",
Herbie Ong800c9902018-12-06 15:28:53 -0800394 },
395 },
Herbie Ong8170d692019-02-13 14:13:21 -0800396 want: `oneof_string: "hello"
397`,
Herbie Ong800c9902018-12-06 15:28:53 -0800398 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800399 desc: "oneof set to enum",
400 input: &pb3.Oneofs{
401 Union: &pb3.Oneofs_OneofEnum{
402 OneofEnum: pb3.Enum_ZERO,
Herbie Ong800c9902018-12-06 15:28:53 -0800403 },
404 },
Herbie Ong8170d692019-02-13 14:13:21 -0800405 want: `oneof_enum: ZERO
406`,
Herbie Ong800c9902018-12-06 15:28:53 -0800407 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800408 desc: "oneof set to empty message",
409 input: &pb3.Oneofs{
410 Union: &pb3.Oneofs_OneofNested{
411 OneofNested: &pb3.Nested{},
412 },
413 },
414 want: "oneof_nested: {}\n",
415 }, {
416 desc: "oneof set to message",
417 input: &pb3.Oneofs{
418 Union: &pb3.Oneofs_OneofNested{
419 OneofNested: &pb3.Nested{
420 SString: "nested message",
Herbie Ong800c9902018-12-06 15:28:53 -0800421 },
422 },
423 },
Herbie Ong8170d692019-02-13 14:13:21 -0800424 want: `oneof_nested: {
425 s_string: "nested message"
Herbie Ong800c9902018-12-06 15:28:53 -0800426}
427`,
428 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800429 desc: "repeated fields not set",
Herbie Ong800c9902018-12-06 15:28:53 -0800430 input: &pb2.Repeats{},
431 want: "\n",
432 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800433 desc: "repeated fields set to empty slices",
Herbie Ong800c9902018-12-06 15:28:53 -0800434 input: &pb2.Repeats{
Herbie Ongcddf8192018-11-28 18:25:20 -0800435 RptBool: []bool{},
436 RptInt32: []int32{},
437 RptInt64: []int64{},
438 RptUint32: []uint32{},
439 RptUint64: []uint64{},
440 RptFloat: []float32{},
441 RptDouble: []float64{},
442 RptBytes: [][]byte{},
Herbie Ong800c9902018-12-06 15:28:53 -0800443 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800444 want: "\n",
445 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800446 desc: "repeated fields set to some values",
Herbie Ong800c9902018-12-06 15:28:53 -0800447 input: &pb2.Repeats{
Herbie Ongcddf8192018-11-28 18:25:20 -0800448 RptBool: []bool{true, false, true, true},
449 RptInt32: []int32{1, 6, 0, 0},
450 RptInt64: []int64{-64, 47},
451 RptUint32: []uint32{0xff, 0xffff},
452 RptUint64: []uint64{0xdeadbeef},
Herbie Ong84f09602019-01-17 19:31:47 -0800453 RptFloat: []float32{float32(math.NaN()), float32(math.Inf(1)), float32(math.Inf(-1)), 1.034},
Herbie Ongcddf8192018-11-28 18:25:20 -0800454 RptDouble: []float64{math.NaN(), math.Inf(1), math.Inf(-1), 1.23e-308},
455 RptString: []string{"hello", "世界"},
456 RptBytes: [][]byte{
457 []byte("hello"),
458 []byte("\xe4\xb8\x96\xe7\x95\x8c"),
459 },
Herbie Ong800c9902018-12-06 15:28:53 -0800460 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800461 want: `rpt_bool: true
462rpt_bool: false
463rpt_bool: true
464rpt_bool: true
465rpt_int32: 1
466rpt_int32: 6
467rpt_int32: 0
468rpt_int32: 0
469rpt_int64: -64
470rpt_int64: 47
471rpt_uint32: 255
472rpt_uint32: 65535
473rpt_uint64: 3735928559
Herbie Ong84f09602019-01-17 19:31:47 -0800474rpt_float: nan
475rpt_float: inf
476rpt_float: -inf
477rpt_float: 1.034
Herbie Ongcddf8192018-11-28 18:25:20 -0800478rpt_double: nan
479rpt_double: inf
480rpt_double: -inf
481rpt_double: 1.23e-308
482rpt_string: "hello"
483rpt_string: "世界"
484rpt_bytes: "hello"
485rpt_bytes: "世界"
486`,
487 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800488 desc: "repeated enums",
Herbie Ong800c9902018-12-06 15:28:53 -0800489 input: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800490 RptEnum: []pb2.Enum{pb2.Enum_ONE, 2, pb2.Enum_TEN, 42},
Herbie Ongcddf8192018-11-28 18:25:20 -0800491 RptNestedEnum: []pb2.Enums_NestedEnum{2, 47, 10},
Herbie Ong800c9902018-12-06 15:28:53 -0800492 },
Herbie Ong8170d692019-02-13 14:13:21 -0800493 want: `rpt_enum: ONE
494rpt_enum: TWO
495rpt_enum: TEN
Herbie Ongcddf8192018-11-28 18:25:20 -0800496rpt_enum: 42
Herbie Ongcddf8192018-11-28 18:25:20 -0800497rpt_nested_enum: DOS
498rpt_nested_enum: 47
499rpt_nested_enum: DIEZ
500`,
501 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800502 desc: "repeated messages set to empty",
Herbie Ong800c9902018-12-06 15:28:53 -0800503 input: &pb2.Nests{
Herbie Ongcddf8192018-11-28 18:25:20 -0800504 RptNested: []*pb2.Nested{},
505 Rptgroup: []*pb2.Nests_RptGroup{},
Herbie Ong800c9902018-12-06 15:28:53 -0800506 },
507 want: "\n",
Herbie Ongcddf8192018-11-28 18:25:20 -0800508 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800509 desc: "repeated messages",
Herbie Ong800c9902018-12-06 15:28:53 -0800510 input: &pb2.Nests{
Herbie Ongcddf8192018-11-28 18:25:20 -0800511 RptNested: []*pb2.Nested{
512 {
513 OptString: scalar.String("repeat nested one"),
514 },
515 {
516 OptString: scalar.String("repeat nested two"),
517 OptNested: &pb2.Nested{
518 OptString: scalar.String("inside repeat nested two"),
519 },
520 },
521 {},
522 },
Herbie Ong800c9902018-12-06 15:28:53 -0800523 },
524 want: `rpt_nested: {
Herbie Ongcddf8192018-11-28 18:25:20 -0800525 opt_string: "repeat nested one"
526}
527rpt_nested: {
528 opt_string: "repeat nested two"
529 opt_nested: {
530 opt_string: "inside repeat nested two"
531 }
532}
533rpt_nested: {}
534`,
535 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800536 desc: "repeated messages contains nil value",
Herbie Ongf5db2df2019-02-07 20:17:45 -0800537 input: &pb2.Nests{
538 RptNested: []*pb2.Nested{nil, {}},
539 },
540 want: `rpt_nested: {}
541rpt_nested: {}
542`,
543 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800544 desc: "repeated groups",
Herbie Ong800c9902018-12-06 15:28:53 -0800545 input: &pb2.Nests{
Herbie Ongcddf8192018-11-28 18:25:20 -0800546 Rptgroup: []*pb2.Nests_RptGroup{
547 {
Herbie Ong8170d692019-02-13 14:13:21 -0800548 RptString: []string{"hello", "world"},
Herbie Ongcddf8192018-11-28 18:25:20 -0800549 },
550 {},
Herbie Ong8170d692019-02-13 14:13:21 -0800551 nil,
Herbie Ongcddf8192018-11-28 18:25:20 -0800552 },
Herbie Ong800c9902018-12-06 15:28:53 -0800553 },
Herbie Ongde7313b2019-01-14 19:26:50 -0800554 want: `RptGroup: {
Herbie Ong8170d692019-02-13 14:13:21 -0800555 rpt_string: "hello"
556 rpt_string: "world"
Herbie Ongcddf8192018-11-28 18:25:20 -0800557}
Herbie Ongde7313b2019-01-14 19:26:50 -0800558RptGroup: {}
Herbie Ong8170d692019-02-13 14:13:21 -0800559RptGroup: {}
Herbie Ongcddf8192018-11-28 18:25:20 -0800560`,
561 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800562 desc: "map fields not set",
563 input: &pb3.Maps{},
Herbie Ongcddf8192018-11-28 18:25:20 -0800564 want: "\n",
565 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800566 desc: "map fields set to empty",
567 input: &pb3.Maps{
568 Int32ToStr: map[int32]string{},
569 BoolToUint32: map[bool]uint32{},
570 Uint64ToEnum: map[uint64]pb3.Enum{},
571 StrToNested: map[string]*pb3.Nested{},
572 StrToOneofs: map[string]*pb3.Oneofs{},
Herbie Ong800c9902018-12-06 15:28:53 -0800573 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800574 want: "\n",
575 }, {
576 desc: "map fields 1",
Herbie Ong8170d692019-02-13 14:13:21 -0800577 input: &pb3.Maps{
Herbie Ongcddf8192018-11-28 18:25:20 -0800578 Int32ToStr: map[int32]string{
579 -101: "-101",
580 0xff: "0xff",
581 0: "zero",
582 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800583 BoolToUint32: map[bool]uint32{
584 true: 42,
585 false: 101,
586 },
Herbie Ong800c9902018-12-06 15:28:53 -0800587 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800588 want: `int32_to_str: {
589 key: -101
590 value: "-101"
591}
592int32_to_str: {
593 key: 0
594 value: "zero"
595}
596int32_to_str: {
597 key: 255
598 value: "0xff"
599}
Herbie Ongcddf8192018-11-28 18:25:20 -0800600bool_to_uint32: {
601 key: false
602 value: 101
603}
604bool_to_uint32: {
605 key: true
606 value: 42
607}
608`,
609 }, {
610 desc: "map fields 2",
Herbie Ong8170d692019-02-13 14:13:21 -0800611 input: &pb3.Maps{
612 Uint64ToEnum: map[uint64]pb3.Enum{
613 1: pb3.Enum_ONE,
614 2: pb3.Enum_TWO,
615 10: pb3.Enum_TEN,
616 47: 47,
Herbie Ongcddf8192018-11-28 18:25:20 -0800617 },
Herbie Ong800c9902018-12-06 15:28:53 -0800618 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800619 want: `uint64_to_enum: {
620 key: 1
Herbie Ong8170d692019-02-13 14:13:21 -0800621 value: ONE
Herbie Ongcddf8192018-11-28 18:25:20 -0800622}
623uint64_to_enum: {
624 key: 2
Herbie Ong8170d692019-02-13 14:13:21 -0800625 value: TWO
Herbie Ongcddf8192018-11-28 18:25:20 -0800626}
627uint64_to_enum: {
628 key: 10
Herbie Ong8170d692019-02-13 14:13:21 -0800629 value: TEN
630}
631uint64_to_enum: {
632 key: 47
633 value: 47
Herbie Ongcddf8192018-11-28 18:25:20 -0800634}
635`,
636 }, {
637 desc: "map fields 3",
Herbie Ong8170d692019-02-13 14:13:21 -0800638 input: &pb3.Maps{
639 StrToNested: map[string]*pb3.Nested{
640 "nested": &pb3.Nested{
641 SString: "nested in a map",
Herbie Ongcddf8192018-11-28 18:25:20 -0800642 },
643 },
Herbie Ong800c9902018-12-06 15:28:53 -0800644 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800645 want: `str_to_nested: {
Herbie Ong8170d692019-02-13 14:13:21 -0800646 key: "nested"
Herbie Ongcddf8192018-11-28 18:25:20 -0800647 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800648 s_string: "nested in a map"
Herbie Ongcddf8192018-11-28 18:25:20 -0800649 }
650}
651`,
652 }, {
653 desc: "map fields 4",
Herbie Ong8170d692019-02-13 14:13:21 -0800654 input: &pb3.Maps{
655 StrToOneofs: map[string]*pb3.Oneofs{
656 "string": &pb3.Oneofs{
657 Union: &pb3.Oneofs_OneofString{
658 OneofString: "hello",
Herbie Ongcddf8192018-11-28 18:25:20 -0800659 },
660 },
Herbie Ong8170d692019-02-13 14:13:21 -0800661 "nested": &pb3.Oneofs{
662 Union: &pb3.Oneofs_OneofNested{
663 OneofNested: &pb3.Nested{
664 SString: "nested oneof in map field value",
Herbie Ongcddf8192018-11-28 18:25:20 -0800665 },
666 },
667 },
668 },
Herbie Ong800c9902018-12-06 15:28:53 -0800669 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800670 want: `str_to_oneofs: {
671 key: "nested"
672 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800673 oneof_nested: {
674 s_string: "nested oneof in map field value"
Herbie Ongcddf8192018-11-28 18:25:20 -0800675 }
676 }
677}
678str_to_oneofs: {
679 key: "string"
680 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800681 oneof_string: "hello"
Herbie Ongcddf8192018-11-28 18:25:20 -0800682 }
683}
684`,
685 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800686 desc: "map field contains nil value",
687 input: &pb3.Maps{
688 StrToNested: map[string]*pb3.Nested{
Herbie Ongf5db2df2019-02-07 20:17:45 -0800689 "nil": nil,
690 },
691 },
692 want: `str_to_nested: {
693 key: "nil"
694 value: {}
695}
696`,
697 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800698 desc: "proto2 required fields not set",
699 input: &pb2.Requireds{},
700 want: "\n",
701 wantErr: true,
Herbie Ongcddf8192018-11-28 18:25:20 -0800702 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800703 desc: "proto2 required fields partially set",
704 input: &pb2.Requireds{
705 ReqBool: scalar.Bool(false),
Herbie Ong800c9902018-12-06 15:28:53 -0800706 ReqSfixed64: scalar.Int64(0xbeefcafe),
707 ReqDouble: scalar.Float64(math.NaN()),
708 ReqString: scalar.String("hello"),
Herbie Ong8170d692019-02-13 14:13:21 -0800709 ReqEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800710 },
711 want: `req_bool: false
Herbie Ong800c9902018-12-06 15:28:53 -0800712req_sfixed64: 3203386110
713req_double: nan
714req_string: "hello"
Herbie Ong8170d692019-02-13 14:13:21 -0800715req_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800716`,
717 wantErr: true,
718 }, {
719 desc: "proto2 required fields all set",
720 input: &pb2.Requireds{
721 ReqBool: scalar.Bool(false),
Herbie Ong800c9902018-12-06 15:28:53 -0800722 ReqSfixed64: scalar.Int64(0),
Herbie Ong8170d692019-02-13 14:13:21 -0800723 ReqDouble: scalar.Float64(1.23),
Herbie Ong800c9902018-12-06 15:28:53 -0800724 ReqString: scalar.String(""),
Herbie Ong8170d692019-02-13 14:13:21 -0800725 ReqEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800726 ReqNested: &pb2.Nested{},
727 },
728 want: `req_bool: false
Herbie Ong800c9902018-12-06 15:28:53 -0800729req_sfixed64: 0
Herbie Ong8170d692019-02-13 14:13:21 -0800730req_double: 1.23
Herbie Ong800c9902018-12-06 15:28:53 -0800731req_string: ""
Herbie Ong8170d692019-02-13 14:13:21 -0800732req_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800733req_nested: {}
Herbie Ongcddf8192018-11-28 18:25:20 -0800734`,
735 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800736 desc: "indirect required field",
737 input: &pb2.IndirectRequired{
738 OptNested: &pb2.NestedWithRequired{},
739 },
740 want: "opt_nested: {}\n",
741 wantErr: true,
Herbie Ongcddf8192018-11-28 18:25:20 -0800742 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800743 desc: "indirect required field in empty repeated",
744 input: &pb2.IndirectRequired{
745 RptNested: []*pb2.NestedWithRequired{},
746 },
747 want: "\n",
Herbie Ongcddf8192018-11-28 18:25:20 -0800748 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800749 desc: "indirect required field in repeated",
750 input: &pb2.IndirectRequired{
751 RptNested: []*pb2.NestedWithRequired{
752 &pb2.NestedWithRequired{},
Herbie Ongcddf8192018-11-28 18:25:20 -0800753 },
Herbie Ong800c9902018-12-06 15:28:53 -0800754 },
755 want: "rpt_nested: {}\n",
756 wantErr: true,
757 }, {
758 desc: "indirect required field in empty map",
759 input: &pb2.IndirectRequired{
760 StrToNested: map[string]*pb2.NestedWithRequired{},
761 },
762 want: "\n",
763 }, {
764 desc: "indirect required field in map",
765 input: &pb2.IndirectRequired{
766 StrToNested: map[string]*pb2.NestedWithRequired{
767 "fail": &pb2.NestedWithRequired{},
768 },
769 },
770 want: `str_to_nested: {
771 key: "fail"
772 value: {}
Herbie Ongcddf8192018-11-28 18:25:20 -0800773}
774`,
Herbie Ong800c9902018-12-06 15:28:53 -0800775 wantErr: true,
Herbie Ong20a1d312018-12-11 21:08:58 -0800776 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800777 desc: "indirect required field in oneof",
778 input: &pb2.IndirectRequired{
779 Union: &pb2.IndirectRequired_OneofNested{
780 OneofNested: &pb2.NestedWithRequired{},
781 },
782 },
783 want: "oneof_nested: {}\n",
784 wantErr: true,
785 }, {
Herbie Ong20a1d312018-12-11 21:08:58 -0800786 desc: "unknown varint and fixed types",
787 input: &pb2.Scalars{
788 OptString: scalar.String("this message contains unknown fields"),
789 XXX_unrecognized: pack.Message{
790 pack.Tag{101, pack.VarintType}, pack.Bool(true),
791 pack.Tag{102, pack.VarintType}, pack.Varint(0xff),
792 pack.Tag{103, pack.Fixed32Type}, pack.Uint32(47),
793 pack.Tag{104, pack.Fixed64Type}, pack.Int64(0xdeadbeef),
794 }.Marshal(),
795 },
796 want: `opt_string: "this message contains unknown fields"
797101: 1
798102: 255
799103: 47
800104: 3735928559
801`,
802 }, {
803 desc: "unknown length-delimited",
804 input: &pb2.Scalars{
805 XXX_unrecognized: pack.Message{
806 pack.Tag{101, pack.BytesType}, pack.LengthPrefix{pack.Bool(true), pack.Bool(false)},
807 pack.Tag{102, pack.BytesType}, pack.String("hello world"),
808 pack.Tag{103, pack.BytesType}, pack.Bytes("\xe4\xb8\x96\xe7\x95\x8c"),
809 }.Marshal(),
810 },
811 want: `101: "\x01\x00"
812102: "hello world"
813103: "世界"
814`,
815 }, {
816 desc: "unknown group type",
817 input: &pb2.Scalars{
818 XXX_unrecognized: pack.Message{
819 pack.Tag{101, pack.StartGroupType}, pack.Tag{101, pack.EndGroupType},
820 pack.Tag{102, pack.StartGroupType},
821 pack.Tag{101, pack.VarintType}, pack.Bool(false),
822 pack.Tag{102, pack.BytesType}, pack.String("inside a group"),
823 pack.Tag{102, pack.EndGroupType},
824 }.Marshal(),
825 },
826 want: `101: {}
827102: {
828 101: 0
829 102: "inside a group"
830}
831`,
832 }, {
833 desc: "unknown unpack repeated field",
834 input: &pb2.Scalars{
835 XXX_unrecognized: pack.Message{
836 pack.Tag{101, pack.BytesType}, pack.LengthPrefix{pack.Bool(true), pack.Bool(false), pack.Bool(true)},
837 pack.Tag{102, pack.BytesType}, pack.String("hello"),
838 pack.Tag{101, pack.VarintType}, pack.Bool(true),
839 pack.Tag{102, pack.BytesType}, pack.String("世界"),
840 }.Marshal(),
841 },
842 want: `101: "\x01\x00\x01"
843101: 1
844102: "hello"
845102: "世界"
846`,
Herbie Ongcf253082018-12-17 17:13:07 -0800847 }, {
848 desc: "extensions of non-repeated fields",
849 input: func() proto.Message {
850 m := &pb2.Extensions{
851 OptString: scalar.String("non-extension field"),
852 OptBool: scalar.Bool(true),
853 OptInt32: scalar.Int32(42),
854 }
855 setExtension(m, pb2.E_OptExtBool, true)
856 setExtension(m, pb2.E_OptExtString, "extension field")
Herbie Ong8170d692019-02-13 14:13:21 -0800857 setExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
Herbie Ongcf253082018-12-17 17:13:07 -0800858 setExtension(m, pb2.E_OptExtNested, &pb2.Nested{
859 OptString: scalar.String("nested in an extension"),
860 OptNested: &pb2.Nested{
861 OptString: scalar.String("another nested in an extension"),
862 },
863 })
864 return m
865 }(),
866 want: `opt_string: "non-extension field"
867opt_bool: true
868opt_int32: 42
869[pb2.opt_ext_bool]: true
Herbie Ong8170d692019-02-13 14:13:21 -0800870[pb2.opt_ext_enum]: TEN
Herbie Ongcf253082018-12-17 17:13:07 -0800871[pb2.opt_ext_nested]: {
872 opt_string: "nested in an extension"
873 opt_nested: {
874 opt_string: "another nested in an extension"
875 }
876}
877[pb2.opt_ext_string]: "extension field"
878`,
879 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800880 desc: "extension message field set to nil",
Herbie Ongcf253082018-12-17 17:13:07 -0800881 input: func() proto.Message {
882 m := &pb2.Extensions{}
883 setExtension(m, pb2.E_OptExtNested, nil)
884 return m
885 }(),
886 want: "\n",
887 }, {
888 desc: "extensions of repeated fields",
889 input: func() proto.Message {
890 m := &pb2.Extensions{}
Herbie Ong8170d692019-02-13 14:13:21 -0800891 setExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
Herbie Ongcf253082018-12-17 17:13:07 -0800892 setExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
893 setExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
894 &pb2.Nested{OptString: scalar.String("one")},
895 &pb2.Nested{OptString: scalar.String("two")},
896 &pb2.Nested{OptString: scalar.String("three")},
897 })
898 return m
899 }(),
Herbie Ong8170d692019-02-13 14:13:21 -0800900 want: `[pb2.rpt_ext_enum]: TEN
Herbie Ongcf253082018-12-17 17:13:07 -0800901[pb2.rpt_ext_enum]: 101
Herbie Ong8170d692019-02-13 14:13:21 -0800902[pb2.rpt_ext_enum]: ONE
Herbie Ongcf253082018-12-17 17:13:07 -0800903[pb2.rpt_ext_fixed32]: 42
904[pb2.rpt_ext_fixed32]: 47
905[pb2.rpt_ext_nested]: {
906 opt_string: "one"
907}
908[pb2.rpt_ext_nested]: {
909 opt_string: "two"
910}
911[pb2.rpt_ext_nested]: {
912 opt_string: "three"
913}
914`,
915 }, {
916 desc: "extensions of non-repeated fields in another message",
917 input: func() proto.Message {
918 m := &pb2.Extensions{}
919 setExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
920 setExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
Herbie Ong8170d692019-02-13 14:13:21 -0800921 setExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
Herbie Ongcf253082018-12-17 17:13:07 -0800922 setExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
923 OptString: scalar.String("nested in an extension"),
924 OptNested: &pb2.Nested{
925 OptString: scalar.String("another nested in an extension"),
926 },
927 })
928 return m
929 }(),
930 want: `[pb2.ExtensionsContainer.opt_ext_bool]: true
Herbie Ong8170d692019-02-13 14:13:21 -0800931[pb2.ExtensionsContainer.opt_ext_enum]: TEN
Herbie Ongcf253082018-12-17 17:13:07 -0800932[pb2.ExtensionsContainer.opt_ext_nested]: {
933 opt_string: "nested in an extension"
934 opt_nested: {
935 opt_string: "another nested in an extension"
936 }
937}
938[pb2.ExtensionsContainer.opt_ext_string]: "extension field"
939`,
940 }, {
941 desc: "extensions of repeated fields in another message",
942 input: func() proto.Message {
943 m := &pb2.Extensions{
944 OptString: scalar.String("non-extension field"),
945 OptBool: scalar.Bool(true),
946 OptInt32: scalar.Int32(42),
947 }
Herbie Ong8170d692019-02-13 14:13:21 -0800948 setExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
Herbie Ongcf253082018-12-17 17:13:07 -0800949 setExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
950 setExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
951 &pb2.Nested{OptString: scalar.String("one")},
952 &pb2.Nested{OptString: scalar.String("two")},
953 &pb2.Nested{OptString: scalar.String("three")},
954 })
955 return m
956 }(),
957 want: `opt_string: "non-extension field"
958opt_bool: true
959opt_int32: 42
Herbie Ong8170d692019-02-13 14:13:21 -0800960[pb2.ExtensionsContainer.rpt_ext_enum]: TEN
Herbie Ongcf253082018-12-17 17:13:07 -0800961[pb2.ExtensionsContainer.rpt_ext_enum]: 101
Herbie Ong8170d692019-02-13 14:13:21 -0800962[pb2.ExtensionsContainer.rpt_ext_enum]: ONE
Herbie Ongcf253082018-12-17 17:13:07 -0800963[pb2.ExtensionsContainer.rpt_ext_nested]: {
964 opt_string: "one"
965}
966[pb2.ExtensionsContainer.rpt_ext_nested]: {
967 opt_string: "two"
968}
969[pb2.ExtensionsContainer.rpt_ext_nested]: {
970 opt_string: "three"
971}
972[pb2.ExtensionsContainer.rpt_ext_string]: "hello"
973[pb2.ExtensionsContainer.rpt_ext_string]: "world"
974`,
Herbie Ong6470ea62019-01-07 18:56:57 -0800975 }, {
976 desc: "MessageSet",
977 input: func() proto.Message {
978 m := &pb2.MessageSet{}
979 setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
980 OptString: scalar.String("a messageset extension"),
981 })
982 setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
983 OptString: scalar.String("not a messageset extension"),
984 })
985 setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
986 OptString: scalar.String("just a regular extension"),
987 })
988 return m
989 }(),
990 want: `[pb2.MessageSetExtension]: {
991 opt_string: "a messageset extension"
992}
993[pb2.MessageSetExtension.ext_nested]: {
994 opt_string: "just a regular extension"
995}
996[pb2.MessageSetExtension.not_message_set_extension]: {
997 opt_string: "not a messageset extension"
998}
999`,
1000 }, {
1001 desc: "not real MessageSet 1",
1002 input: func() proto.Message {
1003 m := &pb2.FakeMessageSet{}
1004 setExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
1005 OptString: scalar.String("not a messageset extension"),
1006 })
1007 return m
1008 }(),
1009 want: `[pb2.FakeMessageSetExtension.message_set_extension]: {
1010 opt_string: "not a messageset extension"
1011}
1012`,
1013 }, {
1014 desc: "not real MessageSet 2",
1015 input: func() proto.Message {
1016 m := &pb2.MessageSet{}
1017 setExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
1018 OptString: scalar.String("another not a messageset extension"),
1019 })
1020 return m
1021 }(),
1022 want: `[pb2.message_set_extension]: {
1023 opt_string: "another not a messageset extension"
1024}
1025`,
Herbie Ongf42b55f2019-01-02 15:46:07 -08001026 }, {
Herbie Ong8170d692019-02-13 14:13:21 -08001027 desc: "Any not expanded",
Herbie Ong66c365c2019-01-04 14:08:41 -08001028 mo: textpb.MarshalOptions{
1029 Resolver: preg.NewTypes(),
1030 },
Herbie Ongf42b55f2019-01-02 15:46:07 -08001031 input: func() proto.Message {
1032 m := &pb2.Nested{
1033 OptString: scalar.String("embedded inside Any"),
1034 OptNested: &pb2.Nested{
1035 OptString: scalar.String("inception"),
1036 },
1037 }
1038 // TODO: Switch to V2 marshal when ready.
1039 b, err := protoV1.Marshal(m)
1040 if err != nil {
1041 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1042 }
Herbie Ong8170d692019-02-13 14:13:21 -08001043 return wrapV1Message(&anypb.Any{
Herbie Ong66c365c2019-01-04 14:08:41 -08001044 TypeUrl: "pb2.Nested",
Herbie Ongf42b55f2019-01-02 15:46:07 -08001045 Value: b,
Herbie Ong66c365c2019-01-04 14:08:41 -08001046 })
Herbie Ongf42b55f2019-01-02 15:46:07 -08001047 }(),
1048 want: `type_url: "pb2.Nested"
1049value: "\n\x13embedded inside Any\x12\x0b\n\tinception"
1050`,
1051 }, {
Herbie Ong8170d692019-02-13 14:13:21 -08001052 desc: "Any expanded",
Herbie Ong66c365c2019-01-04 14:08:41 -08001053 mo: textpb.MarshalOptions{
1054 Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
1055 },
Herbie Ongf42b55f2019-01-02 15:46:07 -08001056 input: func() proto.Message {
1057 m := &pb2.Nested{
1058 OptString: scalar.String("embedded inside Any"),
1059 OptNested: &pb2.Nested{
1060 OptString: scalar.String("inception"),
1061 },
1062 }
1063 // TODO: Switch to V2 marshal when ready.
1064 b, err := protoV1.Marshal(m)
1065 if err != nil {
1066 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1067 }
Herbie Ong8170d692019-02-13 14:13:21 -08001068 return wrapV1Message(&anypb.Any{
Herbie Ong66c365c2019-01-04 14:08:41 -08001069 TypeUrl: "foo/pb2.Nested",
Herbie Ongf42b55f2019-01-02 15:46:07 -08001070 Value: b,
Herbie Ong66c365c2019-01-04 14:08:41 -08001071 })
Herbie Ongf42b55f2019-01-02 15:46:07 -08001072 }(),
Herbie Ong66c365c2019-01-04 14:08:41 -08001073 want: `[foo/pb2.Nested]: {
Herbie Ongf42b55f2019-01-02 15:46:07 -08001074 opt_string: "embedded inside Any"
1075 opt_nested: {
1076 opt_string: "inception"
1077 }
1078}
1079`,
1080 }, {
Herbie Ong8170d692019-02-13 14:13:21 -08001081 desc: "Any expanded with missing required error",
Herbie Ong66c365c2019-01-04 14:08:41 -08001082 mo: textpb.MarshalOptions{
1083 Resolver: preg.NewTypes((&pb2.PartialRequired{}).ProtoReflect().Type()),
1084 },
Herbie Ongf42b55f2019-01-02 15:46:07 -08001085 input: func() proto.Message {
1086 m := &pb2.PartialRequired{
1087 OptString: scalar.String("embedded inside Any"),
1088 }
1089 // TODO: Switch to V2 marshal when ready.
1090 b, err := protoV1.Marshal(m)
1091 // Ignore required not set error.
1092 if _, ok := err.(*protoV1.RequiredNotSetError); !ok {
1093 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1094 }
Herbie Ong8170d692019-02-13 14:13:21 -08001095 return wrapV1Message(&anypb.Any{
Herbie Ongf42b55f2019-01-02 15:46:07 -08001096 TypeUrl: string(m.ProtoReflect().Type().FullName()),
1097 Value: b,
Herbie Ong66c365c2019-01-04 14:08:41 -08001098 })
Herbie Ongf42b55f2019-01-02 15:46:07 -08001099 }(),
1100 want: `[pb2.PartialRequired]: {
1101 opt_string: "embedded inside Any"
1102}
1103`,
1104 wantErr: true,
1105 }, {
Herbie Ong8170d692019-02-13 14:13:21 -08001106 desc: "Any with invalid value",
Herbie Ong66c365c2019-01-04 14:08:41 -08001107 mo: textpb.MarshalOptions{
1108 Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
1109 },
Herbie Ong8170d692019-02-13 14:13:21 -08001110 input: wrapV1Message(&anypb.Any{
Herbie Ong66c365c2019-01-04 14:08:41 -08001111 TypeUrl: "foo/pb2.Nested",
1112 Value: dhex("80"),
1113 }),
1114 want: `type_url: "foo/pb2.Nested"
Herbie Onga94f78c2019-01-03 15:39:58 -08001115value: "\x80"
1116`,
Herbie Ongcddf8192018-11-28 18:25:20 -08001117 }}
1118
1119 for _, tt := range tests {
1120 tt := tt
1121 t.Run(tt.desc, func(t *testing.T) {
1122 t.Parallel()
Herbie Ongf42b55f2019-01-02 15:46:07 -08001123 b, err := tt.mo.Marshal(tt.input)
Herbie Ongcddf8192018-11-28 18:25:20 -08001124 if err != nil && !tt.wantErr {
Herbie Ongf42b55f2019-01-02 15:46:07 -08001125 t.Errorf("Marshal() returned error: %v\n", err)
Herbie Ongcddf8192018-11-28 18:25:20 -08001126 }
Herbie Ong800c9902018-12-06 15:28:53 -08001127 if err == nil && tt.wantErr {
Herbie Ongf42b55f2019-01-02 15:46:07 -08001128 t.Error("Marshal() got nil error, want error\n")
Herbie Ongcddf8192018-11-28 18:25:20 -08001129 }
Herbie Ong800c9902018-12-06 15:28:53 -08001130 got := string(b)
1131 if tt.want != "" && got != tt.want {
1132 t.Errorf("Marshal()\n<got>\n%v\n<want>\n%v\n", got, tt.want)
1133 if diff := cmp.Diff(tt.want, got, splitLines); diff != "" {
Herbie Ongcddf8192018-11-28 18:25:20 -08001134 t.Errorf("Marshal() diff -want +got\n%v\n", diff)
1135 }
1136 }
1137 })
1138 }
1139}