blob: 5797a8bd5b84de757bf6cbb1f90d9df303e10c54 [file] [log] [blame]
Herbie Ongc96a79d2019-03-08 10:49:17 -08001// 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 protojson_test
Herbie Ongc96a79d2019-03-08 10:49:17 -08006
7import (
8 "math"
9 "testing"
10
Damien Neil5c5b5312019-05-14 12:44:37 -070011 "google.golang.org/protobuf/encoding/protojson"
Damien Neile89e6242019-05-13 23:55:40 -070012 "google.golang.org/protobuf/encoding/testprotos/pb2"
13 "google.golang.org/protobuf/encoding/testprotos/pb3"
14 pimpl "google.golang.org/protobuf/internal/impl"
15 "google.golang.org/protobuf/internal/scalar"
16 "google.golang.org/protobuf/proto"
17 preg "google.golang.org/protobuf/reflect/protoregistry"
18 "google.golang.org/protobuf/runtime/protoiface"
Herbie Onge63c4c42019-03-22 22:20:22 -070019
Joe Tsaia95b29f2019-05-16 12:47:20 -070020 "google.golang.org/protobuf/types/known/anypb"
21 "google.golang.org/protobuf/types/known/durationpb"
22 "google.golang.org/protobuf/types/known/emptypb"
23 "google.golang.org/protobuf/types/known/fieldmaskpb"
24 "google.golang.org/protobuf/types/known/structpb"
25 "google.golang.org/protobuf/types/known/timestamppb"
26 "google.golang.org/protobuf/types/known/wrapperspb"
Herbie Ongc96a79d2019-03-08 10:49:17 -080027)
28
Herbie Onge52379a2019-03-15 18:00:19 -070029func init() {
30 // TODO: remove these registerExtension calls when generated code registers
31 // to V2 global registry.
32 registerExtension(pb2.E_OptExtBool)
33 registerExtension(pb2.E_OptExtString)
34 registerExtension(pb2.E_OptExtEnum)
35 registerExtension(pb2.E_OptExtNested)
36 registerExtension(pb2.E_RptExtFixed32)
37 registerExtension(pb2.E_RptExtEnum)
38 registerExtension(pb2.E_RptExtNested)
39 registerExtension(pb2.E_ExtensionsContainer_OptExtBool)
40 registerExtension(pb2.E_ExtensionsContainer_OptExtString)
41 registerExtension(pb2.E_ExtensionsContainer_OptExtEnum)
42 registerExtension(pb2.E_ExtensionsContainer_OptExtNested)
43 registerExtension(pb2.E_ExtensionsContainer_RptExtString)
44 registerExtension(pb2.E_ExtensionsContainer_RptExtEnum)
45 registerExtension(pb2.E_ExtensionsContainer_RptExtNested)
46 registerExtension(pb2.E_MessageSetExtension)
47 registerExtension(pb2.E_MessageSetExtension_MessageSetExtension)
48 registerExtension(pb2.E_MessageSetExtension_NotMessageSetExtension)
49 registerExtension(pb2.E_MessageSetExtension_ExtNested)
50 registerExtension(pb2.E_FakeMessageSetExtension_MessageSetExtension)
51}
52
Joe Tsai4fddeba2019-03-20 18:29:32 -070053func registerExtension(xd *protoiface.ExtensionDescV1) {
Herbie Onge52379a2019-03-15 18:00:19 -070054 preg.GlobalTypes.Register(xd.Type)
55}
56
Herbie Ongc96a79d2019-03-08 10:49:17 -080057func TestUnmarshal(t *testing.T) {
58 tests := []struct {
59 desc string
Damien Neil5c5b5312019-05-14 12:44:37 -070060 umo protojson.UnmarshalOptions
Herbie Ongc96a79d2019-03-08 10:49:17 -080061 inputMessage proto.Message
62 inputText string
63 wantMessage proto.Message
64 // TODO: verify expected error message substring.
65 wantErr bool
66 }{{
67 desc: "proto2 empty message",
68 inputMessage: &pb2.Scalars{},
69 inputText: "{}",
70 wantMessage: &pb2.Scalars{},
71 }, {
72 desc: "unexpected value instead of EOF",
73 inputMessage: &pb2.Scalars{},
74 inputText: "{} {}",
75 wantErr: true,
76 }, {
77 desc: "proto2 optional scalars set to zero values",
78 inputMessage: &pb2.Scalars{},
79 inputText: `{
80 "optBool": false,
81 "optInt32": 0,
82 "optInt64": 0,
83 "optUint32": 0,
84 "optUint64": 0,
85 "optSint32": 0,
86 "optSint64": 0,
87 "optFixed32": 0,
88 "optFixed64": 0,
89 "optSfixed32": 0,
90 "optSfixed64": 0,
91 "optFloat": 0,
92 "optDouble": 0,
93 "optBytes": "",
94 "optString": ""
95}`,
96 wantMessage: &pb2.Scalars{
97 OptBool: scalar.Bool(false),
98 OptInt32: scalar.Int32(0),
99 OptInt64: scalar.Int64(0),
100 OptUint32: scalar.Uint32(0),
101 OptUint64: scalar.Uint64(0),
102 OptSint32: scalar.Int32(0),
103 OptSint64: scalar.Int64(0),
104 OptFixed32: scalar.Uint32(0),
105 OptFixed64: scalar.Uint64(0),
106 OptSfixed32: scalar.Int32(0),
107 OptSfixed64: scalar.Int64(0),
108 OptFloat: scalar.Float32(0),
109 OptDouble: scalar.Float64(0),
110 OptBytes: []byte{},
111 OptString: scalar.String(""),
112 },
113 }, {
114 desc: "proto3 scalars set to zero values",
115 inputMessage: &pb3.Scalars{},
116 inputText: `{
117 "sBool": false,
118 "sInt32": 0,
119 "sInt64": 0,
120 "sUint32": 0,
121 "sUint64": 0,
122 "sSint32": 0,
123 "sSint64": 0,
124 "sFixed32": 0,
125 "sFixed64": 0,
126 "sSfixed32": 0,
127 "sSfixed64": 0,
128 "sFloat": 0,
129 "sDouble": 0,
130 "sBytes": "",
131 "sString": ""
132}`,
133 wantMessage: &pb3.Scalars{},
134 }, {
135 desc: "proto2 optional scalars set to null",
136 inputMessage: &pb2.Scalars{},
137 inputText: `{
138 "optBool": null,
139 "optInt32": null,
140 "optInt64": null,
141 "optUint32": null,
142 "optUint64": null,
143 "optSint32": null,
144 "optSint64": null,
145 "optFixed32": null,
146 "optFixed64": null,
147 "optSfixed32": null,
148 "optSfixed64": null,
149 "optFloat": null,
150 "optDouble": null,
151 "optBytes": null,
152 "optString": null
153}`,
154 wantMessage: &pb2.Scalars{},
155 }, {
156 desc: "proto3 scalars set to null",
157 inputMessage: &pb3.Scalars{},
158 inputText: `{
159 "sBool": null,
160 "sInt32": null,
161 "sInt64": null,
162 "sUint32": null,
163 "sUint64": null,
164 "sSint32": null,
165 "sSint64": null,
166 "sFixed32": null,
167 "sFixed64": null,
168 "sSfixed32": null,
169 "sSfixed64": null,
170 "sFloat": null,
171 "sDouble": null,
172 "sBytes": null,
173 "sString": null
174}`,
175 wantMessage: &pb3.Scalars{},
176 }, {
177 desc: "boolean",
178 inputMessage: &pb3.Scalars{},
179 inputText: `{"sBool": true}`,
180 wantMessage: &pb3.Scalars{
181 SBool: true,
182 },
183 }, {
184 desc: "not boolean",
185 inputMessage: &pb3.Scalars{},
186 inputText: `{"sBool": "true"}`,
187 wantErr: true,
188 }, {
189 desc: "float and double",
190 inputMessage: &pb3.Scalars{},
191 inputText: `{
192 "sFloat": 1.234,
193 "sDouble": 5.678
194}`,
195 wantMessage: &pb3.Scalars{
196 SFloat: 1.234,
197 SDouble: 5.678,
198 },
199 }, {
200 desc: "float and double in string",
201 inputMessage: &pb3.Scalars{},
202 inputText: `{
203 "sFloat": "1.234",
204 "sDouble": "5.678"
205}`,
206 wantMessage: &pb3.Scalars{
207 SFloat: 1.234,
208 SDouble: 5.678,
209 },
210 }, {
211 desc: "float and double in E notation",
212 inputMessage: &pb3.Scalars{},
213 inputText: `{
214 "sFloat": 12.34E-1,
215 "sDouble": 5.678e4
216}`,
217 wantMessage: &pb3.Scalars{
218 SFloat: 1.234,
219 SDouble: 56780,
220 },
221 }, {
222 desc: "float and double in string E notation",
223 inputMessage: &pb3.Scalars{},
224 inputText: `{
225 "sFloat": "12.34E-1",
226 "sDouble": "5.678e4"
227}`,
228 wantMessage: &pb3.Scalars{
229 SFloat: 1.234,
230 SDouble: 56780,
231 },
232 }, {
233 desc: "float exceeds limit",
234 inputMessage: &pb3.Scalars{},
235 inputText: `{"sFloat": 3.4e39}`,
236 wantErr: true,
237 }, {
238 desc: "float in string exceeds limit",
239 inputMessage: &pb3.Scalars{},
240 inputText: `{"sFloat": "-3.4e39"}`,
241 wantErr: true,
242 }, {
243 desc: "double exceeds limit",
244 inputMessage: &pb3.Scalars{},
245 inputText: `{"sFloat": -1.79e+309}`,
246 wantErr: true,
247 }, {
248 desc: "double in string exceeds limit",
249 inputMessage: &pb3.Scalars{},
250 inputText: `{"sFloat": "1.79e+309"}`,
251 wantErr: true,
252 }, {
253 desc: "infinites",
254 inputMessage: &pb3.Scalars{},
255 inputText: `{"sFloat": "Infinity", "sDouble": "-Infinity"}`,
256 wantMessage: &pb3.Scalars{
257 SFloat: float32(math.Inf(+1)),
258 SDouble: math.Inf(-1),
259 },
260 }, {
Herbie Ong06a6b0b2019-04-24 21:15:45 -0700261 desc: "float string with leading space",
262 inputMessage: &pb3.Scalars{},
263 inputText: `{"sFloat": " 1.234"}`,
264 wantErr: true,
265 }, {
266 desc: "double string with trailing space",
267 inputMessage: &pb3.Scalars{},
268 inputText: `{"sDouble": "5.678 "}`,
269 wantErr: true,
270 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800271 desc: "not float",
272 inputMessage: &pb3.Scalars{},
273 inputText: `{"sFloat": true}`,
274 wantErr: true,
275 }, {
276 desc: "not double",
277 inputMessage: &pb3.Scalars{},
278 inputText: `{"sDouble": "not a number"}`,
279 wantErr: true,
280 }, {
281 desc: "integers",
282 inputMessage: &pb3.Scalars{},
283 inputText: `{
284 "sInt32": 1234,
285 "sInt64": -1234,
286 "sUint32": 1e2,
287 "sUint64": 100E-2,
288 "sSint32": 1.0,
289 "sSint64": -1.0,
290 "sFixed32": 1.234e+5,
291 "sFixed64": 1200E-2,
292 "sSfixed32": -1.234e05,
293 "sSfixed64": -1200e-02
294}`,
295 wantMessage: &pb3.Scalars{
296 SInt32: 1234,
297 SInt64: -1234,
298 SUint32: 100,
299 SUint64: 1,
300 SSint32: 1,
301 SSint64: -1,
302 SFixed32: 123400,
303 SFixed64: 12,
304 SSfixed32: -123400,
305 SSfixed64: -12,
306 },
307 }, {
308 desc: "integers in string",
309 inputMessage: &pb3.Scalars{},
310 inputText: `{
311 "sInt32": "1234",
312 "sInt64": "-1234",
313 "sUint32": "1e2",
314 "sUint64": "100E-2",
315 "sSint32": "1.0",
316 "sSint64": "-1.0",
317 "sFixed32": "1.234e+5",
318 "sFixed64": "1200E-2",
319 "sSfixed32": "-1.234e05",
320 "sSfixed64": "-1200e-02"
321}`,
322 wantMessage: &pb3.Scalars{
323 SInt32: 1234,
324 SInt64: -1234,
325 SUint32: 100,
326 SUint64: 1,
327 SSint32: 1,
328 SSint64: -1,
329 SFixed32: 123400,
330 SFixed64: 12,
331 SSfixed32: -123400,
332 SSfixed64: -12,
333 },
334 }, {
335 desc: "integers in escaped string",
336 inputMessage: &pb3.Scalars{},
337 inputText: `{"sInt32": "\u0031\u0032"}`,
338 wantMessage: &pb3.Scalars{
339 SInt32: 12,
340 },
341 }, {
Herbie Ong06a6b0b2019-04-24 21:15:45 -0700342 desc: "integer string with leading space",
343 inputMessage: &pb3.Scalars{},
344 inputText: `{"sInt32": " 1234"}`,
345 wantErr: true,
346 }, {
347 desc: "integer string with trailing space",
348 inputMessage: &pb3.Scalars{},
349 inputText: `{"sUint32": "1e2 "}`,
350 wantErr: true,
351 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800352 desc: "number is not an integer",
353 inputMessage: &pb3.Scalars{},
354 inputText: `{"sInt32": 1.001}`,
355 wantErr: true,
356 }, {
357 desc: "32-bit int exceeds limit",
358 inputMessage: &pb3.Scalars{},
359 inputText: `{"sInt32": 2e10}`,
360 wantErr: true,
361 }, {
362 desc: "64-bit int exceeds limit",
363 inputMessage: &pb3.Scalars{},
364 inputText: `{"sSfixed64": -9e19}`,
365 wantErr: true,
366 }, {
367 desc: "not integer",
368 inputMessage: &pb3.Scalars{},
369 inputText: `{"sInt32": "not a number"}`,
370 wantErr: true,
371 }, {
372 desc: "not unsigned integer",
373 inputMessage: &pb3.Scalars{},
374 inputText: `{"sUint32": "not a number"}`,
375 wantErr: true,
376 }, {
377 desc: "number is not an unsigned integer",
378 inputMessage: &pb3.Scalars{},
379 inputText: `{"sUint32": -1}`,
380 wantErr: true,
381 }, {
382 desc: "string",
383 inputMessage: &pb2.Scalars{},
384 inputText: `{"optString": "谷歌"}`,
385 wantMessage: &pb2.Scalars{
386 OptString: scalar.String("谷歌"),
387 },
388 }, {
389 desc: "string with invalid UTF-8",
390 inputMessage: &pb3.Scalars{},
391 inputText: "{\"sString\": \"\xff\"}",
Damien Neil8c86fc52019-06-19 09:28:29 -0700392 wantErr: true,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800393 }, {
394 desc: "not string",
395 inputMessage: &pb2.Scalars{},
396 inputText: `{"optString": 42}`,
397 wantErr: true,
398 }, {
399 desc: "bytes",
400 inputMessage: &pb3.Scalars{},
401 inputText: `{"sBytes": "aGVsbG8gd29ybGQ"}`,
402 wantMessage: &pb3.Scalars{
403 SBytes: []byte("hello world"),
404 },
405 }, {
406 desc: "bytes padded",
407 inputMessage: &pb3.Scalars{},
408 inputText: `{"sBytes": "aGVsbG8gd29ybGQ="}`,
409 wantMessage: &pb3.Scalars{
410 SBytes: []byte("hello world"),
411 },
412 }, {
413 desc: "not bytes",
414 inputMessage: &pb3.Scalars{},
415 inputText: `{"sBytes": true}`,
416 wantErr: true,
417 }, {
418 desc: "proto2 enum",
419 inputMessage: &pb2.Enums{},
420 inputText: `{
421 "optEnum": "ONE",
422 "optNestedEnum": "UNO"
423}`,
424 wantMessage: &pb2.Enums{
425 OptEnum: pb2.Enum_ONE.Enum(),
426 OptNestedEnum: pb2.Enums_UNO.Enum(),
427 },
428 }, {
429 desc: "proto3 enum",
430 inputMessage: &pb3.Enums{},
431 inputText: `{
432 "sEnum": "ONE",
433 "sNestedEnum": "DIEZ"
434}`,
435 wantMessage: &pb3.Enums{
436 SEnum: pb3.Enum_ONE,
437 SNestedEnum: pb3.Enums_DIEZ,
438 },
439 }, {
440 desc: "enum numeric value",
441 inputMessage: &pb3.Enums{},
442 inputText: `{
443 "sEnum": 2,
444 "sNestedEnum": 2
445}`,
446 wantMessage: &pb3.Enums{
447 SEnum: pb3.Enum_TWO,
448 SNestedEnum: pb3.Enums_DOS,
449 },
450 }, {
451 desc: "enum unnamed numeric value",
452 inputMessage: &pb3.Enums{},
453 inputText: `{
454 "sEnum": 101,
455 "sNestedEnum": -101
456}`,
457 wantMessage: &pb3.Enums{
458 SEnum: 101,
459 SNestedEnum: -101,
460 },
461 }, {
462 desc: "enum set to number string",
463 inputMessage: &pb3.Enums{},
464 inputText: `{
Herbie Ong300b9fe2019-03-29 15:42:20 -0700465 "sEnum": "1"
Herbie Ongc96a79d2019-03-08 10:49:17 -0800466}`,
467 wantErr: true,
468 }, {
469 desc: "enum set to invalid named",
470 inputMessage: &pb3.Enums{},
471 inputText: `{
Herbie Ong300b9fe2019-03-29 15:42:20 -0700472 "sEnum": "UNNAMED"
Herbie Ongc96a79d2019-03-08 10:49:17 -0800473}`,
474 wantErr: true,
475 }, {
476 desc: "enum set to not enum",
477 inputMessage: &pb3.Enums{},
478 inputText: `{
Herbie Ong300b9fe2019-03-29 15:42:20 -0700479 "sEnum": true
Herbie Ongc96a79d2019-03-08 10:49:17 -0800480}`,
481 wantErr: true,
482 }, {
Herbie Ong300b9fe2019-03-29 15:42:20 -0700483 desc: "enum set to JSON null",
484 inputMessage: &pb3.Enums{},
485 inputText: `{
486 "sEnum": null
487}`,
488 wantMessage: &pb3.Enums{},
489 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800490 desc: "proto name",
491 inputMessage: &pb3.JSONNames{},
492 inputText: `{
493 "s_string": "proto name used"
494}`,
495 wantMessage: &pb3.JSONNames{
496 SString: "proto name used",
497 },
498 }, {
499 desc: "json_name",
500 inputMessage: &pb3.JSONNames{},
501 inputText: `{
502 "foo_bar": "json_name used"
503}`,
504 wantMessage: &pb3.JSONNames{
505 SString: "json_name used",
506 },
507 }, {
508 desc: "camelCase name",
509 inputMessage: &pb3.JSONNames{},
510 inputText: `{
511 "sString": "camelcase used"
512}`,
513 wantErr: true,
514 }, {
515 desc: "proto name and json_name",
516 inputMessage: &pb3.JSONNames{},
517 inputText: `{
518 "foo_bar": "json_name used",
519 "s_string": "proto name used"
520}`,
521 wantErr: true,
522 }, {
523 desc: "duplicate field names",
524 inputMessage: &pb3.JSONNames{},
525 inputText: `{
526 "foo_bar": "one",
527 "foo_bar": "two",
528}`,
529 wantErr: true,
530 }, {
531 desc: "null message",
532 inputMessage: &pb2.Nests{},
533 inputText: "null",
534 wantErr: true,
535 }, {
536 desc: "proto2 nested message not set",
537 inputMessage: &pb2.Nests{},
538 inputText: "{}",
539 wantMessage: &pb2.Nests{},
540 }, {
541 desc: "proto2 nested message set to null",
542 inputMessage: &pb2.Nests{},
543 inputText: `{
544 "optNested": null,
545 "optgroup": null
546}`,
547 wantMessage: &pb2.Nests{},
548 }, {
549 desc: "proto2 nested message set to empty",
550 inputMessage: &pb2.Nests{},
551 inputText: `{
552 "optNested": {},
553 "optgroup": {}
554}`,
555 wantMessage: &pb2.Nests{
556 OptNested: &pb2.Nested{},
557 Optgroup: &pb2.Nests_OptGroup{},
558 },
559 }, {
560 desc: "proto2 nested messages",
561 inputMessage: &pb2.Nests{},
562 inputText: `{
563 "optNested": {
564 "optString": "nested message",
565 "optNested": {
566 "optString": "another nested message"
567 }
568 }
569}`,
570 wantMessage: &pb2.Nests{
571 OptNested: &pb2.Nested{
572 OptString: scalar.String("nested message"),
573 OptNested: &pb2.Nested{
574 OptString: scalar.String("another nested message"),
575 },
576 },
577 },
578 }, {
579 desc: "proto2 groups",
580 inputMessage: &pb2.Nests{},
581 inputText: `{
582 "optgroup": {
583 "optString": "inside a group",
584 "optNested": {
585 "optString": "nested message inside a group"
586 },
587 "optnestedgroup": {
588 "optFixed32": 47
589 }
590 }
591}`,
592 wantMessage: &pb2.Nests{
593 Optgroup: &pb2.Nests_OptGroup{
594 OptString: scalar.String("inside a group"),
595 OptNested: &pb2.Nested{
596 OptString: scalar.String("nested message inside a group"),
597 },
598 Optnestedgroup: &pb2.Nests_OptGroup_OptNestedGroup{
599 OptFixed32: scalar.Uint32(47),
600 },
601 },
602 },
603 }, {
604 desc: "proto3 nested message not set",
605 inputMessage: &pb3.Nests{},
606 inputText: "{}",
607 wantMessage: &pb3.Nests{},
608 }, {
609 desc: "proto3 nested message set to null",
610 inputMessage: &pb3.Nests{},
611 inputText: `{"sNested": null}`,
612 wantMessage: &pb3.Nests{},
613 }, {
614 desc: "proto3 nested message set to empty",
615 inputMessage: &pb3.Nests{},
616 inputText: `{"sNested": {}}`,
617 wantMessage: &pb3.Nests{
618 SNested: &pb3.Nested{},
619 },
620 }, {
621 desc: "proto3 nested message",
622 inputMessage: &pb3.Nests{},
623 inputText: `{
624 "sNested": {
625 "sString": "nested message",
626 "sNested": {
627 "sString": "another nested message"
628 }
629 }
630}`,
631 wantMessage: &pb3.Nests{
632 SNested: &pb3.Nested{
633 SString: "nested message",
634 SNested: &pb3.Nested{
635 SString: "another nested message",
636 },
637 },
638 },
639 }, {
640 desc: "message set to non-message",
641 inputMessage: &pb3.Nests{},
642 inputText: `"not valid"`,
643 wantErr: true,
644 }, {
645 desc: "nested message set to non-message",
646 inputMessage: &pb3.Nests{},
647 inputText: `{"sNested": true}`,
648 wantErr: true,
649 }, {
650 desc: "oneof not set",
651 inputMessage: &pb3.Oneofs{},
652 inputText: "{}",
653 wantMessage: &pb3.Oneofs{},
654 }, {
655 desc: "oneof set to empty string",
656 inputMessage: &pb3.Oneofs{},
657 inputText: `{"oneofString": ""}`,
658 wantMessage: &pb3.Oneofs{
659 Union: &pb3.Oneofs_OneofString{},
660 },
661 }, {
662 desc: "oneof set to string",
663 inputMessage: &pb3.Oneofs{},
664 inputText: `{"oneofString": "hello"}`,
665 wantMessage: &pb3.Oneofs{
666 Union: &pb3.Oneofs_OneofString{
667 OneofString: "hello",
668 },
669 },
670 }, {
671 desc: "oneof set to enum",
672 inputMessage: &pb3.Oneofs{},
673 inputText: `{"oneofEnum": "ZERO"}`,
674 wantMessage: &pb3.Oneofs{
675 Union: &pb3.Oneofs_OneofEnum{
676 OneofEnum: pb3.Enum_ZERO,
677 },
678 },
679 }, {
680 desc: "oneof set to empty message",
681 inputMessage: &pb3.Oneofs{},
682 inputText: `{"oneofNested": {}}`,
683 wantMessage: &pb3.Oneofs{
684 Union: &pb3.Oneofs_OneofNested{
685 OneofNested: &pb3.Nested{},
686 },
687 },
688 }, {
689 desc: "oneof set to message",
690 inputMessage: &pb3.Oneofs{},
691 inputText: `{
692 "oneofNested": {
693 "sString": "nested message"
694 }
695}`,
696 wantMessage: &pb3.Oneofs{
697 Union: &pb3.Oneofs_OneofNested{
698 OneofNested: &pb3.Nested{
699 SString: "nested message",
700 },
701 },
702 },
703 }, {
Herbie Ong8a1d4602019-04-02 20:19:36 -0700704 desc: "oneof set to more than one field",
705 inputMessage: &pb3.Oneofs{},
706 inputText: `{
707 "oneofEnum": "ZERO",
708 "oneofString": "hello"
709}`,
710 wantErr: true,
711 }, {
712 desc: "oneof set to null and value",
713 inputMessage: &pb3.Oneofs{},
714 inputText: `{
715 "oneofEnum": "ZERO",
716 "oneofString": null
717}`,
718 wantMessage: &pb3.Oneofs{
719 Union: &pb3.Oneofs_OneofEnum{
720 OneofEnum: pb3.Enum_ZERO,
721 },
722 },
723 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800724 desc: "repeated null fields",
725 inputMessage: &pb2.Repeats{},
726 inputText: `{
727 "rptString": null,
728 "rptInt32" : null,
729 "rptFloat" : null,
730 "rptBytes" : null
731}`,
732 wantMessage: &pb2.Repeats{},
733 }, {
734 desc: "repeated scalars",
735 inputMessage: &pb2.Repeats{},
736 inputText: `{
737 "rptString": ["hello", "world"],
738 "rptInt32" : [-1, 0, 1],
739 "rptBool" : [false, true]
740}`,
741 wantMessage: &pb2.Repeats{
742 RptString: []string{"hello", "world"},
743 RptInt32: []int32{-1, 0, 1},
744 RptBool: []bool{false, true},
745 },
746 }, {
747 desc: "repeated enums",
748 inputMessage: &pb2.Enums{},
749 inputText: `{
750 "rptEnum" : ["TEN", 1, 42],
751 "rptNestedEnum": ["DOS", 2, -47]
752}`,
753 wantMessage: &pb2.Enums{
754 RptEnum: []pb2.Enum{pb2.Enum_TEN, pb2.Enum_ONE, 42},
755 RptNestedEnum: []pb2.Enums_NestedEnum{pb2.Enums_DOS, pb2.Enums_DOS, -47},
756 },
757 }, {
758 desc: "repeated messages",
759 inputMessage: &pb2.Nests{},
760 inputText: `{
761 "rptNested": [
762 {
763 "optString": "repeat nested one"
764 },
765 {
766 "optString": "repeat nested two",
767 "optNested": {
768 "optString": "inside repeat nested two"
769 }
770 },
771 {}
772 ]
773}`,
774 wantMessage: &pb2.Nests{
775 RptNested: []*pb2.Nested{
776 {
777 OptString: scalar.String("repeat nested one"),
778 },
779 {
780 OptString: scalar.String("repeat nested two"),
781 OptNested: &pb2.Nested{
782 OptString: scalar.String("inside repeat nested two"),
783 },
784 },
785 {},
786 },
787 },
788 }, {
789 desc: "repeated groups",
790 inputMessage: &pb2.Nests{},
791 inputText: `{
792 "rptgroup": [
793 {
794 "rptString": ["hello", "world"]
795 },
796 {}
797 ]
798}
799`,
800 wantMessage: &pb2.Nests{
801 Rptgroup: []*pb2.Nests_RptGroup{
802 {
803 RptString: []string{"hello", "world"},
804 },
805 {},
806 },
807 },
808 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -0700809 desc: "repeated string contains invalid UTF8",
810 inputMessage: &pb2.Repeats{},
811 inputText: `{"rptString": ["` + "abc\xff" + `"]}`,
Damien Neil8c86fc52019-06-19 09:28:29 -0700812 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -0700813 }, {
814 desc: "repeated messages contain invalid UTF8",
815 inputMessage: &pb2.Nests{},
816 inputText: `{"rptNested": [{"optString": "` + "abc\xff" + `"}]}`,
Damien Neil8c86fc52019-06-19 09:28:29 -0700817 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -0700818 }, {
819 desc: "repeated scalars contain invalid type",
Herbie Ongc96a79d2019-03-08 10:49:17 -0800820 inputMessage: &pb2.Repeats{},
821 inputText: `{"rptString": ["hello", null, "world"]}`,
822 wantErr: true,
823 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -0700824 desc: "repeated messages contain invalid type",
Herbie Ongc96a79d2019-03-08 10:49:17 -0800825 inputMessage: &pb2.Nests{},
826 inputText: `{"rptNested": [{}, null]}`,
827 wantErr: true,
828 }, {
829 desc: "map fields 1",
830 inputMessage: &pb3.Maps{},
831 inputText: `{
832 "int32ToStr": {
833 "-101": "-101",
834 "0" : "zero",
835 "255" : "0xff"
836 },
837 "boolToUint32": {
838 "false": 101,
839 "true" : "42"
840 }
841}`,
842 wantMessage: &pb3.Maps{
843 Int32ToStr: map[int32]string{
844 -101: "-101",
845 0xff: "0xff",
846 0: "zero",
847 },
848 BoolToUint32: map[bool]uint32{
849 true: 42,
850 false: 101,
851 },
852 },
853 }, {
854 desc: "map fields 2",
855 inputMessage: &pb3.Maps{},
856 inputText: `{
857 "uint64ToEnum": {
858 "1" : "ONE",
859 "2" : 2,
860 "10": 101
861 }
862}`,
863 wantMessage: &pb3.Maps{
864 Uint64ToEnum: map[uint64]pb3.Enum{
865 1: pb3.Enum_ONE,
866 2: pb3.Enum_TWO,
867 10: 101,
868 },
869 },
870 }, {
871 desc: "map fields 3",
872 inputMessage: &pb3.Maps{},
873 inputText: `{
874 "strToNested": {
875 "nested_one": {
876 "sString": "nested in a map"
877 },
878 "nested_two": {}
879 }
880}`,
881 wantMessage: &pb3.Maps{
882 StrToNested: map[string]*pb3.Nested{
883 "nested_one": {
884 SString: "nested in a map",
885 },
886 "nested_two": {},
887 },
888 },
889 }, {
890 desc: "map fields 4",
891 inputMessage: &pb3.Maps{},
892 inputText: `{
893 "strToOneofs": {
894 "nested": {
895 "oneofNested": {
896 "sString": "nested oneof in map field value"
897 }
898 },
899 "string": {
900 "oneofString": "hello"
901 }
902 }
903}`,
904 wantMessage: &pb3.Maps{
905 StrToOneofs: map[string]*pb3.Oneofs{
906 "string": {
907 Union: &pb3.Oneofs_OneofString{
908 OneofString: "hello",
909 },
910 },
911 "nested": {
912 Union: &pb3.Oneofs_OneofNested{
913 OneofNested: &pb3.Nested{
914 SString: "nested oneof in map field value",
915 },
916 },
917 },
918 },
919 },
920 }, {
921 desc: "map contains duplicate keys",
922 inputMessage: &pb3.Maps{},
923 inputText: `{
924 "int32ToStr": {
925 "0": "cero",
926 "0": "zero"
927 }
928}
929`,
930 wantErr: true,
931 }, {
932 desc: "map key empty string",
933 inputMessage: &pb3.Maps{},
934 inputText: `{
935 "strToNested": {
936 "": {}
937 }
938}`,
939 wantMessage: &pb3.Maps{
940 StrToNested: map[string]*pb3.Nested{
941 "": {},
942 },
943 },
944 }, {
945 desc: "map contains invalid key 1",
946 inputMessage: &pb3.Maps{},
947 inputText: `{
948 "int32ToStr": {
949 "invalid": "cero"
950}`,
951 wantErr: true,
952 }, {
953 desc: "map contains invalid key 2",
954 inputMessage: &pb3.Maps{},
955 inputText: `{
956 "int32ToStr": {
957 "1.02": "float"
958}`,
959 wantErr: true,
960 }, {
961 desc: "map contains invalid key 3",
962 inputMessage: &pb3.Maps{},
963 inputText: `{
964 "int32ToStr": {
965 "2147483648": "exceeds 32-bit integer max limit"
966}`,
967 wantErr: true,
968 }, {
969 desc: "map contains invalid key 4",
970 inputMessage: &pb3.Maps{},
971 inputText: `{
972 "uint64ToEnum": {
973 "-1": 0
974 }
975}`,
976 wantErr: true,
977 }, {
978 desc: "map contains invalid value",
979 inputMessage: &pb3.Maps{},
980 inputText: `{
981 "int32ToStr": {
982 "101": true
983}`,
984 wantErr: true,
985 }, {
986 desc: "map contains null for scalar value",
987 inputMessage: &pb3.Maps{},
988 inputText: `{
989 "int32ToStr": {
990 "101": null
991}`,
992 wantErr: true,
993 }, {
994 desc: "map contains null for message value",
995 inputMessage: &pb3.Maps{},
996 inputText: `{
997 "strToNested": {
998 "hello": null
999 }
1000}`,
1001 wantErr: true,
Herbie Onge52379a2019-03-15 18:00:19 -07001002 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -07001003 desc: "map contains contains message value with invalid UTF8",
1004 inputMessage: &pb3.Maps{},
1005 inputText: `{
1006 "strToNested": {
1007 "hello": {
1008 "sString": "` + "abc\xff" + `"
1009 }
1010 }
1011}`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001012 wantErr: true,
1013 }, {
1014 desc: "map key contains invalid UTF8",
1015 inputMessage: &pb3.Maps{},
1016 inputText: `{
1017 "strToNested": {
1018 "` + "abc\xff" + `": {}
1019 }
1020}`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001021 wantErr: true,
1022 }, {
Herbie Ong329be5b2019-03-27 14:47:59 -07001023 desc: "required fields not set",
1024 inputMessage: &pb2.Requireds{},
1025 wantErr: true,
1026 }, {
1027 desc: "required field set",
1028 inputMessage: &pb2.PartialRequired{},
1029 inputText: `{
1030 "reqString": "this is required"
1031}`,
1032 wantMessage: &pb2.PartialRequired{
1033 ReqString: scalar.String("this is required"),
1034 },
1035 }, {
1036 desc: "required fields partially set",
1037 inputMessage: &pb2.Requireds{},
1038 inputText: `{
1039 "reqBool": false,
1040 "reqSfixed64": 42,
1041 "reqString": "hello",
1042 "reqEnum": "ONE"
1043}`,
1044 wantMessage: &pb2.Requireds{
1045 ReqBool: scalar.Bool(false),
1046 ReqSfixed64: scalar.Int64(42),
1047 ReqString: scalar.String("hello"),
1048 ReqEnum: pb2.Enum_ONE.Enum(),
1049 },
1050 wantErr: true,
1051 }, {
1052 desc: "required fields partially set with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001053 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001054 inputMessage: &pb2.Requireds{},
1055 inputText: `{
1056 "reqBool": false,
1057 "reqSfixed64": 42,
1058 "reqString": "hello",
1059 "reqEnum": "ONE"
1060}`,
1061 wantMessage: &pb2.Requireds{
1062 ReqBool: scalar.Bool(false),
1063 ReqSfixed64: scalar.Int64(42),
1064 ReqString: scalar.String("hello"),
1065 ReqEnum: pb2.Enum_ONE.Enum(),
1066 },
1067 }, {
1068 desc: "required fields all set",
1069 inputMessage: &pb2.Requireds{},
1070 inputText: `{
1071 "reqBool": false,
1072 "reqSfixed64": 42,
1073 "reqDouble": 1.23,
1074 "reqString": "hello",
1075 "reqEnum": "ONE",
1076 "reqNested": {}
1077}`,
1078 wantMessage: &pb2.Requireds{
1079 ReqBool: scalar.Bool(false),
1080 ReqSfixed64: scalar.Int64(42),
1081 ReqDouble: scalar.Float64(1.23),
1082 ReqString: scalar.String("hello"),
1083 ReqEnum: pb2.Enum_ONE.Enum(),
1084 ReqNested: &pb2.Nested{},
1085 },
1086 }, {
1087 desc: "indirect required field",
1088 inputMessage: &pb2.IndirectRequired{},
1089 inputText: `{
1090 "optNested": {}
1091}`,
1092 wantMessage: &pb2.IndirectRequired{
1093 OptNested: &pb2.NestedWithRequired{},
1094 },
1095 wantErr: true,
1096 }, {
1097 desc: "indirect required field with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001098 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001099 inputMessage: &pb2.IndirectRequired{},
1100 inputText: `{
1101 "optNested": {}
1102}`,
1103 wantMessage: &pb2.IndirectRequired{
1104 OptNested: &pb2.NestedWithRequired{},
1105 },
1106 }, {
1107 desc: "indirect required field in repeated",
1108 inputMessage: &pb2.IndirectRequired{},
1109 inputText: `{
1110 "rptNested": [
1111 {"reqString": "one"},
1112 {}
1113 ]
1114}`,
1115 wantMessage: &pb2.IndirectRequired{
1116 RptNested: []*pb2.NestedWithRequired{
1117 {
1118 ReqString: scalar.String("one"),
1119 },
1120 {},
1121 },
1122 },
1123 wantErr: true,
1124 }, {
1125 desc: "indirect required field in repeated with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001126 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001127 inputMessage: &pb2.IndirectRequired{},
1128 inputText: `{
1129 "rptNested": [
1130 {"reqString": "one"},
1131 {}
1132 ]
1133}`,
1134 wantMessage: &pb2.IndirectRequired{
1135 RptNested: []*pb2.NestedWithRequired{
1136 {
1137 ReqString: scalar.String("one"),
1138 },
1139 {},
1140 },
1141 },
1142 }, {
1143 desc: "indirect required field in map",
1144 inputMessage: &pb2.IndirectRequired{},
1145 inputText: `{
1146 "strToNested": {
1147 "missing": {},
1148 "contains": {
1149 "reqString": "here"
1150 }
1151 }
1152}`,
1153 wantMessage: &pb2.IndirectRequired{
1154 StrToNested: map[string]*pb2.NestedWithRequired{
1155 "missing": &pb2.NestedWithRequired{},
1156 "contains": &pb2.NestedWithRequired{
1157 ReqString: scalar.String("here"),
1158 },
1159 },
1160 },
1161 wantErr: true,
1162 }, {
1163 desc: "indirect required field in map with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001164 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001165 inputMessage: &pb2.IndirectRequired{},
1166 inputText: `{
1167 "strToNested": {
1168 "missing": {},
1169 "contains": {
1170 "reqString": "here"
1171 }
1172 }
1173}`,
1174 wantMessage: &pb2.IndirectRequired{
1175 StrToNested: map[string]*pb2.NestedWithRequired{
1176 "missing": &pb2.NestedWithRequired{},
1177 "contains": &pb2.NestedWithRequired{
1178 ReqString: scalar.String("here"),
1179 },
1180 },
1181 },
1182 }, {
1183 desc: "indirect required field in oneof",
1184 inputMessage: &pb2.IndirectRequired{},
1185 inputText: `{
1186 "oneofNested": {}
1187}`,
1188 wantMessage: &pb2.IndirectRequired{
1189 Union: &pb2.IndirectRequired_OneofNested{
1190 OneofNested: &pb2.NestedWithRequired{},
1191 },
1192 },
1193 wantErr: true,
1194 }, {
1195 desc: "indirect required field in oneof with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001196 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001197 inputMessage: &pb2.IndirectRequired{},
1198 inputText: `{
1199 "oneofNested": {}
1200}`,
1201 wantMessage: &pb2.IndirectRequired{
1202 Union: &pb2.IndirectRequired_OneofNested{
1203 OneofNested: &pb2.NestedWithRequired{},
1204 },
1205 },
1206 }, {
Herbie Onge52379a2019-03-15 18:00:19 -07001207 desc: "extensions of non-repeated fields",
1208 inputMessage: &pb2.Extensions{},
1209 inputText: `{
1210 "optString": "non-extension field",
1211 "optBool": true,
1212 "optInt32": 42,
1213 "[pb2.opt_ext_bool]": true,
1214 "[pb2.opt_ext_nested]": {
1215 "optString": "nested in an extension",
Herbie Onge63c4c42019-03-22 22:20:22 -07001216 "optNested": {
1217 "optString": "another nested in an extension"
Herbie Onge52379a2019-03-15 18:00:19 -07001218 }
1219 },
1220 "[pb2.opt_ext_string]": "extension field",
1221 "[pb2.opt_ext_enum]": "TEN"
1222}`,
1223 wantMessage: func() proto.Message {
1224 m := &pb2.Extensions{
1225 OptString: scalar.String("non-extension field"),
1226 OptBool: scalar.Bool(true),
1227 OptInt32: scalar.Int32(42),
1228 }
1229 setExtension(m, pb2.E_OptExtBool, true)
1230 setExtension(m, pb2.E_OptExtString, "extension field")
1231 setExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
1232 setExtension(m, pb2.E_OptExtNested, &pb2.Nested{
1233 OptString: scalar.String("nested in an extension"),
1234 OptNested: &pb2.Nested{
1235 OptString: scalar.String("another nested in an extension"),
1236 },
1237 })
1238 return m
1239 }(),
1240 }, {
1241 desc: "extensions of repeated fields",
1242 inputMessage: &pb2.Extensions{},
1243 inputText: `{
1244 "[pb2.rpt_ext_enum]": ["TEN", 101, "ONE"],
1245 "[pb2.rpt_ext_fixed32]": [42, 47],
1246 "[pb2.rpt_ext_nested]": [
1247 {"optString": "one"},
1248 {"optString": "two"},
1249 {"optString": "three"}
1250 ]
1251}`,
1252 wantMessage: func() proto.Message {
1253 m := &pb2.Extensions{}
1254 setExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
1255 setExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
1256 setExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
1257 &pb2.Nested{OptString: scalar.String("one")},
1258 &pb2.Nested{OptString: scalar.String("two")},
1259 &pb2.Nested{OptString: scalar.String("three")},
1260 })
1261 return m
1262 }(),
1263 }, {
1264 desc: "extensions of non-repeated fields in another message",
1265 inputMessage: &pb2.Extensions{},
1266 inputText: `{
1267 "[pb2.ExtensionsContainer.opt_ext_bool]": true,
1268 "[pb2.ExtensionsContainer.opt_ext_enum]": "TEN",
1269 "[pb2.ExtensionsContainer.opt_ext_nested]": {
1270 "optString": "nested in an extension",
1271 "optNested": {
1272 "optString": "another nested in an extension"
1273 }
1274 },
1275 "[pb2.ExtensionsContainer.opt_ext_string]": "extension field"
1276}`,
1277 wantMessage: func() proto.Message {
1278 m := &pb2.Extensions{}
1279 setExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
1280 setExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
1281 setExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
1282 setExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
1283 OptString: scalar.String("nested in an extension"),
1284 OptNested: &pb2.Nested{
1285 OptString: scalar.String("another nested in an extension"),
1286 },
1287 })
1288 return m
1289 }(),
1290 }, {
1291 desc: "extensions of repeated fields in another message",
1292 inputMessage: &pb2.Extensions{},
1293 inputText: `{
1294 "optString": "non-extension field",
1295 "optBool": true,
1296 "optInt32": 42,
1297 "[pb2.ExtensionsContainer.rpt_ext_nested]": [
1298 {"optString": "one"},
1299 {"optString": "two"},
1300 {"optString": "three"}
1301 ],
1302 "[pb2.ExtensionsContainer.rpt_ext_enum]": ["TEN", 101, "ONE"],
1303 "[pb2.ExtensionsContainer.rpt_ext_string]": ["hello", "world"]
1304}`,
1305 wantMessage: func() proto.Message {
1306 m := &pb2.Extensions{
1307 OptString: scalar.String("non-extension field"),
1308 OptBool: scalar.Bool(true),
1309 OptInt32: scalar.Int32(42),
1310 }
1311 setExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
1312 setExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
1313 setExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
1314 &pb2.Nested{OptString: scalar.String("one")},
1315 &pb2.Nested{OptString: scalar.String("two")},
1316 &pb2.Nested{OptString: scalar.String("three")},
1317 })
1318 return m
1319 }(),
1320 }, {
1321 desc: "invalid extension field name",
1322 inputMessage: &pb2.Extensions{},
1323 inputText: `{ "[pb2.invalid_message_field]": true }`,
1324 wantErr: true,
1325 }, {
1326 desc: "MessageSet",
1327 inputMessage: &pb2.MessageSet{},
1328 inputText: `{
1329 "[pb2.MessageSetExtension]": {
1330 "optString": "a messageset extension"
1331 },
1332 "[pb2.MessageSetExtension.ext_nested]": {
1333 "optString": "just a regular extension"
1334 },
1335 "[pb2.MessageSetExtension.not_message_set_extension]": {
1336 "optString": "not a messageset extension"
1337 }
1338}`,
1339 wantMessage: func() proto.Message {
1340 m := &pb2.MessageSet{}
1341 setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
1342 OptString: scalar.String("a messageset extension"),
1343 })
1344 setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
1345 OptString: scalar.String("not a messageset extension"),
1346 })
1347 setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
1348 OptString: scalar.String("just a regular extension"),
1349 })
1350 return m
1351 }(),
1352 }, {
Herbie Onge52379a2019-03-15 18:00:19 -07001353 desc: "extensions of repeated field contains null",
1354 inputMessage: &pb2.Extensions{},
1355 inputText: `{
1356 "[pb2.ExtensionsContainer.rpt_ext_nested]": [
1357 {"optString": "one"},
1358 null,
1359 {"optString": "three"}
1360 ],
1361}`,
1362 wantErr: true,
1363 }, {
1364 desc: "not real MessageSet 1",
1365 inputMessage: &pb2.FakeMessageSet{},
1366 inputText: `{
1367 "[pb2.FakeMessageSetExtension.message_set_extension]": {
1368 "optString": "not a messageset extension"
1369 }
1370}`,
1371 wantMessage: func() proto.Message {
1372 m := &pb2.FakeMessageSet{}
1373 setExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
1374 OptString: scalar.String("not a messageset extension"),
1375 })
1376 return m
1377 }(),
1378 }, {
1379 desc: "not real MessageSet 2",
1380 inputMessage: &pb2.FakeMessageSet{},
1381 inputText: `{
1382 "[pb2.FakeMessageSetExtension]": {
1383 "optString": "not a messageset extension"
1384 }
1385}`,
1386 wantErr: true,
1387 }, {
1388 desc: "not real MessageSet 3",
1389 inputMessage: &pb2.MessageSet{},
1390 inputText: `{
1391 "[pb2.message_set_extension]": {
1392 "optString": "another not a messageset extension"
1393 }
1394}`,
1395 wantMessage: func() proto.Message {
1396 m := &pb2.MessageSet{}
1397 setExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
1398 OptString: scalar.String("another not a messageset extension"),
1399 })
1400 return m
1401 }(),
Herbie Onge63c4c42019-03-22 22:20:22 -07001402 }, {
1403 desc: "Empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001404 inputMessage: &emptypb.Empty{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001405 inputText: `{}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001406 wantMessage: &emptypb.Empty{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001407 }, {
1408 desc: "Empty contains unknown",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001409 inputMessage: &emptypb.Empty{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001410 inputText: `{"unknown": null}`,
1411 wantErr: true,
1412 }, {
1413 desc: "BoolValue false",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001414 inputMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001415 inputText: `false`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001416 wantMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001417 }, {
1418 desc: "BoolValue true",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001419 inputMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001420 inputText: `true`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001421 wantMessage: &wrapperspb.BoolValue{Value: true},
Herbie Onge63c4c42019-03-22 22:20:22 -07001422 }, {
1423 desc: "BoolValue invalid value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001424 inputMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001425 inputText: `{}`,
1426 wantErr: true,
1427 }, {
1428 desc: "Int32Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001429 inputMessage: &wrapperspb.Int32Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001430 inputText: `42`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001431 wantMessage: &wrapperspb.Int32Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001432 }, {
1433 desc: "Int32Value in JSON string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001434 inputMessage: &wrapperspb.Int32Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001435 inputText: `"1.23e3"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001436 wantMessage: &wrapperspb.Int32Value{Value: 1230},
Herbie Onge63c4c42019-03-22 22:20:22 -07001437 }, {
1438 desc: "Int64Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001439 inputMessage: &wrapperspb.Int64Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001440 inputText: `"42"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001441 wantMessage: &wrapperspb.Int64Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001442 }, {
1443 desc: "UInt32Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001444 inputMessage: &wrapperspb.UInt32Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001445 inputText: `42`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001446 wantMessage: &wrapperspb.UInt32Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001447 }, {
1448 desc: "UInt64Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001449 inputMessage: &wrapperspb.UInt64Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001450 inputText: `"42"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001451 wantMessage: &wrapperspb.UInt64Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001452 }, {
1453 desc: "FloatValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001454 inputMessage: &wrapperspb.FloatValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001455 inputText: `1.02`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001456 wantMessage: &wrapperspb.FloatValue{Value: 1.02},
Herbie Onge63c4c42019-03-22 22:20:22 -07001457 }, {
1458 desc: "FloatValue exceeds max limit",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001459 inputMessage: &wrapperspb.FloatValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001460 inputText: `1.23+40`,
1461 wantErr: true,
1462 }, {
1463 desc: "FloatValue Infinity",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001464 inputMessage: &wrapperspb.FloatValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001465 inputText: `"-Infinity"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001466 wantMessage: &wrapperspb.FloatValue{Value: float32(math.Inf(-1))},
Herbie Onge63c4c42019-03-22 22:20:22 -07001467 }, {
1468 desc: "DoubleValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001469 inputMessage: &wrapperspb.DoubleValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001470 inputText: `1.02`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001471 wantMessage: &wrapperspb.DoubleValue{Value: 1.02},
Herbie Onge63c4c42019-03-22 22:20:22 -07001472 }, {
1473 desc: "DoubleValue Infinity",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001474 inputMessage: &wrapperspb.DoubleValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001475 inputText: `"Infinity"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001476 wantMessage: &wrapperspb.DoubleValue{Value: math.Inf(+1)},
Herbie Onge63c4c42019-03-22 22:20:22 -07001477 }, {
1478 desc: "StringValue empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001479 inputMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001480 inputText: `""`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001481 wantMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001482 }, {
1483 desc: "StringValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001484 inputMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001485 inputText: `"谷歌"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001486 wantMessage: &wrapperspb.StringValue{Value: "谷歌"},
Herbie Onge63c4c42019-03-22 22:20:22 -07001487 }, {
1488 desc: "StringValue with invalid UTF8 error",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001489 inputMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001490 inputText: "\"abc\xff\"",
Herbie Onge63c4c42019-03-22 22:20:22 -07001491 wantErr: true,
1492 }, {
1493 desc: "StringValue field with invalid UTF8 error",
1494 inputMessage: &pb2.KnownTypes{},
1495 inputText: "{\n \"optString\": \"abc\xff\"\n}",
Damien Neil8c86fc52019-06-19 09:28:29 -07001496 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -07001497 }, {
Herbie Ong300b9fe2019-03-29 15:42:20 -07001498 desc: "NullValue field with JSON null",
1499 inputMessage: &pb2.KnownTypes{},
1500 inputText: `{
1501 "optNull": null
1502}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001503 wantMessage: &pb2.KnownTypes{OptNull: new(structpb.NullValue)},
Herbie Ong300b9fe2019-03-29 15:42:20 -07001504 }, {
1505 desc: "NullValue field with string",
1506 inputMessage: &pb2.KnownTypes{},
1507 inputText: `{
1508 "optNull": "NULL_VALUE"
1509}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001510 wantMessage: &pb2.KnownTypes{OptNull: new(structpb.NullValue)},
Herbie Ong300b9fe2019-03-29 15:42:20 -07001511 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -07001512 desc: "BytesValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001513 inputMessage: &wrapperspb.BytesValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001514 inputText: `"aGVsbG8="`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001515 wantMessage: &wrapperspb.BytesValue{Value: []byte("hello")},
Herbie Onge63c4c42019-03-22 22:20:22 -07001516 }, {
1517 desc: "Value null",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001518 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001519 inputText: `null`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001520 wantMessage: &structpb.Value{Kind: &structpb.Value_NullValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001521 }, {
1522 desc: "Value field null",
1523 inputMessage: &pb2.KnownTypes{},
1524 inputText: `{
1525 "optValue": null
1526}`,
1527 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001528 OptValue: &structpb.Value{Kind: &structpb.Value_NullValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001529 },
1530 }, {
1531 desc: "Value bool",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001532 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001533 inputText: `false`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001534 wantMessage: &structpb.Value{Kind: &structpb.Value_BoolValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001535 }, {
1536 desc: "Value field bool",
1537 inputMessage: &pb2.KnownTypes{},
1538 inputText: `{
1539 "optValue": true
1540}`,
1541 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001542 OptValue: &structpb.Value{Kind: &structpb.Value_BoolValue{true}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001543 },
1544 }, {
1545 desc: "Value number",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001546 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001547 inputText: `1.02`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001548 wantMessage: &structpb.Value{Kind: &structpb.Value_NumberValue{1.02}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001549 }, {
1550 desc: "Value field number",
1551 inputMessage: &pb2.KnownTypes{},
1552 inputText: `{
1553 "optValue": 1.02
1554}`,
1555 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001556 OptValue: &structpb.Value{Kind: &structpb.Value_NumberValue{1.02}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001557 },
1558 }, {
1559 desc: "Value string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001560 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001561 inputText: `"hello"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001562 wantMessage: &structpb.Value{Kind: &structpb.Value_StringValue{"hello"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001563 }, {
1564 desc: "Value string with invalid UTF8",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001565 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001566 inputText: "\"\xff\"",
Herbie Onge63c4c42019-03-22 22:20:22 -07001567 wantErr: true,
1568 }, {
1569 desc: "Value field string",
1570 inputMessage: &pb2.KnownTypes{},
1571 inputText: `{
1572 "optValue": "NaN"
1573}`,
1574 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001575 OptValue: &structpb.Value{Kind: &structpb.Value_StringValue{"NaN"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001576 },
1577 }, {
1578 desc: "Value field string with invalid UTF8",
1579 inputMessage: &pb2.KnownTypes{},
1580 inputText: `{
1581 "optValue": "` + "\xff" + `"
1582}`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001583 wantErr: true,
1584 }, {
1585 desc: "Value empty struct",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001586 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001587 inputText: `{}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001588 wantMessage: &structpb.Value{
1589 Kind: &structpb.Value_StructValue{
1590 &structpb.Struct{Fields: map[string]*structpb.Value{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001591 },
1592 },
1593 }, {
1594 desc: "Value struct",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001595 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001596 inputText: `{
1597 "string": "hello",
1598 "number": 123,
1599 "null": null,
1600 "bool": false,
1601 "struct": {
1602 "string": "world"
1603 },
1604 "list": []
1605}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001606 wantMessage: &structpb.Value{
1607 Kind: &structpb.Value_StructValue{
1608 &structpb.Struct{
1609 Fields: map[string]*structpb.Value{
1610 "string": {Kind: &structpb.Value_StringValue{"hello"}},
1611 "number": {Kind: &structpb.Value_NumberValue{123}},
1612 "null": {Kind: &structpb.Value_NullValue{}},
1613 "bool": {Kind: &structpb.Value_BoolValue{false}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001614 "struct": {
Joe Tsaia95b29f2019-05-16 12:47:20 -07001615 Kind: &structpb.Value_StructValue{
1616 &structpb.Struct{
1617 Fields: map[string]*structpb.Value{
1618 "string": {Kind: &structpb.Value_StringValue{"world"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001619 },
1620 },
1621 },
1622 },
1623 "list": {
Joe Tsaia95b29f2019-05-16 12:47:20 -07001624 Kind: &structpb.Value_ListValue{&structpb.ListValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001625 },
1626 },
1627 },
1628 },
1629 },
1630 }, {
1631 desc: "Value struct with invalid UTF8 string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001632 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001633 inputText: "{\"string\": \"abc\xff\"}",
Damien Neil8c86fc52019-06-19 09:28:29 -07001634 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -07001635 }, {
1636 desc: "Value field struct",
1637 inputMessage: &pb2.KnownTypes{},
1638 inputText: `{
1639 "optValue": {
1640 "string": "hello"
1641 }
1642}`,
1643 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001644 OptValue: &structpb.Value{
1645 Kind: &structpb.Value_StructValue{
1646 &structpb.Struct{
1647 Fields: map[string]*structpb.Value{
1648 "string": {Kind: &structpb.Value_StringValue{"hello"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001649 },
1650 },
1651 },
1652 },
1653 },
1654 }, {
1655 desc: "Value empty list",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001656 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001657 inputText: `[]`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001658 wantMessage: &structpb.Value{
1659 Kind: &structpb.Value_ListValue{
1660 &structpb.ListValue{Values: []*structpb.Value{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001661 },
1662 },
1663 }, {
1664 desc: "Value list",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001665 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001666 inputText: `[
1667 "string",
1668 123,
1669 null,
1670 true,
1671 {},
1672 [
1673 "string",
1674 1.23,
1675 null,
1676 false
1677 ]
1678]`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001679 wantMessage: &structpb.Value{
1680 Kind: &structpb.Value_ListValue{
1681 &structpb.ListValue{
1682 Values: []*structpb.Value{
1683 {Kind: &structpb.Value_StringValue{"string"}},
1684 {Kind: &structpb.Value_NumberValue{123}},
1685 {Kind: &structpb.Value_NullValue{}},
1686 {Kind: &structpb.Value_BoolValue{true}},
1687 {Kind: &structpb.Value_StructValue{&structpb.Struct{}}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001688 {
Joe Tsaia95b29f2019-05-16 12:47:20 -07001689 Kind: &structpb.Value_ListValue{
1690 &structpb.ListValue{
1691 Values: []*structpb.Value{
1692 {Kind: &structpb.Value_StringValue{"string"}},
1693 {Kind: &structpb.Value_NumberValue{1.23}},
1694 {Kind: &structpb.Value_NullValue{}},
1695 {Kind: &structpb.Value_BoolValue{false}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001696 },
1697 },
1698 },
1699 },
1700 },
1701 },
1702 },
1703 },
1704 }, {
1705 desc: "Value list with invalid UTF8 string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001706 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001707 inputText: "[\"abc\xff\"]",
Damien Neil8c86fc52019-06-19 09:28:29 -07001708 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -07001709 }, {
1710 desc: "Value field list with invalid UTF8 string",
1711 inputMessage: &pb2.KnownTypes{},
1712 inputText: `{
1713 "optValue": [ "` + "abc\xff" + `"]
1714}`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001715 wantErr: true,
1716 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001717 desc: "Duration empty string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001718 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001719 inputText: `""`,
1720 wantErr: true,
1721 }, {
1722 desc: "Duration with secs",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001723 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001724 inputText: `"3s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001725 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ongc4450372019-03-27 09:59:51 -07001726 }, {
1727 desc: "Duration with escaped unicode",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001728 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001729 inputText: `"\u0033s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001730 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ongc4450372019-03-27 09:59:51 -07001731 }, {
1732 desc: "Duration with -secs",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001733 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001734 inputText: `"-3s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001735 wantMessage: &durationpb.Duration{Seconds: -3},
Herbie Ongc4450372019-03-27 09:59:51 -07001736 }, {
Herbie Ong17523eb2019-03-29 17:46:57 -07001737 desc: "Duration with plus sign",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001738 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001739 inputText: `"+3s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001740 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ong17523eb2019-03-29 17:46:57 -07001741 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001742 desc: "Duration with nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001743 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001744 inputText: `"0.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001745 wantMessage: &durationpb.Duration{Nanos: 1e6},
Herbie Ongc4450372019-03-27 09:59:51 -07001746 }, {
1747 desc: "Duration with -nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001748 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001749 inputText: `"-0.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001750 wantMessage: &durationpb.Duration{Nanos: -1e6},
Herbie Ongc4450372019-03-27 09:59:51 -07001751 }, {
Herbie Ong17523eb2019-03-29 17:46:57 -07001752 desc: "Duration with -nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001753 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001754 inputText: `"-.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001755 wantMessage: &durationpb.Duration{Nanos: -1e6},
Herbie Ong17523eb2019-03-29 17:46:57 -07001756 }, {
1757 desc: "Duration with +nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001758 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001759 inputText: `"+.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001760 wantMessage: &durationpb.Duration{Nanos: 1e6},
Herbie Ong17523eb2019-03-29 17:46:57 -07001761 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001762 desc: "Duration with -secs -nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001763 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001764 inputText: `"-123.000000450s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001765 wantMessage: &durationpb.Duration{Seconds: -123, Nanos: -450},
Herbie Ongc4450372019-03-27 09:59:51 -07001766 }, {
1767 desc: "Duration with large secs",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001768 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001769 inputText: `"10000000000.000000001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001770 wantMessage: &durationpb.Duration{Seconds: 1e10, Nanos: 1},
Herbie Ongc4450372019-03-27 09:59:51 -07001771 }, {
1772 desc: "Duration with decimal without fractional",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001773 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001774 inputText: `"3.s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001775 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ongc4450372019-03-27 09:59:51 -07001776 }, {
1777 desc: "Duration with decimal without integer",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001778 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001779 inputText: `"0.5s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001780 wantMessage: &durationpb.Duration{Nanos: 5e8},
Herbie Ongc4450372019-03-27 09:59:51 -07001781 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001782 desc: "Duration max value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001783 inputMessage: &durationpb.Duration{},
Herbie Ongad9c1252019-04-24 20:51:28 -07001784 inputText: `"315576000000.999999999s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001785 wantMessage: &durationpb.Duration{Seconds: 315576000000, Nanos: 999999999},
Herbie Ongad9c1252019-04-24 20:51:28 -07001786 }, {
1787 desc: "Duration min value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001788 inputMessage: &durationpb.Duration{},
Herbie Ongad9c1252019-04-24 20:51:28 -07001789 inputText: `"-315576000000.999999999s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001790 wantMessage: &durationpb.Duration{Seconds: -315576000000, Nanos: -999999999},
Herbie Ongad9c1252019-04-24 20:51:28 -07001791 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001792 desc: "Duration with +secs out of range",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001793 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001794 inputText: `"315576000001s"`,
1795 wantErr: true,
1796 }, {
1797 desc: "Duration with -secs out of range",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001798 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001799 inputText: `"-315576000001s"`,
1800 wantErr: true,
1801 }, {
1802 desc: "Duration with nanos beyond 9 digits",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001803 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001804 inputText: `"0.1000000000s"`,
Herbie Ongc4450372019-03-27 09:59:51 -07001805 wantErr: true,
1806 }, {
1807 desc: "Duration without suffix s",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001808 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001809 inputText: `"123"`,
1810 wantErr: true,
1811 }, {
Herbie Ong17523eb2019-03-29 17:46:57 -07001812 desc: "Duration invalid signed fraction",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001813 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001814 inputText: `"123.+123s"`,
1815 wantErr: true,
1816 }, {
1817 desc: "Duration invalid multiple .",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001818 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001819 inputText: `"123.123.s"`,
1820 wantErr: true,
1821 }, {
1822 desc: "Duration invalid integer",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001823 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001824 inputText: `"01s"`,
1825 wantErr: true,
1826 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001827 desc: "Timestamp zero",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001828 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001829 inputText: `"1970-01-01T00:00:00Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001830 wantMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001831 }, {
1832 desc: "Timestamp with tz adjustment",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001833 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001834 inputText: `"1970-01-01T00:00:00+01:00"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001835 wantMessage: &timestamppb.Timestamp{Seconds: -3600},
Herbie Ongc4450372019-03-27 09:59:51 -07001836 }, {
1837 desc: "Timestamp UTC",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001838 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001839 inputText: `"2019-03-19T23:03:21Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001840 wantMessage: &timestamppb.Timestamp{Seconds: 1553036601},
Herbie Ongc4450372019-03-27 09:59:51 -07001841 }, {
1842 desc: "Timestamp with escaped unicode",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001843 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001844 inputText: `"2019-0\u0033-19T23:03:21Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001845 wantMessage: &timestamppb.Timestamp{Seconds: 1553036601},
Herbie Ongc4450372019-03-27 09:59:51 -07001846 }, {
1847 desc: "Timestamp with nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001848 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001849 inputText: `"2019-03-19T23:03:21.000000001Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001850 wantMessage: &timestamppb.Timestamp{Seconds: 1553036601, Nanos: 1},
Herbie Ongc4450372019-03-27 09:59:51 -07001851 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001852 desc: "Timestamp max value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001853 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001854 inputText: `"9999-12-31T23:59:59.999999999Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001855 wantMessage: &timestamppb.Timestamp{Seconds: 253402300799, Nanos: 999999999},
Herbie Ongc4450372019-03-27 09:59:51 -07001856 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001857 desc: "Timestamp above max value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001858 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001859 inputText: `"9999-12-31T23:59:59-01:00"`,
1860 wantErr: true,
1861 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001862 desc: "Timestamp min value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001863 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001864 inputText: `"0001-01-01T00:00:00Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001865 wantMessage: &timestamppb.Timestamp{Seconds: -62135596800},
Herbie Ongc4450372019-03-27 09:59:51 -07001866 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001867 desc: "Timestamp below min value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001868 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001869 inputText: `"0001-01-01T00:00:00+01:00"`,
1870 wantErr: true,
1871 }, {
1872 desc: "Timestamp with nanos beyond 9 digits",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001873 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001874 inputText: `"1970-01-01T00:00:00.0000000001Z"`,
1875 wantErr: true,
1876 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -07001877 desc: "FieldMask empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001878 inputMessage: &fieldmaskpb.FieldMask{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001879 inputText: `""`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001880 wantMessage: &fieldmaskpb.FieldMask{Paths: []string{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001881 }, {
1882 desc: "FieldMask",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001883 inputMessage: &fieldmaskpb.FieldMask{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001884 inputText: `"foo,fooBar , foo.barQux ,Foo"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001885 wantMessage: &fieldmaskpb.FieldMask{
Herbie Onge63c4c42019-03-22 22:20:22 -07001886 Paths: []string{
1887 "foo",
1888 "foo_bar",
1889 "foo.bar_qux",
1890 "_foo",
1891 },
1892 },
1893 }, {
1894 desc: "FieldMask field",
1895 inputMessage: &pb2.KnownTypes{},
1896 inputText: `{
1897 "optFieldmask": "foo, qux.fooBar"
1898}`,
1899 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001900 OptFieldmask: &fieldmaskpb.FieldMask{
Herbie Onge63c4c42019-03-22 22:20:22 -07001901 Paths: []string{
1902 "foo",
1903 "qux.foo_bar",
1904 },
1905 },
1906 },
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001907 }, {
1908 desc: "Any empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001909 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001910 inputText: `{}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001911 wantMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001912 }, {
1913 desc: "Any with non-custom message",
Damien Neil5c5b5312019-05-14 12:44:37 -07001914 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001915 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001916 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001917 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001918 inputText: `{
1919 "@type": "foo/pb2.Nested",
1920 "optString": "embedded inside Any",
1921 "optNested": {
1922 "optString": "inception"
1923 }
1924}`,
1925 wantMessage: func() proto.Message {
1926 m := &pb2.Nested{
1927 OptString: scalar.String("embedded inside Any"),
1928 OptNested: &pb2.Nested{
1929 OptString: scalar.String("inception"),
1930 },
1931 }
1932 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
1933 if err != nil {
1934 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1935 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001936 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001937 TypeUrl: "foo/pb2.Nested",
1938 Value: b,
1939 }
1940 }(),
1941 }, {
1942 desc: "Any with empty embedded message",
Damien Neil5c5b5312019-05-14 12:44:37 -07001943 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001944 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001945 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001946 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07001947 inputText: `{"@type": "foo/pb2.Nested"}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001948 wantMessage: &anypb.Any{TypeUrl: "foo/pb2.Nested"},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001949 }, {
1950 desc: "Any without registered type",
Damien Neil5c5b5312019-05-14 12:44:37 -07001951 umo: protojson.UnmarshalOptions{Resolver: preg.NewTypes()},
Joe Tsaia95b29f2019-05-16 12:47:20 -07001952 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07001953 inputText: `{"@type": "foo/pb2.Nested"}`,
1954 wantErr: true,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001955 }, {
Damien Neil0c9f0a92019-06-19 10:41:09 -07001956 desc: "Any with missing required",
Damien Neil5c5b5312019-05-14 12:44:37 -07001957 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001958 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.PartialRequired{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001959 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001960 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001961 inputText: `{
1962 "@type": "pb2.PartialRequired",
1963 "optString": "embedded inside Any"
1964}`,
1965 wantMessage: func() proto.Message {
1966 m := &pb2.PartialRequired{
1967 OptString: scalar.String("embedded inside Any"),
1968 }
Damien Neil96c229a2019-04-03 12:17:24 -07001969 b, err := proto.MarshalOptions{
1970 Deterministic: true,
1971 AllowPartial: true,
1972 }.Marshal(m)
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001973 if err != nil {
1974 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1975 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001976 return &anypb.Any{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001977 TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001978 Value: b,
1979 }
1980 }(),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001981 }, {
1982 desc: "Any with partial required and AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001983 umo: protojson.UnmarshalOptions{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001984 AllowPartial: true,
Joe Tsai0fc49f82019-05-01 12:29:25 -07001985 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.PartialRequired{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001986 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001987 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001988 inputText: `{
1989 "@type": "pb2.PartialRequired",
1990 "optString": "embedded inside Any"
1991}`,
1992 wantMessage: func() proto.Message {
1993 m := &pb2.PartialRequired{
1994 OptString: scalar.String("embedded inside Any"),
1995 }
Damien Neil96c229a2019-04-03 12:17:24 -07001996 b, err := proto.MarshalOptions{
1997 Deterministic: true,
1998 AllowPartial: true,
1999 }.Marshal(m)
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002000 if err != nil {
2001 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2002 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002003 return &anypb.Any{
Joe Tsai0fc49f82019-05-01 12:29:25 -07002004 TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002005 Value: b,
2006 }
2007 }(),
2008 }, {
2009 desc: "Any with invalid UTF8",
Damien Neil5c5b5312019-05-14 12:44:37 -07002010 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07002011 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002012 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002013 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002014 inputText: `{
2015 "optString": "` + "abc\xff" + `",
2016 "@type": "foo/pb2.Nested"
2017}`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002018 wantErr: true,
2019 }, {
2020 desc: "Any with BoolValue",
Damien Neil5c5b5312019-05-14 12:44:37 -07002021 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002022 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.BoolValue{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002023 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002024 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002025 inputText: `{
2026 "@type": "type.googleapis.com/google.protobuf.BoolValue",
2027 "value": true
2028}`,
2029 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002030 m := &wrapperspb.BoolValue{Value: true}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002031 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2032 if err != nil {
2033 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2034 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002035 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002036 TypeUrl: "type.googleapis.com/google.protobuf.BoolValue",
2037 Value: b,
2038 }
2039 }(),
2040 }, {
2041 desc: "Any with Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002042 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002043 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&emptypb.Empty{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002044 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002045 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002046 inputText: `{
2047 "value": {},
2048 "@type": "type.googleapis.com/google.protobuf.Empty"
2049}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002050 wantMessage: &anypb.Any{
Herbie Ong4f0be712019-04-25 17:57:12 -07002051 TypeUrl: "type.googleapis.com/google.protobuf.Empty",
2052 },
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002053 }, {
2054 desc: "Any with missing Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002055 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002056 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&emptypb.Empty{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002057 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002058 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002059 inputText: `{
2060 "@type": "type.googleapis.com/google.protobuf.Empty"
2061}`,
2062 wantErr: true,
2063 }, {
2064 desc: "Any with StringValue containing invalid UTF8",
Damien Neil5c5b5312019-05-14 12:44:37 -07002065 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002066 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002067 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002068 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002069 inputText: `{
2070 "@type": "google.protobuf.StringValue",
2071 "value": "` + "abc\xff" + `"
2072}`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002073 wantErr: true,
2074 }, {
2075 desc: "Any with Int64Value",
Damien Neil5c5b5312019-05-14 12:44:37 -07002076 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002077 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.Int64Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002078 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002079 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002080 inputText: `{
2081 "@type": "google.protobuf.Int64Value",
2082 "value": "42"
2083}`,
2084 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002085 m := &wrapperspb.Int64Value{Value: 42}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002086 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2087 if err != nil {
2088 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2089 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002090 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002091 TypeUrl: "google.protobuf.Int64Value",
2092 Value: b,
2093 }
2094 }(),
2095 }, {
2096 desc: "Any with invalid Int64Value",
Damien Neil5c5b5312019-05-14 12:44:37 -07002097 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002098 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.Int64Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002099 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002100 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002101 inputText: `{
2102 "@type": "google.protobuf.Int64Value",
2103 "value": "forty-two"
2104}`,
2105 wantErr: true,
2106 }, {
2107 desc: "Any with invalid UInt64Value",
Damien Neil5c5b5312019-05-14 12:44:37 -07002108 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002109 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.UInt64Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002110 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002111 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002112 inputText: `{
2113 "@type": "google.protobuf.UInt64Value",
2114 "value": -42
2115}`,
2116 wantErr: true,
2117 }, {
2118 desc: "Any with Duration",
Damien Neil5c5b5312019-05-14 12:44:37 -07002119 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002120 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&durationpb.Duration{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002121 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002122 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002123 inputText: `{
2124 "@type": "type.googleapis.com/google.protobuf.Duration",
2125 "value": "0s"
2126}`,
2127 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002128 m := &durationpb.Duration{}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002129 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2130 if err != nil {
2131 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2132 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002133 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002134 TypeUrl: "type.googleapis.com/google.protobuf.Duration",
2135 Value: b,
2136 }
2137 }(),
2138 }, {
2139 desc: "Any with Value of StringValue",
Damien Neil5c5b5312019-05-14 12:44:37 -07002140 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002141 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&structpb.Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002142 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002143 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002144 inputText: `{
2145 "@type": "google.protobuf.Value",
2146 "value": "` + "abc\xff" + `"
2147}`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002148 wantErr: true,
2149 }, {
2150 desc: "Any with Value of NullValue",
Damien Neil5c5b5312019-05-14 12:44:37 -07002151 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002152 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&structpb.Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002153 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002154 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002155 inputText: `{
2156 "@type": "google.protobuf.Value",
2157 "value": null
2158}`,
2159 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002160 m := &structpb.Value{Kind: &structpb.Value_NullValue{}}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002161 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2162 if err != nil {
2163 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2164 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002165 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002166 TypeUrl: "google.protobuf.Value",
2167 Value: b,
2168 }
2169 }(),
2170 }, {
2171 desc: "Any with Struct",
Damien Neil5c5b5312019-05-14 12:44:37 -07002172 umo: protojson.UnmarshalOptions{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002173 Resolver: preg.NewTypes(
Joe Tsaia95b29f2019-05-16 12:47:20 -07002174 pimpl.Export{}.MessageTypeOf(&structpb.Struct{}),
2175 pimpl.Export{}.MessageTypeOf(&structpb.Value{}),
2176 pimpl.Export{}.MessageTypeOf(&wrapperspb.BoolValue{}),
2177 pimpl.Export{}.EnumTypeOf(structpb.NullValue_NULL_VALUE),
2178 pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{}),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002179 ),
2180 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002181 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002182 inputText: `{
2183 "@type": "google.protobuf.Struct",
2184 "value": {
2185 "bool": true,
2186 "null": null,
2187 "string": "hello",
2188 "struct": {
2189 "string": "world"
2190 }
2191 }
2192}`,
2193 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002194 m := &structpb.Struct{
2195 Fields: map[string]*structpb.Value{
2196 "bool": {Kind: &structpb.Value_BoolValue{true}},
2197 "null": {Kind: &structpb.Value_NullValue{}},
2198 "string": {Kind: &structpb.Value_StringValue{"hello"}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002199 "struct": {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002200 Kind: &structpb.Value_StructValue{
2201 &structpb.Struct{
2202 Fields: map[string]*structpb.Value{
2203 "string": {Kind: &structpb.Value_StringValue{"world"}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002204 },
2205 },
2206 },
2207 },
2208 },
2209 }
2210 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2211 if err != nil {
2212 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2213 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002214 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002215 TypeUrl: "google.protobuf.Struct",
2216 Value: b,
2217 }
2218 }(),
2219 }, {
2220 desc: "Any with missing @type",
Damien Neil5c5b5312019-05-14 12:44:37 -07002221 umo: protojson.UnmarshalOptions{},
Joe Tsaia95b29f2019-05-16 12:47:20 -07002222 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002223 inputText: `{
2224 "value": {}
2225}`,
2226 wantErr: true,
2227 }, {
2228 desc: "Any with empty @type",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002229 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002230 inputText: `{
2231 "@type": ""
2232}`,
2233 wantErr: true,
2234 }, {
2235 desc: "Any with duplicate @type",
Damien Neil5c5b5312019-05-14 12:44:37 -07002236 umo: protojson.UnmarshalOptions{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002237 Resolver: preg.NewTypes(
Joe Tsai0fc49f82019-05-01 12:29:25 -07002238 pimpl.Export{}.MessageTypeOf(&pb2.Nested{}),
Joe Tsaia95b29f2019-05-16 12:47:20 -07002239 pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{}),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002240 ),
2241 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002242 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002243 inputText: `{
2244 "@type": "google.protobuf.StringValue",
2245 "value": "hello",
2246 "@type": "pb2.Nested"
2247}`,
2248 wantErr: true,
2249 }, {
2250 desc: "Any with duplicate value",
Damien Neil5c5b5312019-05-14 12:44:37 -07002251 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002252 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002253 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002254 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002255 inputText: `{
2256 "@type": "google.protobuf.StringValue",
2257 "value": "hello",
2258 "value": "world"
2259}`,
2260 wantErr: true,
2261 }, {
2262 desc: "Any with unknown field",
Damien Neil5c5b5312019-05-14 12:44:37 -07002263 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07002264 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002265 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002266 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002267 inputText: `{
2268 "@type": "pb2.Nested",
2269 "optString": "hello",
2270 "unknown": "world"
2271}`,
2272 wantErr: true,
2273 }, {
2274 desc: "Any with embedded type containing Any",
Damien Neil5c5b5312019-05-14 12:44:37 -07002275 umo: protojson.UnmarshalOptions{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002276 Resolver: preg.NewTypes(
Joe Tsai0fc49f82019-05-01 12:29:25 -07002277 pimpl.Export{}.MessageTypeOf(&pb2.KnownTypes{}),
Joe Tsaia95b29f2019-05-16 12:47:20 -07002278 pimpl.Export{}.MessageTypeOf(&anypb.Any{}),
2279 pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{}),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002280 ),
2281 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002282 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002283 inputText: `{
2284 "@type": "pb2.KnownTypes",
2285 "optAny": {
2286 "@type": "google.protobuf.StringValue",
2287 "value": "` + "abc\xff" + `"
2288 }
2289}`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002290 wantErr: true,
2291 }, {
2292 desc: "well known types as field values",
Damien Neil5c5b5312019-05-14 12:44:37 -07002293 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002294 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&emptypb.Empty{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002295 },
2296 inputMessage: &pb2.KnownTypes{},
2297 inputText: `{
2298 "optBool": false,
2299 "optInt32": 42,
2300 "optInt64": "42",
2301 "optUint32": 42,
2302 "optUint64": "42",
2303 "optFloat": 1.23,
2304 "optDouble": 3.1415,
2305 "optString": "hello",
2306 "optBytes": "aGVsbG8=",
2307 "optDuration": "123s",
2308 "optTimestamp": "2019-03-19T23:03:21Z",
2309 "optStruct": {
2310 "string": "hello"
2311 },
2312 "optList": [
2313 null,
2314 "",
2315 {},
2316 []
2317 ],
2318 "optValue": "world",
2319 "optEmpty": {},
2320 "optAny": {
2321 "@type": "google.protobuf.Empty",
2322 "value": {}
2323 },
2324 "optFieldmask": "fooBar,barFoo"
2325}`,
2326 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002327 OptBool: &wrapperspb.BoolValue{Value: false},
2328 OptInt32: &wrapperspb.Int32Value{Value: 42},
2329 OptInt64: &wrapperspb.Int64Value{Value: 42},
2330 OptUint32: &wrapperspb.UInt32Value{Value: 42},
2331 OptUint64: &wrapperspb.UInt64Value{Value: 42},
2332 OptFloat: &wrapperspb.FloatValue{Value: 1.23},
2333 OptDouble: &wrapperspb.DoubleValue{Value: 3.1415},
2334 OptString: &wrapperspb.StringValue{Value: "hello"},
2335 OptBytes: &wrapperspb.BytesValue{Value: []byte("hello")},
2336 OptDuration: &durationpb.Duration{Seconds: 123},
2337 OptTimestamp: &timestamppb.Timestamp{Seconds: 1553036601},
2338 OptStruct: &structpb.Struct{
2339 Fields: map[string]*structpb.Value{
2340 "string": {Kind: &structpb.Value_StringValue{"hello"}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002341 },
2342 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002343 OptList: &structpb.ListValue{
2344 Values: []*structpb.Value{
2345 {Kind: &structpb.Value_NullValue{}},
2346 {Kind: &structpb.Value_StringValue{}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002347 {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002348 Kind: &structpb.Value_StructValue{
2349 &structpb.Struct{Fields: map[string]*structpb.Value{}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002350 },
2351 },
2352 {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002353 Kind: &structpb.Value_ListValue{
2354 &structpb.ListValue{Values: []*structpb.Value{}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002355 },
2356 },
2357 },
2358 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002359 OptValue: &structpb.Value{
2360 Kind: &structpb.Value_StringValue{"world"},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002361 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002362 OptEmpty: &emptypb.Empty{},
2363 OptAny: &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002364 TypeUrl: "google.protobuf.Empty",
2365 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002366 OptFieldmask: &fieldmaskpb.FieldMask{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002367 Paths: []string{"foo_bar", "bar_foo"},
2368 },
2369 },
Herbie Ong4f0be712019-04-25 17:57:12 -07002370 }, {
2371 desc: "DiscardUnknown: regular messages",
Damien Neil5c5b5312019-05-14 12:44:37 -07002372 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002373 inputMessage: &pb3.Nests{},
2374 inputText: `{
2375 "sNested": {
2376 "unknown": {
2377 "foo": 1,
2378 "bar": [1, 2, 3]
2379 }
2380 },
2381 "unknown": "not known"
2382}`,
2383 wantMessage: &pb3.Nests{SNested: &pb3.Nested{}},
2384 }, {
2385 desc: "DiscardUnknown: repeated",
Damien Neil5c5b5312019-05-14 12:44:37 -07002386 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002387 inputMessage: &pb2.Nests{},
2388 inputText: `{
2389 "rptNested": [
2390 {"unknown": "blah"},
2391 {"optString": "hello"}
2392 ]
2393}`,
2394 wantMessage: &pb2.Nests{
2395 RptNested: []*pb2.Nested{
2396 {},
2397 {OptString: scalar.String("hello")},
2398 },
2399 },
2400 }, {
2401 desc: "DiscardUnknown: map",
Damien Neil5c5b5312019-05-14 12:44:37 -07002402 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002403 inputMessage: &pb3.Maps{},
2404 inputText: `{
2405 "strToNested": {
2406 "nested_one": {
2407 "unknown": "what you see is not"
2408 }
2409 }
2410}`,
2411 wantMessage: &pb3.Maps{
2412 StrToNested: map[string]*pb3.Nested{
2413 "nested_one": {},
2414 },
2415 },
2416 }, {
2417 desc: "DiscardUnknown: extension",
Damien Neil5c5b5312019-05-14 12:44:37 -07002418 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002419 inputMessage: &pb2.Extensions{},
2420 inputText: `{
2421 "[pb2.opt_ext_nested]": {
2422 "unknown": []
2423 }
2424}`,
2425 wantMessage: func() proto.Message {
2426 m := &pb2.Extensions{}
2427 setExtension(m, pb2.E_OptExtNested, &pb2.Nested{})
2428 return m
2429 }(),
2430 }, {
2431 desc: "DiscardUnknown: Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002432 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Joe Tsaia95b29f2019-05-16 12:47:20 -07002433 inputMessage: &emptypb.Empty{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002434 inputText: `{"unknown": "something"}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002435 wantMessage: &emptypb.Empty{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002436 }, {
2437 desc: "DiscardUnknown: Any without type",
Damien Neil5c5b5312019-05-14 12:44:37 -07002438 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Joe Tsaia95b29f2019-05-16 12:47:20 -07002439 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002440 inputText: `{
2441 "value": {"foo": "bar"},
2442 "unknown": true
2443}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002444 wantMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002445 }, {
2446 desc: "DiscardUnknown: Any",
Damien Neil5c5b5312019-05-14 12:44:37 -07002447 umo: protojson.UnmarshalOptions{
Herbie Ong4f0be712019-04-25 17:57:12 -07002448 DiscardUnknown: true,
Joe Tsai0fc49f82019-05-01 12:29:25 -07002449 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong4f0be712019-04-25 17:57:12 -07002450 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002451 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002452 inputText: `{
2453 "@type": "foo/pb2.Nested",
2454 "unknown": "none"
2455}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002456 wantMessage: &anypb.Any{
Herbie Ong4f0be712019-04-25 17:57:12 -07002457 TypeUrl: "foo/pb2.Nested",
2458 },
2459 }, {
2460 desc: "DiscardUnknown: Any with Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002461 umo: protojson.UnmarshalOptions{
Herbie Ong4f0be712019-04-25 17:57:12 -07002462 DiscardUnknown: true,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002463 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&emptypb.Empty{})),
Herbie Ong4f0be712019-04-25 17:57:12 -07002464 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002465 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002466 inputText: `{
2467 "@type": "type.googleapis.com/google.protobuf.Empty",
2468 "value": {"unknown": 47}
2469}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002470 wantMessage: &anypb.Any{
Herbie Ong4f0be712019-04-25 17:57:12 -07002471 TypeUrl: "type.googleapis.com/google.protobuf.Empty",
2472 },
Herbie Ongc96a79d2019-03-08 10:49:17 -08002473 }}
2474
2475 for _, tt := range tests {
2476 tt := tt
2477 t.Run(tt.desc, func(t *testing.T) {
Joe Tsaicdb77732019-05-14 16:05:06 -07002478 err := tt.umo.Unmarshal([]byte(tt.inputText), tt.inputMessage)
Herbie Ongc96a79d2019-03-08 10:49:17 -08002479 if err != nil && !tt.wantErr {
2480 t.Errorf("Unmarshal() returned error: %v\n\n", err)
2481 }
2482 if err == nil && tt.wantErr {
2483 t.Error("Unmarshal() got nil error, want error\n\n")
2484 }
Joe Tsai8d30bbe2019-05-16 15:53:25 -07002485 if tt.wantMessage != nil && !proto.Equal(tt.inputMessage, tt.wantMessage) {
Herbie Ongc96a79d2019-03-08 10:49:17 -08002486 t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", tt.inputMessage, tt.wantMessage)
2487 }
2488 })
2489 }
2490}