blob: 0de7d7f2520d093646794f2f2abaf8bd57554980 [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
11 protoV1 "github.com/golang/protobuf/proto"
Damien Neil5c5b5312019-05-14 12:44:37 -070012 "google.golang.org/protobuf/encoding/protojson"
Damien Neile89e6242019-05-13 23:55:40 -070013 "google.golang.org/protobuf/encoding/testprotos/pb2"
14 "google.golang.org/protobuf/encoding/testprotos/pb3"
15 pimpl "google.golang.org/protobuf/internal/impl"
16 "google.golang.org/protobuf/internal/scalar"
17 "google.golang.org/protobuf/proto"
18 preg "google.golang.org/protobuf/reflect/protoregistry"
19 "google.golang.org/protobuf/runtime/protoiface"
Herbie Onge63c4c42019-03-22 22:20:22 -070020
Joe Tsaia95b29f2019-05-16 12:47:20 -070021 "google.golang.org/protobuf/types/known/anypb"
22 "google.golang.org/protobuf/types/known/durationpb"
23 "google.golang.org/protobuf/types/known/emptypb"
24 "google.golang.org/protobuf/types/known/fieldmaskpb"
25 "google.golang.org/protobuf/types/known/structpb"
26 "google.golang.org/protobuf/types/known/timestamppb"
27 "google.golang.org/protobuf/types/known/wrapperspb"
Herbie Ongc96a79d2019-03-08 10:49:17 -080028)
29
Herbie Onge52379a2019-03-15 18:00:19 -070030func init() {
31 // TODO: remove these registerExtension calls when generated code registers
32 // to V2 global registry.
33 registerExtension(pb2.E_OptExtBool)
34 registerExtension(pb2.E_OptExtString)
35 registerExtension(pb2.E_OptExtEnum)
36 registerExtension(pb2.E_OptExtNested)
37 registerExtension(pb2.E_RptExtFixed32)
38 registerExtension(pb2.E_RptExtEnum)
39 registerExtension(pb2.E_RptExtNested)
40 registerExtension(pb2.E_ExtensionsContainer_OptExtBool)
41 registerExtension(pb2.E_ExtensionsContainer_OptExtString)
42 registerExtension(pb2.E_ExtensionsContainer_OptExtEnum)
43 registerExtension(pb2.E_ExtensionsContainer_OptExtNested)
44 registerExtension(pb2.E_ExtensionsContainer_RptExtString)
45 registerExtension(pb2.E_ExtensionsContainer_RptExtEnum)
46 registerExtension(pb2.E_ExtensionsContainer_RptExtNested)
47 registerExtension(pb2.E_MessageSetExtension)
48 registerExtension(pb2.E_MessageSetExtension_MessageSetExtension)
49 registerExtension(pb2.E_MessageSetExtension_NotMessageSetExtension)
50 registerExtension(pb2.E_MessageSetExtension_ExtNested)
51 registerExtension(pb2.E_FakeMessageSetExtension_MessageSetExtension)
52}
53
Joe Tsai4fddeba2019-03-20 18:29:32 -070054func registerExtension(xd *protoiface.ExtensionDescV1) {
Herbie Onge52379a2019-03-15 18:00:19 -070055 preg.GlobalTypes.Register(xd.Type)
56}
57
Herbie Ongc96a79d2019-03-08 10:49:17 -080058func TestUnmarshal(t *testing.T) {
59 tests := []struct {
60 desc string
Damien Neil5c5b5312019-05-14 12:44:37 -070061 umo protojson.UnmarshalOptions
Herbie Ongc96a79d2019-03-08 10:49:17 -080062 inputMessage proto.Message
63 inputText string
64 wantMessage proto.Message
65 // TODO: verify expected error message substring.
66 wantErr bool
67 }{{
68 desc: "proto2 empty message",
69 inputMessage: &pb2.Scalars{},
70 inputText: "{}",
71 wantMessage: &pb2.Scalars{},
72 }, {
73 desc: "unexpected value instead of EOF",
74 inputMessage: &pb2.Scalars{},
75 inputText: "{} {}",
76 wantErr: true,
77 }, {
78 desc: "proto2 optional scalars set to zero values",
79 inputMessage: &pb2.Scalars{},
80 inputText: `{
81 "optBool": false,
82 "optInt32": 0,
83 "optInt64": 0,
84 "optUint32": 0,
85 "optUint64": 0,
86 "optSint32": 0,
87 "optSint64": 0,
88 "optFixed32": 0,
89 "optFixed64": 0,
90 "optSfixed32": 0,
91 "optSfixed64": 0,
92 "optFloat": 0,
93 "optDouble": 0,
94 "optBytes": "",
95 "optString": ""
96}`,
97 wantMessage: &pb2.Scalars{
98 OptBool: scalar.Bool(false),
99 OptInt32: scalar.Int32(0),
100 OptInt64: scalar.Int64(0),
101 OptUint32: scalar.Uint32(0),
102 OptUint64: scalar.Uint64(0),
103 OptSint32: scalar.Int32(0),
104 OptSint64: scalar.Int64(0),
105 OptFixed32: scalar.Uint32(0),
106 OptFixed64: scalar.Uint64(0),
107 OptSfixed32: scalar.Int32(0),
108 OptSfixed64: scalar.Int64(0),
109 OptFloat: scalar.Float32(0),
110 OptDouble: scalar.Float64(0),
111 OptBytes: []byte{},
112 OptString: scalar.String(""),
113 },
114 }, {
115 desc: "proto3 scalars set to zero values",
116 inputMessage: &pb3.Scalars{},
117 inputText: `{
118 "sBool": false,
119 "sInt32": 0,
120 "sInt64": 0,
121 "sUint32": 0,
122 "sUint64": 0,
123 "sSint32": 0,
124 "sSint64": 0,
125 "sFixed32": 0,
126 "sFixed64": 0,
127 "sSfixed32": 0,
128 "sSfixed64": 0,
129 "sFloat": 0,
130 "sDouble": 0,
131 "sBytes": "",
132 "sString": ""
133}`,
134 wantMessage: &pb3.Scalars{},
135 }, {
136 desc: "proto2 optional scalars set to null",
137 inputMessage: &pb2.Scalars{},
138 inputText: `{
139 "optBool": null,
140 "optInt32": null,
141 "optInt64": null,
142 "optUint32": null,
143 "optUint64": null,
144 "optSint32": null,
145 "optSint64": null,
146 "optFixed32": null,
147 "optFixed64": null,
148 "optSfixed32": null,
149 "optSfixed64": null,
150 "optFloat": null,
151 "optDouble": null,
152 "optBytes": null,
153 "optString": null
154}`,
155 wantMessage: &pb2.Scalars{},
156 }, {
157 desc: "proto3 scalars set to null",
158 inputMessage: &pb3.Scalars{},
159 inputText: `{
160 "sBool": null,
161 "sInt32": null,
162 "sInt64": null,
163 "sUint32": null,
164 "sUint64": null,
165 "sSint32": null,
166 "sSint64": null,
167 "sFixed32": null,
168 "sFixed64": null,
169 "sSfixed32": null,
170 "sSfixed64": null,
171 "sFloat": null,
172 "sDouble": null,
173 "sBytes": null,
174 "sString": null
175}`,
176 wantMessage: &pb3.Scalars{},
177 }, {
178 desc: "boolean",
179 inputMessage: &pb3.Scalars{},
180 inputText: `{"sBool": true}`,
181 wantMessage: &pb3.Scalars{
182 SBool: true,
183 },
184 }, {
185 desc: "not boolean",
186 inputMessage: &pb3.Scalars{},
187 inputText: `{"sBool": "true"}`,
188 wantErr: true,
189 }, {
190 desc: "float and double",
191 inputMessage: &pb3.Scalars{},
192 inputText: `{
193 "sFloat": 1.234,
194 "sDouble": 5.678
195}`,
196 wantMessage: &pb3.Scalars{
197 SFloat: 1.234,
198 SDouble: 5.678,
199 },
200 }, {
201 desc: "float and double in string",
202 inputMessage: &pb3.Scalars{},
203 inputText: `{
204 "sFloat": "1.234",
205 "sDouble": "5.678"
206}`,
207 wantMessage: &pb3.Scalars{
208 SFloat: 1.234,
209 SDouble: 5.678,
210 },
211 }, {
212 desc: "float and double in E notation",
213 inputMessage: &pb3.Scalars{},
214 inputText: `{
215 "sFloat": 12.34E-1,
216 "sDouble": 5.678e4
217}`,
218 wantMessage: &pb3.Scalars{
219 SFloat: 1.234,
220 SDouble: 56780,
221 },
222 }, {
223 desc: "float and double in string E notation",
224 inputMessage: &pb3.Scalars{},
225 inputText: `{
226 "sFloat": "12.34E-1",
227 "sDouble": "5.678e4"
228}`,
229 wantMessage: &pb3.Scalars{
230 SFloat: 1.234,
231 SDouble: 56780,
232 },
233 }, {
234 desc: "float exceeds limit",
235 inputMessage: &pb3.Scalars{},
236 inputText: `{"sFloat": 3.4e39}`,
237 wantErr: true,
238 }, {
239 desc: "float in string exceeds limit",
240 inputMessage: &pb3.Scalars{},
241 inputText: `{"sFloat": "-3.4e39"}`,
242 wantErr: true,
243 }, {
244 desc: "double exceeds limit",
245 inputMessage: &pb3.Scalars{},
246 inputText: `{"sFloat": -1.79e+309}`,
247 wantErr: true,
248 }, {
249 desc: "double in string exceeds limit",
250 inputMessage: &pb3.Scalars{},
251 inputText: `{"sFloat": "1.79e+309"}`,
252 wantErr: true,
253 }, {
254 desc: "infinites",
255 inputMessage: &pb3.Scalars{},
256 inputText: `{"sFloat": "Infinity", "sDouble": "-Infinity"}`,
257 wantMessage: &pb3.Scalars{
258 SFloat: float32(math.Inf(+1)),
259 SDouble: math.Inf(-1),
260 },
261 }, {
Herbie Ong06a6b0b2019-04-24 21:15:45 -0700262 desc: "float string with leading space",
263 inputMessage: &pb3.Scalars{},
264 inputText: `{"sFloat": " 1.234"}`,
265 wantErr: true,
266 }, {
267 desc: "double string with trailing space",
268 inputMessage: &pb3.Scalars{},
269 inputText: `{"sDouble": "5.678 "}`,
270 wantErr: true,
271 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800272 desc: "not float",
273 inputMessage: &pb3.Scalars{},
274 inputText: `{"sFloat": true}`,
275 wantErr: true,
276 }, {
277 desc: "not double",
278 inputMessage: &pb3.Scalars{},
279 inputText: `{"sDouble": "not a number"}`,
280 wantErr: true,
281 }, {
282 desc: "integers",
283 inputMessage: &pb3.Scalars{},
284 inputText: `{
285 "sInt32": 1234,
286 "sInt64": -1234,
287 "sUint32": 1e2,
288 "sUint64": 100E-2,
289 "sSint32": 1.0,
290 "sSint64": -1.0,
291 "sFixed32": 1.234e+5,
292 "sFixed64": 1200E-2,
293 "sSfixed32": -1.234e05,
294 "sSfixed64": -1200e-02
295}`,
296 wantMessage: &pb3.Scalars{
297 SInt32: 1234,
298 SInt64: -1234,
299 SUint32: 100,
300 SUint64: 1,
301 SSint32: 1,
302 SSint64: -1,
303 SFixed32: 123400,
304 SFixed64: 12,
305 SSfixed32: -123400,
306 SSfixed64: -12,
307 },
308 }, {
309 desc: "integers in string",
310 inputMessage: &pb3.Scalars{},
311 inputText: `{
312 "sInt32": "1234",
313 "sInt64": "-1234",
314 "sUint32": "1e2",
315 "sUint64": "100E-2",
316 "sSint32": "1.0",
317 "sSint64": "-1.0",
318 "sFixed32": "1.234e+5",
319 "sFixed64": "1200E-2",
320 "sSfixed32": "-1.234e05",
321 "sSfixed64": "-1200e-02"
322}`,
323 wantMessage: &pb3.Scalars{
324 SInt32: 1234,
325 SInt64: -1234,
326 SUint32: 100,
327 SUint64: 1,
328 SSint32: 1,
329 SSint64: -1,
330 SFixed32: 123400,
331 SFixed64: 12,
332 SSfixed32: -123400,
333 SSfixed64: -12,
334 },
335 }, {
336 desc: "integers in escaped string",
337 inputMessage: &pb3.Scalars{},
338 inputText: `{"sInt32": "\u0031\u0032"}`,
339 wantMessage: &pb3.Scalars{
340 SInt32: 12,
341 },
342 }, {
Herbie Ong06a6b0b2019-04-24 21:15:45 -0700343 desc: "integer string with leading space",
344 inputMessage: &pb3.Scalars{},
345 inputText: `{"sInt32": " 1234"}`,
346 wantErr: true,
347 }, {
348 desc: "integer string with trailing space",
349 inputMessage: &pb3.Scalars{},
350 inputText: `{"sUint32": "1e2 "}`,
351 wantErr: true,
352 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800353 desc: "number is not an integer",
354 inputMessage: &pb3.Scalars{},
355 inputText: `{"sInt32": 1.001}`,
356 wantErr: true,
357 }, {
358 desc: "32-bit int exceeds limit",
359 inputMessage: &pb3.Scalars{},
360 inputText: `{"sInt32": 2e10}`,
361 wantErr: true,
362 }, {
363 desc: "64-bit int exceeds limit",
364 inputMessage: &pb3.Scalars{},
365 inputText: `{"sSfixed64": -9e19}`,
366 wantErr: true,
367 }, {
368 desc: "not integer",
369 inputMessage: &pb3.Scalars{},
370 inputText: `{"sInt32": "not a number"}`,
371 wantErr: true,
372 }, {
373 desc: "not unsigned integer",
374 inputMessage: &pb3.Scalars{},
375 inputText: `{"sUint32": "not a number"}`,
376 wantErr: true,
377 }, {
378 desc: "number is not an unsigned integer",
379 inputMessage: &pb3.Scalars{},
380 inputText: `{"sUint32": -1}`,
381 wantErr: true,
382 }, {
383 desc: "string",
384 inputMessage: &pb2.Scalars{},
385 inputText: `{"optString": "谷歌"}`,
386 wantMessage: &pb2.Scalars{
387 OptString: scalar.String("谷歌"),
388 },
389 }, {
390 desc: "string with invalid UTF-8",
391 inputMessage: &pb3.Scalars{},
392 inputText: "{\"sString\": \"\xff\"}",
Damien Neil8c86fc52019-06-19 09:28:29 -0700393 wantErr: true,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800394 }, {
395 desc: "not string",
396 inputMessage: &pb2.Scalars{},
397 inputText: `{"optString": 42}`,
398 wantErr: true,
399 }, {
400 desc: "bytes",
401 inputMessage: &pb3.Scalars{},
402 inputText: `{"sBytes": "aGVsbG8gd29ybGQ"}`,
403 wantMessage: &pb3.Scalars{
404 SBytes: []byte("hello world"),
405 },
406 }, {
407 desc: "bytes padded",
408 inputMessage: &pb3.Scalars{},
409 inputText: `{"sBytes": "aGVsbG8gd29ybGQ="}`,
410 wantMessage: &pb3.Scalars{
411 SBytes: []byte("hello world"),
412 },
413 }, {
414 desc: "not bytes",
415 inputMessage: &pb3.Scalars{},
416 inputText: `{"sBytes": true}`,
417 wantErr: true,
418 }, {
419 desc: "proto2 enum",
420 inputMessage: &pb2.Enums{},
421 inputText: `{
422 "optEnum": "ONE",
423 "optNestedEnum": "UNO"
424}`,
425 wantMessage: &pb2.Enums{
426 OptEnum: pb2.Enum_ONE.Enum(),
427 OptNestedEnum: pb2.Enums_UNO.Enum(),
428 },
429 }, {
430 desc: "proto3 enum",
431 inputMessage: &pb3.Enums{},
432 inputText: `{
433 "sEnum": "ONE",
434 "sNestedEnum": "DIEZ"
435}`,
436 wantMessage: &pb3.Enums{
437 SEnum: pb3.Enum_ONE,
438 SNestedEnum: pb3.Enums_DIEZ,
439 },
440 }, {
441 desc: "enum numeric value",
442 inputMessage: &pb3.Enums{},
443 inputText: `{
444 "sEnum": 2,
445 "sNestedEnum": 2
446}`,
447 wantMessage: &pb3.Enums{
448 SEnum: pb3.Enum_TWO,
449 SNestedEnum: pb3.Enums_DOS,
450 },
451 }, {
452 desc: "enum unnamed numeric value",
453 inputMessage: &pb3.Enums{},
454 inputText: `{
455 "sEnum": 101,
456 "sNestedEnum": -101
457}`,
458 wantMessage: &pb3.Enums{
459 SEnum: 101,
460 SNestedEnum: -101,
461 },
462 }, {
463 desc: "enum set to number string",
464 inputMessage: &pb3.Enums{},
465 inputText: `{
Herbie Ong300b9fe2019-03-29 15:42:20 -0700466 "sEnum": "1"
Herbie Ongc96a79d2019-03-08 10:49:17 -0800467}`,
468 wantErr: true,
469 }, {
470 desc: "enum set to invalid named",
471 inputMessage: &pb3.Enums{},
472 inputText: `{
Herbie Ong300b9fe2019-03-29 15:42:20 -0700473 "sEnum": "UNNAMED"
Herbie Ongc96a79d2019-03-08 10:49:17 -0800474}`,
475 wantErr: true,
476 }, {
477 desc: "enum set to not enum",
478 inputMessage: &pb3.Enums{},
479 inputText: `{
Herbie Ong300b9fe2019-03-29 15:42:20 -0700480 "sEnum": true
Herbie Ongc96a79d2019-03-08 10:49:17 -0800481}`,
482 wantErr: true,
483 }, {
Herbie Ong300b9fe2019-03-29 15:42:20 -0700484 desc: "enum set to JSON null",
485 inputMessage: &pb3.Enums{},
486 inputText: `{
487 "sEnum": null
488}`,
489 wantMessage: &pb3.Enums{},
490 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800491 desc: "proto name",
492 inputMessage: &pb3.JSONNames{},
493 inputText: `{
494 "s_string": "proto name used"
495}`,
496 wantMessage: &pb3.JSONNames{
497 SString: "proto name used",
498 },
499 }, {
500 desc: "json_name",
501 inputMessage: &pb3.JSONNames{},
502 inputText: `{
503 "foo_bar": "json_name used"
504}`,
505 wantMessage: &pb3.JSONNames{
506 SString: "json_name used",
507 },
508 }, {
509 desc: "camelCase name",
510 inputMessage: &pb3.JSONNames{},
511 inputText: `{
512 "sString": "camelcase used"
513}`,
514 wantErr: true,
515 }, {
516 desc: "proto name and json_name",
517 inputMessage: &pb3.JSONNames{},
518 inputText: `{
519 "foo_bar": "json_name used",
520 "s_string": "proto name used"
521}`,
522 wantErr: true,
523 }, {
524 desc: "duplicate field names",
525 inputMessage: &pb3.JSONNames{},
526 inputText: `{
527 "foo_bar": "one",
528 "foo_bar": "two",
529}`,
530 wantErr: true,
531 }, {
532 desc: "null message",
533 inputMessage: &pb2.Nests{},
534 inputText: "null",
535 wantErr: true,
536 }, {
537 desc: "proto2 nested message not set",
538 inputMessage: &pb2.Nests{},
539 inputText: "{}",
540 wantMessage: &pb2.Nests{},
541 }, {
542 desc: "proto2 nested message set to null",
543 inputMessage: &pb2.Nests{},
544 inputText: `{
545 "optNested": null,
546 "optgroup": null
547}`,
548 wantMessage: &pb2.Nests{},
549 }, {
550 desc: "proto2 nested message set to empty",
551 inputMessage: &pb2.Nests{},
552 inputText: `{
553 "optNested": {},
554 "optgroup": {}
555}`,
556 wantMessage: &pb2.Nests{
557 OptNested: &pb2.Nested{},
558 Optgroup: &pb2.Nests_OptGroup{},
559 },
560 }, {
561 desc: "proto2 nested messages",
562 inputMessage: &pb2.Nests{},
563 inputText: `{
564 "optNested": {
565 "optString": "nested message",
566 "optNested": {
567 "optString": "another nested message"
568 }
569 }
570}`,
571 wantMessage: &pb2.Nests{
572 OptNested: &pb2.Nested{
573 OptString: scalar.String("nested message"),
574 OptNested: &pb2.Nested{
575 OptString: scalar.String("another nested message"),
576 },
577 },
578 },
579 }, {
580 desc: "proto2 groups",
581 inputMessage: &pb2.Nests{},
582 inputText: `{
583 "optgroup": {
584 "optString": "inside a group",
585 "optNested": {
586 "optString": "nested message inside a group"
587 },
588 "optnestedgroup": {
589 "optFixed32": 47
590 }
591 }
592}`,
593 wantMessage: &pb2.Nests{
594 Optgroup: &pb2.Nests_OptGroup{
595 OptString: scalar.String("inside a group"),
596 OptNested: &pb2.Nested{
597 OptString: scalar.String("nested message inside a group"),
598 },
599 Optnestedgroup: &pb2.Nests_OptGroup_OptNestedGroup{
600 OptFixed32: scalar.Uint32(47),
601 },
602 },
603 },
604 }, {
605 desc: "proto3 nested message not set",
606 inputMessage: &pb3.Nests{},
607 inputText: "{}",
608 wantMessage: &pb3.Nests{},
609 }, {
610 desc: "proto3 nested message set to null",
611 inputMessage: &pb3.Nests{},
612 inputText: `{"sNested": null}`,
613 wantMessage: &pb3.Nests{},
614 }, {
615 desc: "proto3 nested message set to empty",
616 inputMessage: &pb3.Nests{},
617 inputText: `{"sNested": {}}`,
618 wantMessage: &pb3.Nests{
619 SNested: &pb3.Nested{},
620 },
621 }, {
622 desc: "proto3 nested message",
623 inputMessage: &pb3.Nests{},
624 inputText: `{
625 "sNested": {
626 "sString": "nested message",
627 "sNested": {
628 "sString": "another nested message"
629 }
630 }
631}`,
632 wantMessage: &pb3.Nests{
633 SNested: &pb3.Nested{
634 SString: "nested message",
635 SNested: &pb3.Nested{
636 SString: "another nested message",
637 },
638 },
639 },
640 }, {
641 desc: "message set to non-message",
642 inputMessage: &pb3.Nests{},
643 inputText: `"not valid"`,
644 wantErr: true,
645 }, {
646 desc: "nested message set to non-message",
647 inputMessage: &pb3.Nests{},
648 inputText: `{"sNested": true}`,
649 wantErr: true,
650 }, {
651 desc: "oneof not set",
652 inputMessage: &pb3.Oneofs{},
653 inputText: "{}",
654 wantMessage: &pb3.Oneofs{},
655 }, {
656 desc: "oneof set to empty string",
657 inputMessage: &pb3.Oneofs{},
658 inputText: `{"oneofString": ""}`,
659 wantMessage: &pb3.Oneofs{
660 Union: &pb3.Oneofs_OneofString{},
661 },
662 }, {
663 desc: "oneof set to string",
664 inputMessage: &pb3.Oneofs{},
665 inputText: `{"oneofString": "hello"}`,
666 wantMessage: &pb3.Oneofs{
667 Union: &pb3.Oneofs_OneofString{
668 OneofString: "hello",
669 },
670 },
671 }, {
672 desc: "oneof set to enum",
673 inputMessage: &pb3.Oneofs{},
674 inputText: `{"oneofEnum": "ZERO"}`,
675 wantMessage: &pb3.Oneofs{
676 Union: &pb3.Oneofs_OneofEnum{
677 OneofEnum: pb3.Enum_ZERO,
678 },
679 },
680 }, {
681 desc: "oneof set to empty message",
682 inputMessage: &pb3.Oneofs{},
683 inputText: `{"oneofNested": {}}`,
684 wantMessage: &pb3.Oneofs{
685 Union: &pb3.Oneofs_OneofNested{
686 OneofNested: &pb3.Nested{},
687 },
688 },
689 }, {
690 desc: "oneof set to message",
691 inputMessage: &pb3.Oneofs{},
692 inputText: `{
693 "oneofNested": {
694 "sString": "nested message"
695 }
696}`,
697 wantMessage: &pb3.Oneofs{
698 Union: &pb3.Oneofs_OneofNested{
699 OneofNested: &pb3.Nested{
700 SString: "nested message",
701 },
702 },
703 },
704 }, {
Herbie Ong8a1d4602019-04-02 20:19:36 -0700705 desc: "oneof set to more than one field",
706 inputMessage: &pb3.Oneofs{},
707 inputText: `{
708 "oneofEnum": "ZERO",
709 "oneofString": "hello"
710}`,
711 wantErr: true,
712 }, {
713 desc: "oneof set to null and value",
714 inputMessage: &pb3.Oneofs{},
715 inputText: `{
716 "oneofEnum": "ZERO",
717 "oneofString": null
718}`,
719 wantMessage: &pb3.Oneofs{
720 Union: &pb3.Oneofs_OneofEnum{
721 OneofEnum: pb3.Enum_ZERO,
722 },
723 },
724 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800725 desc: "repeated null fields",
726 inputMessage: &pb2.Repeats{},
727 inputText: `{
728 "rptString": null,
729 "rptInt32" : null,
730 "rptFloat" : null,
731 "rptBytes" : null
732}`,
733 wantMessage: &pb2.Repeats{},
734 }, {
735 desc: "repeated scalars",
736 inputMessage: &pb2.Repeats{},
737 inputText: `{
738 "rptString": ["hello", "world"],
739 "rptInt32" : [-1, 0, 1],
740 "rptBool" : [false, true]
741}`,
742 wantMessage: &pb2.Repeats{
743 RptString: []string{"hello", "world"},
744 RptInt32: []int32{-1, 0, 1},
745 RptBool: []bool{false, true},
746 },
747 }, {
748 desc: "repeated enums",
749 inputMessage: &pb2.Enums{},
750 inputText: `{
751 "rptEnum" : ["TEN", 1, 42],
752 "rptNestedEnum": ["DOS", 2, -47]
753}`,
754 wantMessage: &pb2.Enums{
755 RptEnum: []pb2.Enum{pb2.Enum_TEN, pb2.Enum_ONE, 42},
756 RptNestedEnum: []pb2.Enums_NestedEnum{pb2.Enums_DOS, pb2.Enums_DOS, -47},
757 },
758 }, {
759 desc: "repeated messages",
760 inputMessage: &pb2.Nests{},
761 inputText: `{
762 "rptNested": [
763 {
764 "optString": "repeat nested one"
765 },
766 {
767 "optString": "repeat nested two",
768 "optNested": {
769 "optString": "inside repeat nested two"
770 }
771 },
772 {}
773 ]
774}`,
775 wantMessage: &pb2.Nests{
776 RptNested: []*pb2.Nested{
777 {
778 OptString: scalar.String("repeat nested one"),
779 },
780 {
781 OptString: scalar.String("repeat nested two"),
782 OptNested: &pb2.Nested{
783 OptString: scalar.String("inside repeat nested two"),
784 },
785 },
786 {},
787 },
788 },
789 }, {
790 desc: "repeated groups",
791 inputMessage: &pb2.Nests{},
792 inputText: `{
793 "rptgroup": [
794 {
795 "rptString": ["hello", "world"]
796 },
797 {}
798 ]
799}
800`,
801 wantMessage: &pb2.Nests{
802 Rptgroup: []*pb2.Nests_RptGroup{
803 {
804 RptString: []string{"hello", "world"},
805 },
806 {},
807 },
808 },
809 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -0700810 desc: "repeated string contains invalid UTF8",
811 inputMessage: &pb2.Repeats{},
812 inputText: `{"rptString": ["` + "abc\xff" + `"]}`,
Damien Neil8c86fc52019-06-19 09:28:29 -0700813 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -0700814 }, {
815 desc: "repeated messages contain invalid UTF8",
816 inputMessage: &pb2.Nests{},
817 inputText: `{"rptNested": [{"optString": "` + "abc\xff" + `"}]}`,
Damien Neil8c86fc52019-06-19 09:28:29 -0700818 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -0700819 }, {
820 desc: "repeated scalars contain invalid type",
Herbie Ongc96a79d2019-03-08 10:49:17 -0800821 inputMessage: &pb2.Repeats{},
822 inputText: `{"rptString": ["hello", null, "world"]}`,
823 wantErr: true,
824 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -0700825 desc: "repeated messages contain invalid type",
Herbie Ongc96a79d2019-03-08 10:49:17 -0800826 inputMessage: &pb2.Nests{},
827 inputText: `{"rptNested": [{}, null]}`,
828 wantErr: true,
829 }, {
830 desc: "map fields 1",
831 inputMessage: &pb3.Maps{},
832 inputText: `{
833 "int32ToStr": {
834 "-101": "-101",
835 "0" : "zero",
836 "255" : "0xff"
837 },
838 "boolToUint32": {
839 "false": 101,
840 "true" : "42"
841 }
842}`,
843 wantMessage: &pb3.Maps{
844 Int32ToStr: map[int32]string{
845 -101: "-101",
846 0xff: "0xff",
847 0: "zero",
848 },
849 BoolToUint32: map[bool]uint32{
850 true: 42,
851 false: 101,
852 },
853 },
854 }, {
855 desc: "map fields 2",
856 inputMessage: &pb3.Maps{},
857 inputText: `{
858 "uint64ToEnum": {
859 "1" : "ONE",
860 "2" : 2,
861 "10": 101
862 }
863}`,
864 wantMessage: &pb3.Maps{
865 Uint64ToEnum: map[uint64]pb3.Enum{
866 1: pb3.Enum_ONE,
867 2: pb3.Enum_TWO,
868 10: 101,
869 },
870 },
871 }, {
872 desc: "map fields 3",
873 inputMessage: &pb3.Maps{},
874 inputText: `{
875 "strToNested": {
876 "nested_one": {
877 "sString": "nested in a map"
878 },
879 "nested_two": {}
880 }
881}`,
882 wantMessage: &pb3.Maps{
883 StrToNested: map[string]*pb3.Nested{
884 "nested_one": {
885 SString: "nested in a map",
886 },
887 "nested_two": {},
888 },
889 },
890 }, {
891 desc: "map fields 4",
892 inputMessage: &pb3.Maps{},
893 inputText: `{
894 "strToOneofs": {
895 "nested": {
896 "oneofNested": {
897 "sString": "nested oneof in map field value"
898 }
899 },
900 "string": {
901 "oneofString": "hello"
902 }
903 }
904}`,
905 wantMessage: &pb3.Maps{
906 StrToOneofs: map[string]*pb3.Oneofs{
907 "string": {
908 Union: &pb3.Oneofs_OneofString{
909 OneofString: "hello",
910 },
911 },
912 "nested": {
913 Union: &pb3.Oneofs_OneofNested{
914 OneofNested: &pb3.Nested{
915 SString: "nested oneof in map field value",
916 },
917 },
918 },
919 },
920 },
921 }, {
922 desc: "map contains duplicate keys",
923 inputMessage: &pb3.Maps{},
924 inputText: `{
925 "int32ToStr": {
926 "0": "cero",
927 "0": "zero"
928 }
929}
930`,
931 wantErr: true,
932 }, {
933 desc: "map key empty string",
934 inputMessage: &pb3.Maps{},
935 inputText: `{
936 "strToNested": {
937 "": {}
938 }
939}`,
940 wantMessage: &pb3.Maps{
941 StrToNested: map[string]*pb3.Nested{
942 "": {},
943 },
944 },
945 }, {
946 desc: "map contains invalid key 1",
947 inputMessage: &pb3.Maps{},
948 inputText: `{
949 "int32ToStr": {
950 "invalid": "cero"
951}`,
952 wantErr: true,
953 }, {
954 desc: "map contains invalid key 2",
955 inputMessage: &pb3.Maps{},
956 inputText: `{
957 "int32ToStr": {
958 "1.02": "float"
959}`,
960 wantErr: true,
961 }, {
962 desc: "map contains invalid key 3",
963 inputMessage: &pb3.Maps{},
964 inputText: `{
965 "int32ToStr": {
966 "2147483648": "exceeds 32-bit integer max limit"
967}`,
968 wantErr: true,
969 }, {
970 desc: "map contains invalid key 4",
971 inputMessage: &pb3.Maps{},
972 inputText: `{
973 "uint64ToEnum": {
974 "-1": 0
975 }
976}`,
977 wantErr: true,
978 }, {
979 desc: "map contains invalid value",
980 inputMessage: &pb3.Maps{},
981 inputText: `{
982 "int32ToStr": {
983 "101": true
984}`,
985 wantErr: true,
986 }, {
987 desc: "map contains null for scalar value",
988 inputMessage: &pb3.Maps{},
989 inputText: `{
990 "int32ToStr": {
991 "101": null
992}`,
993 wantErr: true,
994 }, {
995 desc: "map contains null for message value",
996 inputMessage: &pb3.Maps{},
997 inputText: `{
998 "strToNested": {
999 "hello": null
1000 }
1001}`,
1002 wantErr: true,
Herbie Onge52379a2019-03-15 18:00:19 -07001003 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -07001004 desc: "map contains contains message value with invalid UTF8",
1005 inputMessage: &pb3.Maps{},
1006 inputText: `{
1007 "strToNested": {
1008 "hello": {
1009 "sString": "` + "abc\xff" + `"
1010 }
1011 }
1012}`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001013 wantErr: true,
1014 }, {
1015 desc: "map key contains invalid UTF8",
1016 inputMessage: &pb3.Maps{},
1017 inputText: `{
1018 "strToNested": {
1019 "` + "abc\xff" + `": {}
1020 }
1021}`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001022 wantErr: true,
1023 }, {
Herbie Ong329be5b2019-03-27 14:47:59 -07001024 desc: "required fields not set",
1025 inputMessage: &pb2.Requireds{},
1026 wantErr: true,
1027 }, {
1028 desc: "required field set",
1029 inputMessage: &pb2.PartialRequired{},
1030 inputText: `{
1031 "reqString": "this is required"
1032}`,
1033 wantMessage: &pb2.PartialRequired{
1034 ReqString: scalar.String("this is required"),
1035 },
1036 }, {
1037 desc: "required fields partially set",
1038 inputMessage: &pb2.Requireds{},
1039 inputText: `{
1040 "reqBool": false,
1041 "reqSfixed64": 42,
1042 "reqString": "hello",
1043 "reqEnum": "ONE"
1044}`,
1045 wantMessage: &pb2.Requireds{
1046 ReqBool: scalar.Bool(false),
1047 ReqSfixed64: scalar.Int64(42),
1048 ReqString: scalar.String("hello"),
1049 ReqEnum: pb2.Enum_ONE.Enum(),
1050 },
1051 wantErr: true,
1052 }, {
1053 desc: "required fields partially set with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001054 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001055 inputMessage: &pb2.Requireds{},
1056 inputText: `{
1057 "reqBool": false,
1058 "reqSfixed64": 42,
1059 "reqString": "hello",
1060 "reqEnum": "ONE"
1061}`,
1062 wantMessage: &pb2.Requireds{
1063 ReqBool: scalar.Bool(false),
1064 ReqSfixed64: scalar.Int64(42),
1065 ReqString: scalar.String("hello"),
1066 ReqEnum: pb2.Enum_ONE.Enum(),
1067 },
1068 }, {
1069 desc: "required fields all set",
1070 inputMessage: &pb2.Requireds{},
1071 inputText: `{
1072 "reqBool": false,
1073 "reqSfixed64": 42,
1074 "reqDouble": 1.23,
1075 "reqString": "hello",
1076 "reqEnum": "ONE",
1077 "reqNested": {}
1078}`,
1079 wantMessage: &pb2.Requireds{
1080 ReqBool: scalar.Bool(false),
1081 ReqSfixed64: scalar.Int64(42),
1082 ReqDouble: scalar.Float64(1.23),
1083 ReqString: scalar.String("hello"),
1084 ReqEnum: pb2.Enum_ONE.Enum(),
1085 ReqNested: &pb2.Nested{},
1086 },
1087 }, {
1088 desc: "indirect required field",
1089 inputMessage: &pb2.IndirectRequired{},
1090 inputText: `{
1091 "optNested": {}
1092}`,
1093 wantMessage: &pb2.IndirectRequired{
1094 OptNested: &pb2.NestedWithRequired{},
1095 },
1096 wantErr: true,
1097 }, {
1098 desc: "indirect required field with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001099 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001100 inputMessage: &pb2.IndirectRequired{},
1101 inputText: `{
1102 "optNested": {}
1103}`,
1104 wantMessage: &pb2.IndirectRequired{
1105 OptNested: &pb2.NestedWithRequired{},
1106 },
1107 }, {
1108 desc: "indirect required field in repeated",
1109 inputMessage: &pb2.IndirectRequired{},
1110 inputText: `{
1111 "rptNested": [
1112 {"reqString": "one"},
1113 {}
1114 ]
1115}`,
1116 wantMessage: &pb2.IndirectRequired{
1117 RptNested: []*pb2.NestedWithRequired{
1118 {
1119 ReqString: scalar.String("one"),
1120 },
1121 {},
1122 },
1123 },
1124 wantErr: true,
1125 }, {
1126 desc: "indirect required field in repeated with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001127 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001128 inputMessage: &pb2.IndirectRequired{},
1129 inputText: `{
1130 "rptNested": [
1131 {"reqString": "one"},
1132 {}
1133 ]
1134}`,
1135 wantMessage: &pb2.IndirectRequired{
1136 RptNested: []*pb2.NestedWithRequired{
1137 {
1138 ReqString: scalar.String("one"),
1139 },
1140 {},
1141 },
1142 },
1143 }, {
1144 desc: "indirect required field in map",
1145 inputMessage: &pb2.IndirectRequired{},
1146 inputText: `{
1147 "strToNested": {
1148 "missing": {},
1149 "contains": {
1150 "reqString": "here"
1151 }
1152 }
1153}`,
1154 wantMessage: &pb2.IndirectRequired{
1155 StrToNested: map[string]*pb2.NestedWithRequired{
1156 "missing": &pb2.NestedWithRequired{},
1157 "contains": &pb2.NestedWithRequired{
1158 ReqString: scalar.String("here"),
1159 },
1160 },
1161 },
1162 wantErr: true,
1163 }, {
1164 desc: "indirect required field in map with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001165 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001166 inputMessage: &pb2.IndirectRequired{},
1167 inputText: `{
1168 "strToNested": {
1169 "missing": {},
1170 "contains": {
1171 "reqString": "here"
1172 }
1173 }
1174}`,
1175 wantMessage: &pb2.IndirectRequired{
1176 StrToNested: map[string]*pb2.NestedWithRequired{
1177 "missing": &pb2.NestedWithRequired{},
1178 "contains": &pb2.NestedWithRequired{
1179 ReqString: scalar.String("here"),
1180 },
1181 },
1182 },
1183 }, {
1184 desc: "indirect required field in oneof",
1185 inputMessage: &pb2.IndirectRequired{},
1186 inputText: `{
1187 "oneofNested": {}
1188}`,
1189 wantMessage: &pb2.IndirectRequired{
1190 Union: &pb2.IndirectRequired_OneofNested{
1191 OneofNested: &pb2.NestedWithRequired{},
1192 },
1193 },
1194 wantErr: true,
1195 }, {
1196 desc: "indirect required field in oneof with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001197 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001198 inputMessage: &pb2.IndirectRequired{},
1199 inputText: `{
1200 "oneofNested": {}
1201}`,
1202 wantMessage: &pb2.IndirectRequired{
1203 Union: &pb2.IndirectRequired_OneofNested{
1204 OneofNested: &pb2.NestedWithRequired{},
1205 },
1206 },
1207 }, {
Herbie Onge52379a2019-03-15 18:00:19 -07001208 desc: "extensions of non-repeated fields",
1209 inputMessage: &pb2.Extensions{},
1210 inputText: `{
1211 "optString": "non-extension field",
1212 "optBool": true,
1213 "optInt32": 42,
1214 "[pb2.opt_ext_bool]": true,
1215 "[pb2.opt_ext_nested]": {
1216 "optString": "nested in an extension",
Herbie Onge63c4c42019-03-22 22:20:22 -07001217 "optNested": {
1218 "optString": "another nested in an extension"
Herbie Onge52379a2019-03-15 18:00:19 -07001219 }
1220 },
1221 "[pb2.opt_ext_string]": "extension field",
1222 "[pb2.opt_ext_enum]": "TEN"
1223}`,
1224 wantMessage: func() proto.Message {
1225 m := &pb2.Extensions{
1226 OptString: scalar.String("non-extension field"),
1227 OptBool: scalar.Bool(true),
1228 OptInt32: scalar.Int32(42),
1229 }
1230 setExtension(m, pb2.E_OptExtBool, true)
1231 setExtension(m, pb2.E_OptExtString, "extension field")
1232 setExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
1233 setExtension(m, pb2.E_OptExtNested, &pb2.Nested{
1234 OptString: scalar.String("nested in an extension"),
1235 OptNested: &pb2.Nested{
1236 OptString: scalar.String("another nested in an extension"),
1237 },
1238 })
1239 return m
1240 }(),
1241 }, {
1242 desc: "extensions of repeated fields",
1243 inputMessage: &pb2.Extensions{},
1244 inputText: `{
1245 "[pb2.rpt_ext_enum]": ["TEN", 101, "ONE"],
1246 "[pb2.rpt_ext_fixed32]": [42, 47],
1247 "[pb2.rpt_ext_nested]": [
1248 {"optString": "one"},
1249 {"optString": "two"},
1250 {"optString": "three"}
1251 ]
1252}`,
1253 wantMessage: func() proto.Message {
1254 m := &pb2.Extensions{}
1255 setExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
1256 setExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
1257 setExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
1258 &pb2.Nested{OptString: scalar.String("one")},
1259 &pb2.Nested{OptString: scalar.String("two")},
1260 &pb2.Nested{OptString: scalar.String("three")},
1261 })
1262 return m
1263 }(),
1264 }, {
1265 desc: "extensions of non-repeated fields in another message",
1266 inputMessage: &pb2.Extensions{},
1267 inputText: `{
1268 "[pb2.ExtensionsContainer.opt_ext_bool]": true,
1269 "[pb2.ExtensionsContainer.opt_ext_enum]": "TEN",
1270 "[pb2.ExtensionsContainer.opt_ext_nested]": {
1271 "optString": "nested in an extension",
1272 "optNested": {
1273 "optString": "another nested in an extension"
1274 }
1275 },
1276 "[pb2.ExtensionsContainer.opt_ext_string]": "extension field"
1277}`,
1278 wantMessage: func() proto.Message {
1279 m := &pb2.Extensions{}
1280 setExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
1281 setExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
1282 setExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
1283 setExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
1284 OptString: scalar.String("nested in an extension"),
1285 OptNested: &pb2.Nested{
1286 OptString: scalar.String("another nested in an extension"),
1287 },
1288 })
1289 return m
1290 }(),
1291 }, {
1292 desc: "extensions of repeated fields in another message",
1293 inputMessage: &pb2.Extensions{},
1294 inputText: `{
1295 "optString": "non-extension field",
1296 "optBool": true,
1297 "optInt32": 42,
1298 "[pb2.ExtensionsContainer.rpt_ext_nested]": [
1299 {"optString": "one"},
1300 {"optString": "two"},
1301 {"optString": "three"}
1302 ],
1303 "[pb2.ExtensionsContainer.rpt_ext_enum]": ["TEN", 101, "ONE"],
1304 "[pb2.ExtensionsContainer.rpt_ext_string]": ["hello", "world"]
1305}`,
1306 wantMessage: func() proto.Message {
1307 m := &pb2.Extensions{
1308 OptString: scalar.String("non-extension field"),
1309 OptBool: scalar.Bool(true),
1310 OptInt32: scalar.Int32(42),
1311 }
1312 setExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
1313 setExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
1314 setExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
1315 &pb2.Nested{OptString: scalar.String("one")},
1316 &pb2.Nested{OptString: scalar.String("two")},
1317 &pb2.Nested{OptString: scalar.String("three")},
1318 })
1319 return m
1320 }(),
1321 }, {
1322 desc: "invalid extension field name",
1323 inputMessage: &pb2.Extensions{},
1324 inputText: `{ "[pb2.invalid_message_field]": true }`,
1325 wantErr: true,
1326 }, {
1327 desc: "MessageSet",
1328 inputMessage: &pb2.MessageSet{},
1329 inputText: `{
1330 "[pb2.MessageSetExtension]": {
1331 "optString": "a messageset extension"
1332 },
1333 "[pb2.MessageSetExtension.ext_nested]": {
1334 "optString": "just a regular extension"
1335 },
1336 "[pb2.MessageSetExtension.not_message_set_extension]": {
1337 "optString": "not a messageset extension"
1338 }
1339}`,
1340 wantMessage: func() proto.Message {
1341 m := &pb2.MessageSet{}
1342 setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
1343 OptString: scalar.String("a messageset extension"),
1344 })
1345 setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
1346 OptString: scalar.String("not a messageset extension"),
1347 })
1348 setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
1349 OptString: scalar.String("just a regular extension"),
1350 })
1351 return m
1352 }(),
1353 }, {
Herbie Onge52379a2019-03-15 18:00:19 -07001354 desc: "extensions of repeated field contains null",
1355 inputMessage: &pb2.Extensions{},
1356 inputText: `{
1357 "[pb2.ExtensionsContainer.rpt_ext_nested]": [
1358 {"optString": "one"},
1359 null,
1360 {"optString": "three"}
1361 ],
1362}`,
1363 wantErr: true,
1364 }, {
1365 desc: "not real MessageSet 1",
1366 inputMessage: &pb2.FakeMessageSet{},
1367 inputText: `{
1368 "[pb2.FakeMessageSetExtension.message_set_extension]": {
1369 "optString": "not a messageset extension"
1370 }
1371}`,
1372 wantMessage: func() proto.Message {
1373 m := &pb2.FakeMessageSet{}
1374 setExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
1375 OptString: scalar.String("not a messageset extension"),
1376 })
1377 return m
1378 }(),
1379 }, {
1380 desc: "not real MessageSet 2",
1381 inputMessage: &pb2.FakeMessageSet{},
1382 inputText: `{
1383 "[pb2.FakeMessageSetExtension]": {
1384 "optString": "not a messageset extension"
1385 }
1386}`,
1387 wantErr: true,
1388 }, {
1389 desc: "not real MessageSet 3",
1390 inputMessage: &pb2.MessageSet{},
1391 inputText: `{
1392 "[pb2.message_set_extension]": {
1393 "optString": "another not a messageset extension"
1394 }
1395}`,
1396 wantMessage: func() proto.Message {
1397 m := &pb2.MessageSet{}
1398 setExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
1399 OptString: scalar.String("another not a messageset extension"),
1400 })
1401 return m
1402 }(),
Herbie Onge63c4c42019-03-22 22:20:22 -07001403 }, {
1404 desc: "Empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001405 inputMessage: &emptypb.Empty{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001406 inputText: `{}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001407 wantMessage: &emptypb.Empty{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001408 }, {
1409 desc: "Empty contains unknown",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001410 inputMessage: &emptypb.Empty{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001411 inputText: `{"unknown": null}`,
1412 wantErr: true,
1413 }, {
1414 desc: "BoolValue false",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001415 inputMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001416 inputText: `false`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001417 wantMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001418 }, {
1419 desc: "BoolValue true",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001420 inputMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001421 inputText: `true`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001422 wantMessage: &wrapperspb.BoolValue{Value: true},
Herbie Onge63c4c42019-03-22 22:20:22 -07001423 }, {
1424 desc: "BoolValue invalid value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001425 inputMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001426 inputText: `{}`,
1427 wantErr: true,
1428 }, {
1429 desc: "Int32Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001430 inputMessage: &wrapperspb.Int32Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001431 inputText: `42`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001432 wantMessage: &wrapperspb.Int32Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001433 }, {
1434 desc: "Int32Value in JSON string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001435 inputMessage: &wrapperspb.Int32Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001436 inputText: `"1.23e3"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001437 wantMessage: &wrapperspb.Int32Value{Value: 1230},
Herbie Onge63c4c42019-03-22 22:20:22 -07001438 }, {
1439 desc: "Int64Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001440 inputMessage: &wrapperspb.Int64Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001441 inputText: `"42"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001442 wantMessage: &wrapperspb.Int64Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001443 }, {
1444 desc: "UInt32Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001445 inputMessage: &wrapperspb.UInt32Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001446 inputText: `42`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001447 wantMessage: &wrapperspb.UInt32Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001448 }, {
1449 desc: "UInt64Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001450 inputMessage: &wrapperspb.UInt64Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001451 inputText: `"42"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001452 wantMessage: &wrapperspb.UInt64Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001453 }, {
1454 desc: "FloatValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001455 inputMessage: &wrapperspb.FloatValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001456 inputText: `1.02`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001457 wantMessage: &wrapperspb.FloatValue{Value: 1.02},
Herbie Onge63c4c42019-03-22 22:20:22 -07001458 }, {
1459 desc: "FloatValue exceeds max limit",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001460 inputMessage: &wrapperspb.FloatValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001461 inputText: `1.23+40`,
1462 wantErr: true,
1463 }, {
1464 desc: "FloatValue Infinity",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001465 inputMessage: &wrapperspb.FloatValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001466 inputText: `"-Infinity"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001467 wantMessage: &wrapperspb.FloatValue{Value: float32(math.Inf(-1))},
Herbie Onge63c4c42019-03-22 22:20:22 -07001468 }, {
1469 desc: "DoubleValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001470 inputMessage: &wrapperspb.DoubleValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001471 inputText: `1.02`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001472 wantMessage: &wrapperspb.DoubleValue{Value: 1.02},
Herbie Onge63c4c42019-03-22 22:20:22 -07001473 }, {
1474 desc: "DoubleValue Infinity",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001475 inputMessage: &wrapperspb.DoubleValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001476 inputText: `"Infinity"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001477 wantMessage: &wrapperspb.DoubleValue{Value: math.Inf(+1)},
Herbie Onge63c4c42019-03-22 22:20:22 -07001478 }, {
1479 desc: "StringValue empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001480 inputMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001481 inputText: `""`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001482 wantMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001483 }, {
1484 desc: "StringValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001485 inputMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001486 inputText: `"谷歌"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001487 wantMessage: &wrapperspb.StringValue{Value: "谷歌"},
Herbie Onge63c4c42019-03-22 22:20:22 -07001488 }, {
1489 desc: "StringValue with invalid UTF8 error",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001490 inputMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001491 inputText: "\"abc\xff\"",
Herbie Onge63c4c42019-03-22 22:20:22 -07001492 wantErr: true,
1493 }, {
1494 desc: "StringValue field with invalid UTF8 error",
1495 inputMessage: &pb2.KnownTypes{},
1496 inputText: "{\n \"optString\": \"abc\xff\"\n}",
Damien Neil8c86fc52019-06-19 09:28:29 -07001497 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -07001498 }, {
Herbie Ong300b9fe2019-03-29 15:42:20 -07001499 desc: "NullValue field with JSON null",
1500 inputMessage: &pb2.KnownTypes{},
1501 inputText: `{
1502 "optNull": null
1503}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001504 wantMessage: &pb2.KnownTypes{OptNull: new(structpb.NullValue)},
Herbie Ong300b9fe2019-03-29 15:42:20 -07001505 }, {
1506 desc: "NullValue field with string",
1507 inputMessage: &pb2.KnownTypes{},
1508 inputText: `{
1509 "optNull": "NULL_VALUE"
1510}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001511 wantMessage: &pb2.KnownTypes{OptNull: new(structpb.NullValue)},
Herbie Ong300b9fe2019-03-29 15:42:20 -07001512 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -07001513 desc: "BytesValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001514 inputMessage: &wrapperspb.BytesValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001515 inputText: `"aGVsbG8="`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001516 wantMessage: &wrapperspb.BytesValue{Value: []byte("hello")},
Herbie Onge63c4c42019-03-22 22:20:22 -07001517 }, {
1518 desc: "Value null",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001519 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001520 inputText: `null`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001521 wantMessage: &structpb.Value{Kind: &structpb.Value_NullValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001522 }, {
1523 desc: "Value field null",
1524 inputMessage: &pb2.KnownTypes{},
1525 inputText: `{
1526 "optValue": null
1527}`,
1528 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001529 OptValue: &structpb.Value{Kind: &structpb.Value_NullValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001530 },
1531 }, {
1532 desc: "Value bool",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001533 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001534 inputText: `false`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001535 wantMessage: &structpb.Value{Kind: &structpb.Value_BoolValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001536 }, {
1537 desc: "Value field bool",
1538 inputMessage: &pb2.KnownTypes{},
1539 inputText: `{
1540 "optValue": true
1541}`,
1542 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001543 OptValue: &structpb.Value{Kind: &structpb.Value_BoolValue{true}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001544 },
1545 }, {
1546 desc: "Value number",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001547 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001548 inputText: `1.02`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001549 wantMessage: &structpb.Value{Kind: &structpb.Value_NumberValue{1.02}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001550 }, {
1551 desc: "Value field number",
1552 inputMessage: &pb2.KnownTypes{},
1553 inputText: `{
1554 "optValue": 1.02
1555}`,
1556 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001557 OptValue: &structpb.Value{Kind: &structpb.Value_NumberValue{1.02}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001558 },
1559 }, {
1560 desc: "Value string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001561 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001562 inputText: `"hello"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001563 wantMessage: &structpb.Value{Kind: &structpb.Value_StringValue{"hello"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001564 }, {
1565 desc: "Value string with invalid UTF8",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001566 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001567 inputText: "\"\xff\"",
Herbie Onge63c4c42019-03-22 22:20:22 -07001568 wantErr: true,
1569 }, {
1570 desc: "Value field string",
1571 inputMessage: &pb2.KnownTypes{},
1572 inputText: `{
1573 "optValue": "NaN"
1574}`,
1575 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001576 OptValue: &structpb.Value{Kind: &structpb.Value_StringValue{"NaN"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001577 },
1578 }, {
1579 desc: "Value field string with invalid UTF8",
1580 inputMessage: &pb2.KnownTypes{},
1581 inputText: `{
1582 "optValue": "` + "\xff" + `"
1583}`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001584 wantErr: true,
1585 }, {
1586 desc: "Value empty struct",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001587 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001588 inputText: `{}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001589 wantMessage: &structpb.Value{
1590 Kind: &structpb.Value_StructValue{
1591 &structpb.Struct{Fields: map[string]*structpb.Value{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001592 },
1593 },
1594 }, {
1595 desc: "Value struct",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001596 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001597 inputText: `{
1598 "string": "hello",
1599 "number": 123,
1600 "null": null,
1601 "bool": false,
1602 "struct": {
1603 "string": "world"
1604 },
1605 "list": []
1606}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001607 wantMessage: &structpb.Value{
1608 Kind: &structpb.Value_StructValue{
1609 &structpb.Struct{
1610 Fields: map[string]*structpb.Value{
1611 "string": {Kind: &structpb.Value_StringValue{"hello"}},
1612 "number": {Kind: &structpb.Value_NumberValue{123}},
1613 "null": {Kind: &structpb.Value_NullValue{}},
1614 "bool": {Kind: &structpb.Value_BoolValue{false}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001615 "struct": {
Joe Tsaia95b29f2019-05-16 12:47:20 -07001616 Kind: &structpb.Value_StructValue{
1617 &structpb.Struct{
1618 Fields: map[string]*structpb.Value{
1619 "string": {Kind: &structpb.Value_StringValue{"world"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001620 },
1621 },
1622 },
1623 },
1624 "list": {
Joe Tsaia95b29f2019-05-16 12:47:20 -07001625 Kind: &structpb.Value_ListValue{&structpb.ListValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001626 },
1627 },
1628 },
1629 },
1630 },
1631 }, {
1632 desc: "Value struct with invalid UTF8 string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001633 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001634 inputText: "{\"string\": \"abc\xff\"}",
Damien Neil8c86fc52019-06-19 09:28:29 -07001635 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -07001636 }, {
1637 desc: "Value field struct",
1638 inputMessage: &pb2.KnownTypes{},
1639 inputText: `{
1640 "optValue": {
1641 "string": "hello"
1642 }
1643}`,
1644 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001645 OptValue: &structpb.Value{
1646 Kind: &structpb.Value_StructValue{
1647 &structpb.Struct{
1648 Fields: map[string]*structpb.Value{
1649 "string": {Kind: &structpb.Value_StringValue{"hello"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001650 },
1651 },
1652 },
1653 },
1654 },
1655 }, {
1656 desc: "Value empty list",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001657 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001658 inputText: `[]`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001659 wantMessage: &structpb.Value{
1660 Kind: &structpb.Value_ListValue{
1661 &structpb.ListValue{Values: []*structpb.Value{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001662 },
1663 },
1664 }, {
1665 desc: "Value list",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001666 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001667 inputText: `[
1668 "string",
1669 123,
1670 null,
1671 true,
1672 {},
1673 [
1674 "string",
1675 1.23,
1676 null,
1677 false
1678 ]
1679]`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001680 wantMessage: &structpb.Value{
1681 Kind: &structpb.Value_ListValue{
1682 &structpb.ListValue{
1683 Values: []*structpb.Value{
1684 {Kind: &structpb.Value_StringValue{"string"}},
1685 {Kind: &structpb.Value_NumberValue{123}},
1686 {Kind: &structpb.Value_NullValue{}},
1687 {Kind: &structpb.Value_BoolValue{true}},
1688 {Kind: &structpb.Value_StructValue{&structpb.Struct{}}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001689 {
Joe Tsaia95b29f2019-05-16 12:47:20 -07001690 Kind: &structpb.Value_ListValue{
1691 &structpb.ListValue{
1692 Values: []*structpb.Value{
1693 {Kind: &structpb.Value_StringValue{"string"}},
1694 {Kind: &structpb.Value_NumberValue{1.23}},
1695 {Kind: &structpb.Value_NullValue{}},
1696 {Kind: &structpb.Value_BoolValue{false}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001697 },
1698 },
1699 },
1700 },
1701 },
1702 },
1703 },
1704 },
1705 }, {
1706 desc: "Value list with invalid UTF8 string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001707 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001708 inputText: "[\"abc\xff\"]",
Damien Neil8c86fc52019-06-19 09:28:29 -07001709 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -07001710 }, {
1711 desc: "Value field list with invalid UTF8 string",
1712 inputMessage: &pb2.KnownTypes{},
1713 inputText: `{
1714 "optValue": [ "` + "abc\xff" + `"]
1715}`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001716 wantErr: true,
1717 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001718 desc: "Duration empty string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001719 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001720 inputText: `""`,
1721 wantErr: true,
1722 }, {
1723 desc: "Duration with secs",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001724 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001725 inputText: `"3s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001726 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ongc4450372019-03-27 09:59:51 -07001727 }, {
1728 desc: "Duration with escaped unicode",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001729 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001730 inputText: `"\u0033s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001731 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ongc4450372019-03-27 09:59:51 -07001732 }, {
1733 desc: "Duration with -secs",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001734 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001735 inputText: `"-3s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001736 wantMessage: &durationpb.Duration{Seconds: -3},
Herbie Ongc4450372019-03-27 09:59:51 -07001737 }, {
Herbie Ong17523eb2019-03-29 17:46:57 -07001738 desc: "Duration with plus sign",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001739 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001740 inputText: `"+3s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001741 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ong17523eb2019-03-29 17:46:57 -07001742 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001743 desc: "Duration with nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001744 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001745 inputText: `"0.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001746 wantMessage: &durationpb.Duration{Nanos: 1e6},
Herbie Ongc4450372019-03-27 09:59:51 -07001747 }, {
1748 desc: "Duration with -nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001749 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001750 inputText: `"-0.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001751 wantMessage: &durationpb.Duration{Nanos: -1e6},
Herbie Ongc4450372019-03-27 09:59:51 -07001752 }, {
Herbie Ong17523eb2019-03-29 17:46:57 -07001753 desc: "Duration with -nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001754 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001755 inputText: `"-.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001756 wantMessage: &durationpb.Duration{Nanos: -1e6},
Herbie Ong17523eb2019-03-29 17:46:57 -07001757 }, {
1758 desc: "Duration with +nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001759 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001760 inputText: `"+.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001761 wantMessage: &durationpb.Duration{Nanos: 1e6},
Herbie Ong17523eb2019-03-29 17:46:57 -07001762 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001763 desc: "Duration with -secs -nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001764 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001765 inputText: `"-123.000000450s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001766 wantMessage: &durationpb.Duration{Seconds: -123, Nanos: -450},
Herbie Ongc4450372019-03-27 09:59:51 -07001767 }, {
1768 desc: "Duration with large secs",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001769 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001770 inputText: `"10000000000.000000001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001771 wantMessage: &durationpb.Duration{Seconds: 1e10, Nanos: 1},
Herbie Ongc4450372019-03-27 09:59:51 -07001772 }, {
1773 desc: "Duration with decimal without fractional",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001774 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001775 inputText: `"3.s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001776 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ongc4450372019-03-27 09:59:51 -07001777 }, {
1778 desc: "Duration with decimal without integer",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001779 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001780 inputText: `"0.5s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001781 wantMessage: &durationpb.Duration{Nanos: 5e8},
Herbie Ongc4450372019-03-27 09:59:51 -07001782 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001783 desc: "Duration max value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001784 inputMessage: &durationpb.Duration{},
Herbie Ongad9c1252019-04-24 20:51:28 -07001785 inputText: `"315576000000.999999999s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001786 wantMessage: &durationpb.Duration{Seconds: 315576000000, Nanos: 999999999},
Herbie Ongad9c1252019-04-24 20:51:28 -07001787 }, {
1788 desc: "Duration min value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001789 inputMessage: &durationpb.Duration{},
Herbie Ongad9c1252019-04-24 20:51:28 -07001790 inputText: `"-315576000000.999999999s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001791 wantMessage: &durationpb.Duration{Seconds: -315576000000, Nanos: -999999999},
Herbie Ongad9c1252019-04-24 20:51:28 -07001792 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001793 desc: "Duration with +secs out of range",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001794 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001795 inputText: `"315576000001s"`,
1796 wantErr: true,
1797 }, {
1798 desc: "Duration with -secs out of range",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001799 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001800 inputText: `"-315576000001s"`,
1801 wantErr: true,
1802 }, {
1803 desc: "Duration with nanos beyond 9 digits",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001804 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001805 inputText: `"0.1000000000s"`,
Herbie Ongc4450372019-03-27 09:59:51 -07001806 wantErr: true,
1807 }, {
1808 desc: "Duration without suffix s",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001809 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001810 inputText: `"123"`,
1811 wantErr: true,
1812 }, {
Herbie Ong17523eb2019-03-29 17:46:57 -07001813 desc: "Duration invalid signed fraction",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001814 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001815 inputText: `"123.+123s"`,
1816 wantErr: true,
1817 }, {
1818 desc: "Duration invalid multiple .",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001819 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001820 inputText: `"123.123.s"`,
1821 wantErr: true,
1822 }, {
1823 desc: "Duration invalid integer",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001824 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001825 inputText: `"01s"`,
1826 wantErr: true,
1827 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001828 desc: "Timestamp zero",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001829 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001830 inputText: `"1970-01-01T00:00:00Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001831 wantMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001832 }, {
1833 desc: "Timestamp with tz adjustment",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001834 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001835 inputText: `"1970-01-01T00:00:00+01:00"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001836 wantMessage: &timestamppb.Timestamp{Seconds: -3600},
Herbie Ongc4450372019-03-27 09:59:51 -07001837 }, {
1838 desc: "Timestamp UTC",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001839 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001840 inputText: `"2019-03-19T23:03:21Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001841 wantMessage: &timestamppb.Timestamp{Seconds: 1553036601},
Herbie Ongc4450372019-03-27 09:59:51 -07001842 }, {
1843 desc: "Timestamp with escaped unicode",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001844 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001845 inputText: `"2019-0\u0033-19T23:03:21Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001846 wantMessage: &timestamppb.Timestamp{Seconds: 1553036601},
Herbie Ongc4450372019-03-27 09:59:51 -07001847 }, {
1848 desc: "Timestamp with nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001849 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001850 inputText: `"2019-03-19T23:03:21.000000001Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001851 wantMessage: &timestamppb.Timestamp{Seconds: 1553036601, Nanos: 1},
Herbie Ongc4450372019-03-27 09:59:51 -07001852 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001853 desc: "Timestamp max value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001854 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001855 inputText: `"9999-12-31T23:59:59.999999999Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001856 wantMessage: &timestamppb.Timestamp{Seconds: 253402300799, Nanos: 999999999},
Herbie Ongc4450372019-03-27 09:59:51 -07001857 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001858 desc: "Timestamp above max value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001859 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001860 inputText: `"9999-12-31T23:59:59-01:00"`,
1861 wantErr: true,
1862 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001863 desc: "Timestamp min value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001864 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001865 inputText: `"0001-01-01T00:00:00Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001866 wantMessage: &timestamppb.Timestamp{Seconds: -62135596800},
Herbie Ongc4450372019-03-27 09:59:51 -07001867 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001868 desc: "Timestamp below min value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001869 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001870 inputText: `"0001-01-01T00:00:00+01:00"`,
1871 wantErr: true,
1872 }, {
1873 desc: "Timestamp with nanos beyond 9 digits",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001874 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001875 inputText: `"1970-01-01T00:00:00.0000000001Z"`,
1876 wantErr: true,
1877 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -07001878 desc: "FieldMask empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001879 inputMessage: &fieldmaskpb.FieldMask{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001880 inputText: `""`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001881 wantMessage: &fieldmaskpb.FieldMask{Paths: []string{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001882 }, {
1883 desc: "FieldMask",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001884 inputMessage: &fieldmaskpb.FieldMask{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001885 inputText: `"foo,fooBar , foo.barQux ,Foo"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001886 wantMessage: &fieldmaskpb.FieldMask{
Herbie Onge63c4c42019-03-22 22:20:22 -07001887 Paths: []string{
1888 "foo",
1889 "foo_bar",
1890 "foo.bar_qux",
1891 "_foo",
1892 },
1893 },
1894 }, {
1895 desc: "FieldMask field",
1896 inputMessage: &pb2.KnownTypes{},
1897 inputText: `{
1898 "optFieldmask": "foo, qux.fooBar"
1899}`,
1900 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001901 OptFieldmask: &fieldmaskpb.FieldMask{
Herbie Onge63c4c42019-03-22 22:20:22 -07001902 Paths: []string{
1903 "foo",
1904 "qux.foo_bar",
1905 },
1906 },
1907 },
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001908 }, {
1909 desc: "Any empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001910 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001911 inputText: `{}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001912 wantMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001913 }, {
1914 desc: "Any with non-custom message",
Damien Neil5c5b5312019-05-14 12:44:37 -07001915 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001916 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001917 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001918 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001919 inputText: `{
1920 "@type": "foo/pb2.Nested",
1921 "optString": "embedded inside Any",
1922 "optNested": {
1923 "optString": "inception"
1924 }
1925}`,
1926 wantMessage: func() proto.Message {
1927 m := &pb2.Nested{
1928 OptString: scalar.String("embedded inside Any"),
1929 OptNested: &pb2.Nested{
1930 OptString: scalar.String("inception"),
1931 },
1932 }
1933 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
1934 if err != nil {
1935 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1936 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001937 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001938 TypeUrl: "foo/pb2.Nested",
1939 Value: b,
1940 }
1941 }(),
1942 }, {
1943 desc: "Any with empty embedded message",
Damien Neil5c5b5312019-05-14 12:44:37 -07001944 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001945 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001946 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001947 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07001948 inputText: `{"@type": "foo/pb2.Nested"}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001949 wantMessage: &anypb.Any{TypeUrl: "foo/pb2.Nested"},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001950 }, {
1951 desc: "Any without registered type",
Damien Neil5c5b5312019-05-14 12:44:37 -07001952 umo: protojson.UnmarshalOptions{Resolver: preg.NewTypes()},
Joe Tsaia95b29f2019-05-16 12:47:20 -07001953 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07001954 inputText: `{"@type": "foo/pb2.Nested"}`,
1955 wantErr: true,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001956 }, {
Damien Neil0c9f0a92019-06-19 10:41:09 -07001957 desc: "Any with missing required",
Damien Neil5c5b5312019-05-14 12:44:37 -07001958 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001959 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.PartialRequired{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001960 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001961 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001962 inputText: `{
1963 "@type": "pb2.PartialRequired",
1964 "optString": "embedded inside Any"
1965}`,
1966 wantMessage: func() proto.Message {
1967 m := &pb2.PartialRequired{
1968 OptString: scalar.String("embedded inside Any"),
1969 }
Damien Neil96c229a2019-04-03 12:17:24 -07001970 b, err := proto.MarshalOptions{
1971 Deterministic: true,
1972 AllowPartial: true,
1973 }.Marshal(m)
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001974 if err != nil {
1975 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1976 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001977 return &anypb.Any{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001978 TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001979 Value: b,
1980 }
1981 }(),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001982 }, {
1983 desc: "Any with partial required and AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001984 umo: protojson.UnmarshalOptions{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001985 AllowPartial: true,
Joe Tsai0fc49f82019-05-01 12:29:25 -07001986 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.PartialRequired{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001987 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001988 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001989 inputText: `{
1990 "@type": "pb2.PartialRequired",
1991 "optString": "embedded inside Any"
1992}`,
1993 wantMessage: func() proto.Message {
1994 m := &pb2.PartialRequired{
1995 OptString: scalar.String("embedded inside Any"),
1996 }
Damien Neil96c229a2019-04-03 12:17:24 -07001997 b, err := proto.MarshalOptions{
1998 Deterministic: true,
1999 AllowPartial: true,
2000 }.Marshal(m)
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002001 if err != nil {
2002 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2003 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002004 return &anypb.Any{
Joe Tsai0fc49f82019-05-01 12:29:25 -07002005 TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002006 Value: b,
2007 }
2008 }(),
2009 }, {
2010 desc: "Any with invalid UTF8",
Damien Neil5c5b5312019-05-14 12:44:37 -07002011 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07002012 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002013 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002014 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002015 inputText: `{
2016 "optString": "` + "abc\xff" + `",
2017 "@type": "foo/pb2.Nested"
2018}`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002019 wantErr: true,
2020 }, {
2021 desc: "Any with BoolValue",
Damien Neil5c5b5312019-05-14 12:44:37 -07002022 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002023 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.BoolValue{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002024 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002025 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002026 inputText: `{
2027 "@type": "type.googleapis.com/google.protobuf.BoolValue",
2028 "value": true
2029}`,
2030 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002031 m := &wrapperspb.BoolValue{Value: true}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002032 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2033 if err != nil {
2034 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2035 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002036 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002037 TypeUrl: "type.googleapis.com/google.protobuf.BoolValue",
2038 Value: b,
2039 }
2040 }(),
2041 }, {
2042 desc: "Any with Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002043 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002044 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&emptypb.Empty{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002045 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002046 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002047 inputText: `{
2048 "value": {},
2049 "@type": "type.googleapis.com/google.protobuf.Empty"
2050}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002051 wantMessage: &anypb.Any{
Herbie Ong4f0be712019-04-25 17:57:12 -07002052 TypeUrl: "type.googleapis.com/google.protobuf.Empty",
2053 },
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002054 }, {
2055 desc: "Any with missing Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002056 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002057 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&emptypb.Empty{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002058 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002059 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002060 inputText: `{
2061 "@type": "type.googleapis.com/google.protobuf.Empty"
2062}`,
2063 wantErr: true,
2064 }, {
2065 desc: "Any with StringValue containing invalid UTF8",
Damien Neil5c5b5312019-05-14 12:44:37 -07002066 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002067 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002068 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002069 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002070 inputText: `{
2071 "@type": "google.protobuf.StringValue",
2072 "value": "` + "abc\xff" + `"
2073}`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002074 wantErr: true,
2075 }, {
2076 desc: "Any with Int64Value",
Damien Neil5c5b5312019-05-14 12:44:37 -07002077 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002078 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.Int64Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002079 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002080 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002081 inputText: `{
2082 "@type": "google.protobuf.Int64Value",
2083 "value": "42"
2084}`,
2085 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002086 m := &wrapperspb.Int64Value{Value: 42}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002087 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2088 if err != nil {
2089 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2090 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002091 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002092 TypeUrl: "google.protobuf.Int64Value",
2093 Value: b,
2094 }
2095 }(),
2096 }, {
2097 desc: "Any with invalid Int64Value",
Damien Neil5c5b5312019-05-14 12:44:37 -07002098 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002099 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.Int64Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002100 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002101 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002102 inputText: `{
2103 "@type": "google.protobuf.Int64Value",
2104 "value": "forty-two"
2105}`,
2106 wantErr: true,
2107 }, {
2108 desc: "Any with invalid UInt64Value",
Damien Neil5c5b5312019-05-14 12:44:37 -07002109 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002110 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.UInt64Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002111 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002112 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002113 inputText: `{
2114 "@type": "google.protobuf.UInt64Value",
2115 "value": -42
2116}`,
2117 wantErr: true,
2118 }, {
2119 desc: "Any with Duration",
Damien Neil5c5b5312019-05-14 12:44:37 -07002120 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002121 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&durationpb.Duration{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002122 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002123 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002124 inputText: `{
2125 "@type": "type.googleapis.com/google.protobuf.Duration",
2126 "value": "0s"
2127}`,
2128 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002129 m := &durationpb.Duration{}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002130 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2131 if err != nil {
2132 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2133 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002134 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002135 TypeUrl: "type.googleapis.com/google.protobuf.Duration",
2136 Value: b,
2137 }
2138 }(),
2139 }, {
2140 desc: "Any with Value of StringValue",
Damien Neil5c5b5312019-05-14 12:44:37 -07002141 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002142 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&structpb.Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002143 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002144 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002145 inputText: `{
2146 "@type": "google.protobuf.Value",
2147 "value": "` + "abc\xff" + `"
2148}`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002149 wantErr: true,
2150 }, {
2151 desc: "Any with Value of NullValue",
Damien Neil5c5b5312019-05-14 12:44:37 -07002152 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002153 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&structpb.Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002154 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002155 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002156 inputText: `{
2157 "@type": "google.protobuf.Value",
2158 "value": null
2159}`,
2160 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002161 m := &structpb.Value{Kind: &structpb.Value_NullValue{}}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002162 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2163 if err != nil {
2164 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2165 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002166 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002167 TypeUrl: "google.protobuf.Value",
2168 Value: b,
2169 }
2170 }(),
2171 }, {
2172 desc: "Any with Struct",
Damien Neil5c5b5312019-05-14 12:44:37 -07002173 umo: protojson.UnmarshalOptions{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002174 Resolver: preg.NewTypes(
Joe Tsaia95b29f2019-05-16 12:47:20 -07002175 pimpl.Export{}.MessageTypeOf(&structpb.Struct{}),
2176 pimpl.Export{}.MessageTypeOf(&structpb.Value{}),
2177 pimpl.Export{}.MessageTypeOf(&wrapperspb.BoolValue{}),
2178 pimpl.Export{}.EnumTypeOf(structpb.NullValue_NULL_VALUE),
2179 pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{}),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002180 ),
2181 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002182 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002183 inputText: `{
2184 "@type": "google.protobuf.Struct",
2185 "value": {
2186 "bool": true,
2187 "null": null,
2188 "string": "hello",
2189 "struct": {
2190 "string": "world"
2191 }
2192 }
2193}`,
2194 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002195 m := &structpb.Struct{
2196 Fields: map[string]*structpb.Value{
2197 "bool": {Kind: &structpb.Value_BoolValue{true}},
2198 "null": {Kind: &structpb.Value_NullValue{}},
2199 "string": {Kind: &structpb.Value_StringValue{"hello"}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002200 "struct": {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002201 Kind: &structpb.Value_StructValue{
2202 &structpb.Struct{
2203 Fields: map[string]*structpb.Value{
2204 "string": {Kind: &structpb.Value_StringValue{"world"}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002205 },
2206 },
2207 },
2208 },
2209 },
2210 }
2211 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2212 if err != nil {
2213 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2214 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002215 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002216 TypeUrl: "google.protobuf.Struct",
2217 Value: b,
2218 }
2219 }(),
2220 }, {
2221 desc: "Any with missing @type",
Damien Neil5c5b5312019-05-14 12:44:37 -07002222 umo: protojson.UnmarshalOptions{},
Joe Tsaia95b29f2019-05-16 12:47:20 -07002223 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002224 inputText: `{
2225 "value": {}
2226}`,
2227 wantErr: true,
2228 }, {
2229 desc: "Any with empty @type",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002230 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002231 inputText: `{
2232 "@type": ""
2233}`,
2234 wantErr: true,
2235 }, {
2236 desc: "Any with duplicate @type",
Damien Neil5c5b5312019-05-14 12:44:37 -07002237 umo: protojson.UnmarshalOptions{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002238 Resolver: preg.NewTypes(
Joe Tsai0fc49f82019-05-01 12:29:25 -07002239 pimpl.Export{}.MessageTypeOf(&pb2.Nested{}),
Joe Tsaia95b29f2019-05-16 12:47:20 -07002240 pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{}),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002241 ),
2242 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002243 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002244 inputText: `{
2245 "@type": "google.protobuf.StringValue",
2246 "value": "hello",
2247 "@type": "pb2.Nested"
2248}`,
2249 wantErr: true,
2250 }, {
2251 desc: "Any with duplicate value",
Damien Neil5c5b5312019-05-14 12:44:37 -07002252 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002253 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002254 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002255 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002256 inputText: `{
2257 "@type": "google.protobuf.StringValue",
2258 "value": "hello",
2259 "value": "world"
2260}`,
2261 wantErr: true,
2262 }, {
2263 desc: "Any with unknown field",
Damien Neil5c5b5312019-05-14 12:44:37 -07002264 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07002265 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002266 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002267 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002268 inputText: `{
2269 "@type": "pb2.Nested",
2270 "optString": "hello",
2271 "unknown": "world"
2272}`,
2273 wantErr: true,
2274 }, {
2275 desc: "Any with embedded type containing Any",
Damien Neil5c5b5312019-05-14 12:44:37 -07002276 umo: protojson.UnmarshalOptions{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002277 Resolver: preg.NewTypes(
Joe Tsai0fc49f82019-05-01 12:29:25 -07002278 pimpl.Export{}.MessageTypeOf(&pb2.KnownTypes{}),
Joe Tsaia95b29f2019-05-16 12:47:20 -07002279 pimpl.Export{}.MessageTypeOf(&anypb.Any{}),
2280 pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{}),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002281 ),
2282 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002283 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002284 inputText: `{
2285 "@type": "pb2.KnownTypes",
2286 "optAny": {
2287 "@type": "google.protobuf.StringValue",
2288 "value": "` + "abc\xff" + `"
2289 }
2290}`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002291 wantErr: true,
2292 }, {
2293 desc: "well known types as field values",
Damien Neil5c5b5312019-05-14 12:44:37 -07002294 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002295 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&emptypb.Empty{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002296 },
2297 inputMessage: &pb2.KnownTypes{},
2298 inputText: `{
2299 "optBool": false,
2300 "optInt32": 42,
2301 "optInt64": "42",
2302 "optUint32": 42,
2303 "optUint64": "42",
2304 "optFloat": 1.23,
2305 "optDouble": 3.1415,
2306 "optString": "hello",
2307 "optBytes": "aGVsbG8=",
2308 "optDuration": "123s",
2309 "optTimestamp": "2019-03-19T23:03:21Z",
2310 "optStruct": {
2311 "string": "hello"
2312 },
2313 "optList": [
2314 null,
2315 "",
2316 {},
2317 []
2318 ],
2319 "optValue": "world",
2320 "optEmpty": {},
2321 "optAny": {
2322 "@type": "google.protobuf.Empty",
2323 "value": {}
2324 },
2325 "optFieldmask": "fooBar,barFoo"
2326}`,
2327 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002328 OptBool: &wrapperspb.BoolValue{Value: false},
2329 OptInt32: &wrapperspb.Int32Value{Value: 42},
2330 OptInt64: &wrapperspb.Int64Value{Value: 42},
2331 OptUint32: &wrapperspb.UInt32Value{Value: 42},
2332 OptUint64: &wrapperspb.UInt64Value{Value: 42},
2333 OptFloat: &wrapperspb.FloatValue{Value: 1.23},
2334 OptDouble: &wrapperspb.DoubleValue{Value: 3.1415},
2335 OptString: &wrapperspb.StringValue{Value: "hello"},
2336 OptBytes: &wrapperspb.BytesValue{Value: []byte("hello")},
2337 OptDuration: &durationpb.Duration{Seconds: 123},
2338 OptTimestamp: &timestamppb.Timestamp{Seconds: 1553036601},
2339 OptStruct: &structpb.Struct{
2340 Fields: map[string]*structpb.Value{
2341 "string": {Kind: &structpb.Value_StringValue{"hello"}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002342 },
2343 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002344 OptList: &structpb.ListValue{
2345 Values: []*structpb.Value{
2346 {Kind: &structpb.Value_NullValue{}},
2347 {Kind: &structpb.Value_StringValue{}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002348 {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002349 Kind: &structpb.Value_StructValue{
2350 &structpb.Struct{Fields: map[string]*structpb.Value{}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002351 },
2352 },
2353 {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002354 Kind: &structpb.Value_ListValue{
2355 &structpb.ListValue{Values: []*structpb.Value{}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002356 },
2357 },
2358 },
2359 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002360 OptValue: &structpb.Value{
2361 Kind: &structpb.Value_StringValue{"world"},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002362 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002363 OptEmpty: &emptypb.Empty{},
2364 OptAny: &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002365 TypeUrl: "google.protobuf.Empty",
2366 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002367 OptFieldmask: &fieldmaskpb.FieldMask{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002368 Paths: []string{"foo_bar", "bar_foo"},
2369 },
2370 },
Herbie Ong4f0be712019-04-25 17:57:12 -07002371 }, {
2372 desc: "DiscardUnknown: regular messages",
Damien Neil5c5b5312019-05-14 12:44:37 -07002373 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002374 inputMessage: &pb3.Nests{},
2375 inputText: `{
2376 "sNested": {
2377 "unknown": {
2378 "foo": 1,
2379 "bar": [1, 2, 3]
2380 }
2381 },
2382 "unknown": "not known"
2383}`,
2384 wantMessage: &pb3.Nests{SNested: &pb3.Nested{}},
2385 }, {
2386 desc: "DiscardUnknown: repeated",
Damien Neil5c5b5312019-05-14 12:44:37 -07002387 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002388 inputMessage: &pb2.Nests{},
2389 inputText: `{
2390 "rptNested": [
2391 {"unknown": "blah"},
2392 {"optString": "hello"}
2393 ]
2394}`,
2395 wantMessage: &pb2.Nests{
2396 RptNested: []*pb2.Nested{
2397 {},
2398 {OptString: scalar.String("hello")},
2399 },
2400 },
2401 }, {
2402 desc: "DiscardUnknown: map",
Damien Neil5c5b5312019-05-14 12:44:37 -07002403 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002404 inputMessage: &pb3.Maps{},
2405 inputText: `{
2406 "strToNested": {
2407 "nested_one": {
2408 "unknown": "what you see is not"
2409 }
2410 }
2411}`,
2412 wantMessage: &pb3.Maps{
2413 StrToNested: map[string]*pb3.Nested{
2414 "nested_one": {},
2415 },
2416 },
2417 }, {
2418 desc: "DiscardUnknown: extension",
Damien Neil5c5b5312019-05-14 12:44:37 -07002419 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002420 inputMessage: &pb2.Extensions{},
2421 inputText: `{
2422 "[pb2.opt_ext_nested]": {
2423 "unknown": []
2424 }
2425}`,
2426 wantMessage: func() proto.Message {
2427 m := &pb2.Extensions{}
2428 setExtension(m, pb2.E_OptExtNested, &pb2.Nested{})
2429 return m
2430 }(),
2431 }, {
2432 desc: "DiscardUnknown: Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002433 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Joe Tsaia95b29f2019-05-16 12:47:20 -07002434 inputMessage: &emptypb.Empty{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002435 inputText: `{"unknown": "something"}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002436 wantMessage: &emptypb.Empty{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002437 }, {
2438 desc: "DiscardUnknown: Any without type",
Damien Neil5c5b5312019-05-14 12:44:37 -07002439 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Joe Tsaia95b29f2019-05-16 12:47:20 -07002440 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002441 inputText: `{
2442 "value": {"foo": "bar"},
2443 "unknown": true
2444}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002445 wantMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002446 }, {
2447 desc: "DiscardUnknown: Any",
Damien Neil5c5b5312019-05-14 12:44:37 -07002448 umo: protojson.UnmarshalOptions{
Herbie Ong4f0be712019-04-25 17:57:12 -07002449 DiscardUnknown: true,
Joe Tsai0fc49f82019-05-01 12:29:25 -07002450 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong4f0be712019-04-25 17:57:12 -07002451 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002452 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002453 inputText: `{
2454 "@type": "foo/pb2.Nested",
2455 "unknown": "none"
2456}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002457 wantMessage: &anypb.Any{
Herbie Ong4f0be712019-04-25 17:57:12 -07002458 TypeUrl: "foo/pb2.Nested",
2459 },
2460 }, {
2461 desc: "DiscardUnknown: Any with Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002462 umo: protojson.UnmarshalOptions{
Herbie Ong4f0be712019-04-25 17:57:12 -07002463 DiscardUnknown: true,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002464 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&emptypb.Empty{})),
Herbie Ong4f0be712019-04-25 17:57:12 -07002465 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002466 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002467 inputText: `{
2468 "@type": "type.googleapis.com/google.protobuf.Empty",
2469 "value": {"unknown": 47}
2470}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002471 wantMessage: &anypb.Any{
Herbie Ong4f0be712019-04-25 17:57:12 -07002472 TypeUrl: "type.googleapis.com/google.protobuf.Empty",
2473 },
Herbie Ongc96a79d2019-03-08 10:49:17 -08002474 }}
2475
2476 for _, tt := range tests {
2477 tt := tt
2478 t.Run(tt.desc, func(t *testing.T) {
Joe Tsaicdb77732019-05-14 16:05:06 -07002479 err := tt.umo.Unmarshal([]byte(tt.inputText), tt.inputMessage)
Herbie Ongc96a79d2019-03-08 10:49:17 -08002480 if err != nil && !tt.wantErr {
2481 t.Errorf("Unmarshal() returned error: %v\n\n", err)
2482 }
2483 if err == nil && tt.wantErr {
2484 t.Error("Unmarshal() got nil error, want error\n\n")
2485 }
2486 if tt.wantMessage != nil && !protoV1.Equal(tt.inputMessage.(protoV1.Message), tt.wantMessage.(protoV1.Message)) {
2487 t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", tt.inputMessage, tt.wantMessage)
2488 }
2489 })
2490 }
2491}