OLD | NEW |
1 #! /usr/bin/env python | 1 #! /usr/bin/env python |
2 # | 2 # |
3 # Protocol Buffers - Google's data interchange format | 3 # Protocol Buffers - Google's data interchange format |
4 # Copyright 2008 Google Inc. All rights reserved. | 4 # Copyright 2008 Google Inc. All rights reserved. |
5 # https://developers.google.com/protocol-buffers/ | 5 # https://developers.google.com/protocol-buffers/ |
6 # | 6 # |
7 # Redistribution and use in source and binary forms, with or without | 7 # Redistribution and use in source and binary forms, with or without |
8 # modification, are permitted provided that the following conditions are | 8 # modification, are permitted provided that the following conditions are |
9 # met: | 9 # met: |
10 # | 10 # |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 '"boolValue": false,' | 198 '"boolValue": false,' |
199 '"repeatedEnumValue": [],' | 199 '"repeatedEnumValue": [],' |
200 '"uint64Value": "0",' | 200 '"uint64Value": "0",' |
201 '"doubleValue": 0,' | 201 '"doubleValue": 0,' |
202 '"repeatedFloatValue": [],' | 202 '"repeatedFloatValue": [],' |
203 '"repeatedInt64Value": [],' | 203 '"repeatedInt64Value": [],' |
204 '"repeatedMessageValue": []}')) | 204 '"repeatedMessageValue": []}')) |
205 parsed_message = json_format_proto3_pb2.TestMessage() | 205 parsed_message = json_format_proto3_pb2.TestMessage() |
206 self.CheckParseBack(message, parsed_message) | 206 self.CheckParseBack(message, parsed_message) |
207 | 207 |
208 def testIntegersRepresentedAsFloat(self): | |
209 message = json_format_proto3_pb2.TestMessage() | |
210 json_format.Parse('{"int32Value": -2.147483648e9}', message) | |
211 self.assertEqual(message.int32_value, -2147483648) | |
212 json_format.Parse('{"int32Value": 1e5}', message) | |
213 self.assertEqual(message.int32_value, 100000) | |
214 json_format.Parse('{"int32Value": 1.0}', message) | |
215 self.assertEqual(message.int32_value, 1) | |
216 | |
217 def testMapFields(self): | 208 def testMapFields(self): |
218 message = json_format_proto3_pb2.TestMap() | 209 message = json_format_proto3_pb2.TestMap() |
219 message.bool_map[True] = 1 | 210 message.bool_map[True] = 1 |
220 message.bool_map[False] = 2 | 211 message.bool_map[False] = 2 |
221 message.int32_map[1] = 2 | 212 message.int32_map[1] = 2 |
222 message.int32_map[2] = 3 | 213 message.int32_map[2] = 3 |
223 message.int64_map[1] = 2 | 214 message.int64_map[1] = 2 |
224 message.int64_map[2] = 3 | 215 message.int64_map[2] = 3 |
225 message.uint32_map[1] = 2 | 216 message.uint32_map[1] = 2 |
226 message.uint32_map[2] = 3 | 217 message.uint32_map[2] = 3 |
(...skipping 22 matching lines...) Expand all Loading... |
249 '{}') | 240 '{}') |
250 message.oneof_int32_value = 0 | 241 message.oneof_int32_value = 0 |
251 self.assertEqual( | 242 self.assertEqual( |
252 json_format.MessageToJson(message, True), | 243 json_format.MessageToJson(message, True), |
253 '{\n' | 244 '{\n' |
254 ' "oneofInt32Value": 0\n' | 245 ' "oneofInt32Value": 0\n' |
255 '}') | 246 '}') |
256 parsed_message = json_format_proto3_pb2.TestOneof() | 247 parsed_message = json_format_proto3_pb2.TestOneof() |
257 self.CheckParseBack(message, parsed_message) | 248 self.CheckParseBack(message, parsed_message) |
258 | 249 |
259 def testSurrogates(self): | |
260 # Test correct surrogate handling. | |
261 message = json_format_proto3_pb2.TestMessage() | |
262 json_format.Parse('{"stringValue": "\\uD83D\\uDE01"}', message) | |
263 self.assertEqual(message.string_value, | |
264 b'\xF0\x9F\x98\x81'.decode('utf-8', 'strict')) | |
265 | |
266 # Error case: unpaired high surrogate. | |
267 self.CheckError( | |
268 '{"stringValue": "\\uD83D"}', | |
269 r'Invalid \\uXXXX escape|Unpaired.*surrogate') | |
270 | |
271 # Unpaired low surrogate. | |
272 self.CheckError( | |
273 '{"stringValue": "\\uDE01"}', | |
274 r'Invalid \\uXXXX escape|Unpaired.*surrogate') | |
275 | |
276 def testTimestampMessage(self): | 250 def testTimestampMessage(self): |
277 message = json_format_proto3_pb2.TestTimestamp() | 251 message = json_format_proto3_pb2.TestTimestamp() |
278 message.value.seconds = 0 | 252 message.value.seconds = 0 |
279 message.value.nanos = 0 | 253 message.value.nanos = 0 |
280 message.repeated_value.add().seconds = 20 | 254 message.repeated_value.add().seconds = 20 |
281 message.repeated_value[0].nanos = 1 | 255 message.repeated_value[0].nanos = 1 |
282 message.repeated_value.add().seconds = 0 | 256 message.repeated_value.add().seconds = 0 |
283 message.repeated_value[1].nanos = 10000 | 257 message.repeated_value[1].nanos = 10000 |
284 message.repeated_value.add().seconds = 100000000 | 258 message.repeated_value.add().seconds = 100000000 |
285 message.repeated_value[2].nanos = 0 | 259 message.repeated_value[2].nanos = 0 |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 self.CheckParseBack(message, parsed_message) | 404 self.CheckParseBack(message, parsed_message) |
431 # Can't parse back if the Value message is not set. | 405 # Can't parse back if the Value message is not set. |
432 message.repeated_value.add() | 406 message.repeated_value.add() |
433 self.assertEqual( | 407 self.assertEqual( |
434 json.loads(json_format.MessageToJson(message, False)), | 408 json.loads(json_format.MessageToJson(message, False)), |
435 json.loads( | 409 json.loads( |
436 '{' | 410 '{' |
437 ' "value": "hello",' | 411 ' "value": "hello",' |
438 ' "repeatedValue": [11.1, false, null, null]' | 412 ' "repeatedValue": [11.1, false, null, null]' |
439 '}')) | 413 '}')) |
440 message.Clear() | |
441 json_format.Parse('{"value": null}', message) | |
442 self.assertEqual(message.value.WhichOneof('kind'), 'null_value') | |
443 | 414 |
444 def testListValueMessage(self): | 415 def testListValueMessage(self): |
445 message = json_format_proto3_pb2.TestListValue() | 416 message = json_format_proto3_pb2.TestListValue() |
446 message.value.values.add().number_value = 11.1 | 417 message.value.values.add().number_value = 11.1 |
447 message.value.values.add().null_value = 0 | 418 message.value.values.add().null_value = 0 |
448 message.value.values.add().bool_value = True | 419 message.value.values.add().bool_value = True |
449 message.value.values.add().string_value = 'hello' | 420 message.value.values.add().string_value = 'hello' |
450 message.value.values.add().struct_value['name'] = 'Jim' | 421 message.value.values.add().struct_value['name'] = 'Jim' |
451 message.repeated_value.add().values.add().number_value = 1 | 422 message.repeated_value.add().values.add().number_value = 1 |
452 message.repeated_value.add() | 423 message.repeated_value.add() |
(...skipping 27 matching lines...) Expand all Loading... |
480 ' "value": 5678\n' | 451 ' "value": 5678\n' |
481 ' },\n' | 452 ' },\n' |
482 ' {}],\n' | 453 ' {}],\n' |
483 ' "value": {\n' | 454 ' "value": {\n' |
484 ' "@type": "type.googleapis.com/proto3.MessageType",\n' | 455 ' "@type": "type.googleapis.com/proto3.MessageType",\n' |
485 ' "value": 1234\n' | 456 ' "value": 1234\n' |
486 ' }\n' | 457 ' }\n' |
487 '}\n')) | 458 '}\n')) |
488 parsed_message = json_format_proto3_pb2.TestAny() | 459 parsed_message = json_format_proto3_pb2.TestAny() |
489 self.CheckParseBack(message, parsed_message) | 460 self.CheckParseBack(message, parsed_message) |
490 # Must print @type first | |
491 test_message = json_format_proto3_pb2.TestMessage( | |
492 bool_value=True, | |
493 int32_value=20, | |
494 int64_value=-20, | |
495 uint32_value=20, | |
496 uint64_value=20, | |
497 double_value=3.14, | |
498 string_value='foo') | |
499 message.Clear() | |
500 message.value.Pack(test_message) | |
501 self.assertEqual( | |
502 json_format.MessageToJson(message, False)[0:68], | |
503 '{\n' | |
504 ' "value": {\n' | |
505 ' "@type": "type.googleapis.com/proto3.TestMessage"') | |
506 | 461 |
507 def testWellKnownInAnyMessage(self): | 462 def testWellKnownInAnyMessage(self): |
508 message = any_pb2.Any() | 463 message = any_pb2.Any() |
509 int32_value = wrappers_pb2.Int32Value() | 464 int32_value = wrappers_pb2.Int32Value() |
510 int32_value.value = 1234 | 465 int32_value.value = 1234 |
511 message.Pack(int32_value) | 466 message.Pack(int32_value) |
512 self.assertEqual( | 467 self.assertEqual( |
513 json.loads(json_format.MessageToJson(message, True)), | 468 json.loads(json_format.MessageToJson(message, True)), |
514 json.loads( | 469 json.loads( |
515 '{\n' | 470 '{\n' |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
605 '"repeatedFloatValue": null,' | 560 '"repeatedFloatValue": null,' |
606 '"repeatedDoubleValue": null,' | 561 '"repeatedDoubleValue": null,' |
607 '"repeatedBoolValue": null,' | 562 '"repeatedBoolValue": null,' |
608 '"repeatedStringValue": null,' | 563 '"repeatedStringValue": null,' |
609 '"repeatedBytesValue": null,' | 564 '"repeatedBytesValue": null,' |
610 '"repeatedMessageValue": null,' | 565 '"repeatedMessageValue": null,' |
611 '"repeatedEnumValue": null' | 566 '"repeatedEnumValue": null' |
612 '}', | 567 '}', |
613 parsed_message) | 568 parsed_message) |
614 self.assertEqual(message, parsed_message) | 569 self.assertEqual(message, parsed_message) |
615 # Null and {} should have different behavior for sub message. | |
616 self.assertFalse(parsed_message.HasField('message_value')) | |
617 json_format.Parse('{"messageValue": {}}', parsed_message) | |
618 self.assertTrue(parsed_message.HasField('message_value')) | |
619 # Null is not allowed to be used as an element in repeated field. | |
620 self.assertRaisesRegexp( | 570 self.assertRaisesRegexp( |
621 json_format.ParseError, | 571 json_format.ParseError, |
622 'Failed to parse repeatedInt32Value field: ' | 572 'Failed to parse repeatedInt32Value field: ' |
623 'null is not allowed to be used as an element in a repeated field.', | 573 'null is not allowed to be used as an element in a repeated field.', |
624 json_format.Parse, | 574 json_format.Parse, |
625 '{"repeatedInt32Value":[1, null]}', | 575 '{"repeatedInt32Value":[1, null]}', |
626 parsed_message) | 576 parsed_message) |
627 | 577 |
628 def testNanFloat(self): | 578 def testNanFloat(self): |
629 message = json_format_proto3_pb2.TestMessage() | 579 message = json_format_proto3_pb2.TestMessage() |
630 message.float_value = float('nan') | 580 message.float_value = float('nan') |
631 text = '{\n "floatValue": "NaN"\n}' | 581 text = '{\n "floatValue": "NaN"\n}' |
632 self.assertEqual(json_format.MessageToJson(message), text) | 582 self.assertEqual(json_format.MessageToJson(message), text) |
633 parsed_message = json_format_proto3_pb2.TestMessage() | 583 parsed_message = json_format_proto3_pb2.TestMessage() |
634 json_format.Parse(text, parsed_message) | 584 json_format.Parse(text, parsed_message) |
635 self.assertTrue(math.isnan(parsed_message.float_value)) | 585 self.assertTrue(math.isnan(parsed_message.float_value)) |
636 | 586 |
637 def testParseEmptyText(self): | 587 def testParseEmptyText(self): |
638 self.CheckError('', | 588 self.CheckError('', |
639 r'Failed to load JSON: (Expecting value)|(No JSON).') | 589 r'Failed to load JSON: (Expecting value)|(No JSON).') |
640 | 590 |
641 def testParseEnumValue(self): | 591 def testParseBadEnumValue(self): |
642 message = json_format_proto3_pb2.TestMessage() | 592 self.CheckError( |
643 text = '{"enumValue": 0}' | 593 '{"enumValue": 1}', |
644 json_format.Parse(text, message) | 594 'Enum value must be a string literal with double quotes. ' |
645 text = '{"enumValue": 1}' | 595 'Type "proto3.EnumType" has no value named 1.') |
646 json_format.Parse(text, message) | |
647 self.CheckError( | 596 self.CheckError( |
648 '{"enumValue": "baz"}', | 597 '{"enumValue": "baz"}', |
649 'Failed to parse enumValue field: Invalid enum value baz ' | 598 'Enum value must be a string literal with double quotes. ' |
650 'for enum type proto3.EnumType.') | 599 'Type "proto3.EnumType" has no value named baz.') |
651 | 600 |
652 def testParseBadIdentifer(self): | 601 def testParseBadIdentifer(self): |
653 self.CheckError('{int32Value: 1}', | 602 self.CheckError('{int32Value: 1}', |
654 (r'Failed to load JSON: Expecting property name' | 603 (r'Failed to load JSON: Expecting property name' |
655 r'( enclosed in double quotes)?: line 1')) | 604 r'( enclosed in double quotes)?: line 1')) |
656 self.CheckError('{"unknownName": 1}', | 605 self.CheckError('{"unknownName": 1}', |
657 'Message type "proto3.TestMessage" has no field named ' | 606 'Message type "proto3.TestMessage" has no field named ' |
658 '"unknownName".') | 607 '"unknownName".') |
659 | 608 |
660 def testIgnoreUnknownField(self): | |
661 text = '{"unknownName": 1}' | |
662 parsed_message = json_format_proto3_pb2.TestMessage() | |
663 json_format.Parse(text, parsed_message, ignore_unknown_fields=True) | |
664 text = ('{\n' | |
665 ' "repeatedValue": [ {\n' | |
666 ' "@type": "type.googleapis.com/proto3.MessageType",\n' | |
667 ' "unknownName": 1\n' | |
668 ' }]\n' | |
669 '}\n') | |
670 parsed_message = json_format_proto3_pb2.TestAny() | |
671 json_format.Parse(text, parsed_message, ignore_unknown_fields=True) | |
672 | |
673 def testDuplicateField(self): | 609 def testDuplicateField(self): |
674 # Duplicate key check is not supported for python2.6 | 610 # Duplicate key check is not supported for python2.6 |
675 if sys.version_info < (2, 7): | 611 if sys.version_info < (2, 7): |
676 return | 612 return |
677 self.CheckError('{"int32Value": 1,\n"int32Value":2}', | 613 self.CheckError('{"int32Value": 1,\n"int32Value":2}', |
678 'Failed to load JSON: duplicate key int32Value.') | 614 'Failed to load JSON: duplicate key int32Value.') |
679 | 615 |
680 def testInvalidBoolValue(self): | 616 def testInvalidBoolValue(self): |
681 self.CheckError('{"boolValue": 1}', | 617 self.CheckError('{"boolValue": 1}', |
682 'Failed to parse boolValue field: ' | 618 'Failed to parse boolValue field: ' |
683 'Expected true or false without quotes.') | 619 'Expected true or false without quotes.') |
684 self.CheckError('{"boolValue": "true"}', | 620 self.CheckError('{"boolValue": "true"}', |
685 'Failed to parse boolValue field: ' | 621 'Failed to parse boolValue field: ' |
686 'Expected true or false without quotes.') | 622 'Expected true or false without quotes.') |
687 | 623 |
688 def testInvalidIntegerValue(self): | 624 def testInvalidIntegerValue(self): |
689 message = json_format_proto3_pb2.TestMessage() | 625 message = json_format_proto3_pb2.TestMessage() |
690 text = '{"int32Value": 0x12345}' | 626 text = '{"int32Value": 0x12345}' |
691 self.assertRaises(json_format.ParseError, | 627 self.assertRaises(json_format.ParseError, |
692 json_format.Parse, text, message) | 628 json_format.Parse, text, message) |
693 self.CheckError('{"int32Value": 1.5}', | |
694 'Failed to parse int32Value field: ' | |
695 'Couldn\'t parse integer: 1.5.') | |
696 self.CheckError('{"int32Value": 012345}', | 629 self.CheckError('{"int32Value": 012345}', |
697 (r'Failed to load JSON: Expecting \'?,\'? delimiter: ' | 630 (r'Failed to load JSON: Expecting \'?,\'? delimiter: ' |
698 r'line 1.')) | 631 r'line 1.')) |
| 632 self.CheckError('{"int32Value": 1.0}', |
| 633 'Failed to parse int32Value field: ' |
| 634 'Couldn\'t parse integer: 1.0.') |
699 self.CheckError('{"int32Value": " 1 "}', | 635 self.CheckError('{"int32Value": " 1 "}', |
700 'Failed to parse int32Value field: ' | 636 'Failed to parse int32Value field: ' |
701 'Couldn\'t parse integer: " 1 ".') | 637 'Couldn\'t parse integer: " 1 ".') |
702 self.CheckError('{"int32Value": "1 "}', | 638 self.CheckError('{"int32Value": "1 "}', |
703 'Failed to parse int32Value field: ' | 639 'Failed to parse int32Value field: ' |
704 'Couldn\'t parse integer: "1 ".') | 640 'Couldn\'t parse integer: "1 ".') |
705 self.CheckError('{"int32Value": 12345678901234567890}', | 641 self.CheckError('{"int32Value": 12345678901234567890}', |
706 'Failed to parse int32Value field: Value out of range: ' | 642 'Failed to parse int32Value field: Value out of range: ' |
707 '12345678901234567890.') | 643 '12345678901234567890.') |
| 644 self.CheckError('{"int32Value": 1e5}', |
| 645 'Failed to parse int32Value field: ' |
| 646 'Couldn\'t parse integer: 100000.0.') |
708 self.CheckError('{"uint32Value": -1}', | 647 self.CheckError('{"uint32Value": -1}', |
709 'Failed to parse uint32Value field: ' | 648 'Failed to parse uint32Value field: ' |
710 'Value out of range: -1.') | 649 'Value out of range: -1.') |
711 | 650 |
712 def testInvalidFloatValue(self): | 651 def testInvalidFloatValue(self): |
713 self.CheckError('{"floatValue": "nan"}', | 652 self.CheckError('{"floatValue": "nan"}', |
714 'Failed to parse floatValue field: Couldn\'t ' | 653 'Failed to parse floatValue field: Couldn\'t ' |
715 'parse float "nan", use "NaN" instead.') | 654 'parse float "nan", use "NaN" instead.') |
716 | 655 |
717 def testInvalidBytesValue(self): | 656 def testInvalidBytesValue(self): |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
818 self.assertRaisesRegexp( | 757 self.assertRaisesRegexp( |
819 TypeError, | 758 TypeError, |
820 'Can not find message descriptor by type_url: ' | 759 'Can not find message descriptor by type_url: ' |
821 'type.googleapis.com/MessageNotExist.', | 760 'type.googleapis.com/MessageNotExist.', |
822 json_format.Parse, text, message) | 761 json_format.Parse, text, message) |
823 # Only last part is to be used: b/25630112 | 762 # Only last part is to be used: b/25630112 |
824 text = (r'{"@type": "incorrect.googleapis.com/google.protobuf.Int32Value",' | 763 text = (r'{"@type": "incorrect.googleapis.com/google.protobuf.Int32Value",' |
825 r'"value": 1234}') | 764 r'"value": 1234}') |
826 json_format.Parse(text, message) | 765 json_format.Parse(text, message) |
827 | 766 |
828 def testPreservingProtoFieldNames(self): | |
829 message = json_format_proto3_pb2.TestMessage() | |
830 message.int32_value = 12345 | |
831 self.assertEqual('{\n "int32Value": 12345\n}', | |
832 json_format.MessageToJson(message)) | |
833 self.assertEqual('{\n "int32_value": 12345\n}', | |
834 json_format.MessageToJson(message, False, True)) | |
835 | |
836 # Parsers accept both original proto field names and lowerCamelCase names. | |
837 message = json_format_proto3_pb2.TestMessage() | |
838 json_format.Parse('{"int32Value": 54321}', message) | |
839 self.assertEqual(54321, message.int32_value) | |
840 json_format.Parse('{"int32_value": 12345}', message) | |
841 self.assertEqual(12345, message.int32_value) | |
842 | |
843 def testParseDict(self): | |
844 expected = 12345 | |
845 js_dict = {'int32Value': expected} | |
846 message = json_format_proto3_pb2.TestMessage() | |
847 json_format.ParseDict(js_dict, message) | |
848 self.assertEqual(expected, message.int32_value) | |
849 | |
850 def testMessageToDict(self): | |
851 message = json_format_proto3_pb2.TestMessage() | |
852 message.int32_value = 12345 | |
853 expected = {'int32Value': 12345} | |
854 self.assertEqual(expected, | |
855 json_format.MessageToDict(message)) | |
856 | |
857 def testJsonName(self): | |
858 message = json_format_proto3_pb2.TestCustomJsonName() | |
859 message.value = 12345 | |
860 self.assertEqual('{\n "@value": 12345\n}', | |
861 json_format.MessageToJson(message)) | |
862 parsed_message = json_format_proto3_pb2.TestCustomJsonName() | |
863 self.CheckParseBack(message, parsed_message) | |
864 | |
865 | 767 |
866 if __name__ == '__main__': | 768 if __name__ == '__main__': |
867 unittest.main() | 769 unittest.main() |
OLD | NEW |