| 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 |
| 208 def testMapFields(self): | 217 def testMapFields(self): |
| 209 message = json_format_proto3_pb2.TestMap() | 218 message = json_format_proto3_pb2.TestMap() |
| 210 message.bool_map[True] = 1 | 219 message.bool_map[True] = 1 |
| 211 message.bool_map[False] = 2 | 220 message.bool_map[False] = 2 |
| 212 message.int32_map[1] = 2 | 221 message.int32_map[1] = 2 |
| 213 message.int32_map[2] = 3 | 222 message.int32_map[2] = 3 |
| 214 message.int64_map[1] = 2 | 223 message.int64_map[1] = 2 |
| 215 message.int64_map[2] = 3 | 224 message.int64_map[2] = 3 |
| 216 message.uint32_map[1] = 2 | 225 message.uint32_map[1] = 2 |
| 217 message.uint32_map[2] = 3 | 226 message.uint32_map[2] = 3 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 240 '{}') | 249 '{}') |
| 241 message.oneof_int32_value = 0 | 250 message.oneof_int32_value = 0 |
| 242 self.assertEqual( | 251 self.assertEqual( |
| 243 json_format.MessageToJson(message, True), | 252 json_format.MessageToJson(message, True), |
| 244 '{\n' | 253 '{\n' |
| 245 ' "oneofInt32Value": 0\n' | 254 ' "oneofInt32Value": 0\n' |
| 246 '}') | 255 '}') |
| 247 parsed_message = json_format_proto3_pb2.TestOneof() | 256 parsed_message = json_format_proto3_pb2.TestOneof() |
| 248 self.CheckParseBack(message, parsed_message) | 257 self.CheckParseBack(message, parsed_message) |
| 249 | 258 |
| 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 |
| 250 def testTimestampMessage(self): | 276 def testTimestampMessage(self): |
| 251 message = json_format_proto3_pb2.TestTimestamp() | 277 message = json_format_proto3_pb2.TestTimestamp() |
| 252 message.value.seconds = 0 | 278 message.value.seconds = 0 |
| 253 message.value.nanos = 0 | 279 message.value.nanos = 0 |
| 254 message.repeated_value.add().seconds = 20 | 280 message.repeated_value.add().seconds = 20 |
| 255 message.repeated_value[0].nanos = 1 | 281 message.repeated_value[0].nanos = 1 |
| 256 message.repeated_value.add().seconds = 0 | 282 message.repeated_value.add().seconds = 0 |
| 257 message.repeated_value[1].nanos = 10000 | 283 message.repeated_value[1].nanos = 10000 |
| 258 message.repeated_value.add().seconds = 100000000 | 284 message.repeated_value.add().seconds = 100000000 |
| 259 message.repeated_value[2].nanos = 0 | 285 message.repeated_value[2].nanos = 0 |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 self.CheckParseBack(message, parsed_message) | 430 self.CheckParseBack(message, parsed_message) |
| 405 # Can't parse back if the Value message is not set. | 431 # Can't parse back if the Value message is not set. |
| 406 message.repeated_value.add() | 432 message.repeated_value.add() |
| 407 self.assertEqual( | 433 self.assertEqual( |
| 408 json.loads(json_format.MessageToJson(message, False)), | 434 json.loads(json_format.MessageToJson(message, False)), |
| 409 json.loads( | 435 json.loads( |
| 410 '{' | 436 '{' |
| 411 ' "value": "hello",' | 437 ' "value": "hello",' |
| 412 ' "repeatedValue": [11.1, false, null, null]' | 438 ' "repeatedValue": [11.1, false, null, null]' |
| 413 '}')) | 439 '}')) |
| 440 message.Clear() |
| 441 json_format.Parse('{"value": null}', message) |
| 442 self.assertEqual(message.value.WhichOneof('kind'), 'null_value') |
| 414 | 443 |
| 415 def testListValueMessage(self): | 444 def testListValueMessage(self): |
| 416 message = json_format_proto3_pb2.TestListValue() | 445 message = json_format_proto3_pb2.TestListValue() |
| 417 message.value.values.add().number_value = 11.1 | 446 message.value.values.add().number_value = 11.1 |
| 418 message.value.values.add().null_value = 0 | 447 message.value.values.add().null_value = 0 |
| 419 message.value.values.add().bool_value = True | 448 message.value.values.add().bool_value = True |
| 420 message.value.values.add().string_value = 'hello' | 449 message.value.values.add().string_value = 'hello' |
| 421 message.value.values.add().struct_value['name'] = 'Jim' | 450 message.value.values.add().struct_value['name'] = 'Jim' |
| 422 message.repeated_value.add().values.add().number_value = 1 | 451 message.repeated_value.add().values.add().number_value = 1 |
| 423 message.repeated_value.add() | 452 message.repeated_value.add() |
| (...skipping 27 matching lines...) Expand all Loading... |
| 451 ' "value": 5678\n' | 480 ' "value": 5678\n' |
| 452 ' },\n' | 481 ' },\n' |
| 453 ' {}],\n' | 482 ' {}],\n' |
| 454 ' "value": {\n' | 483 ' "value": {\n' |
| 455 ' "@type": "type.googleapis.com/proto3.MessageType",\n' | 484 ' "@type": "type.googleapis.com/proto3.MessageType",\n' |
| 456 ' "value": 1234\n' | 485 ' "value": 1234\n' |
| 457 ' }\n' | 486 ' }\n' |
| 458 '}\n')) | 487 '}\n')) |
| 459 parsed_message = json_format_proto3_pb2.TestAny() | 488 parsed_message = json_format_proto3_pb2.TestAny() |
| 460 self.CheckParseBack(message, parsed_message) | 489 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"') |
| 461 | 506 |
| 462 def testWellKnownInAnyMessage(self): | 507 def testWellKnownInAnyMessage(self): |
| 463 message = any_pb2.Any() | 508 message = any_pb2.Any() |
| 464 int32_value = wrappers_pb2.Int32Value() | 509 int32_value = wrappers_pb2.Int32Value() |
| 465 int32_value.value = 1234 | 510 int32_value.value = 1234 |
| 466 message.Pack(int32_value) | 511 message.Pack(int32_value) |
| 467 self.assertEqual( | 512 self.assertEqual( |
| 468 json.loads(json_format.MessageToJson(message, True)), | 513 json.loads(json_format.MessageToJson(message, True)), |
| 469 json.loads( | 514 json.loads( |
| 470 '{\n' | 515 '{\n' |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 560 '"repeatedFloatValue": null,' | 605 '"repeatedFloatValue": null,' |
| 561 '"repeatedDoubleValue": null,' | 606 '"repeatedDoubleValue": null,' |
| 562 '"repeatedBoolValue": null,' | 607 '"repeatedBoolValue": null,' |
| 563 '"repeatedStringValue": null,' | 608 '"repeatedStringValue": null,' |
| 564 '"repeatedBytesValue": null,' | 609 '"repeatedBytesValue": null,' |
| 565 '"repeatedMessageValue": null,' | 610 '"repeatedMessageValue": null,' |
| 566 '"repeatedEnumValue": null' | 611 '"repeatedEnumValue": null' |
| 567 '}', | 612 '}', |
| 568 parsed_message) | 613 parsed_message) |
| 569 self.assertEqual(message, parsed_message) | 614 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. |
| 570 self.assertRaisesRegexp( | 620 self.assertRaisesRegexp( |
| 571 json_format.ParseError, | 621 json_format.ParseError, |
| 572 'Failed to parse repeatedInt32Value field: ' | 622 'Failed to parse repeatedInt32Value field: ' |
| 573 'null is not allowed to be used as an element in a repeated field.', | 623 'null is not allowed to be used as an element in a repeated field.', |
| 574 json_format.Parse, | 624 json_format.Parse, |
| 575 '{"repeatedInt32Value":[1, null]}', | 625 '{"repeatedInt32Value":[1, null]}', |
| 576 parsed_message) | 626 parsed_message) |
| 577 | 627 |
| 578 def testNanFloat(self): | 628 def testNanFloat(self): |
| 579 message = json_format_proto3_pb2.TestMessage() | 629 message = json_format_proto3_pb2.TestMessage() |
| 580 message.float_value = float('nan') | 630 message.float_value = float('nan') |
| 581 text = '{\n "floatValue": "NaN"\n}' | 631 text = '{\n "floatValue": "NaN"\n}' |
| 582 self.assertEqual(json_format.MessageToJson(message), text) | 632 self.assertEqual(json_format.MessageToJson(message), text) |
| 583 parsed_message = json_format_proto3_pb2.TestMessage() | 633 parsed_message = json_format_proto3_pb2.TestMessage() |
| 584 json_format.Parse(text, parsed_message) | 634 json_format.Parse(text, parsed_message) |
| 585 self.assertTrue(math.isnan(parsed_message.float_value)) | 635 self.assertTrue(math.isnan(parsed_message.float_value)) |
| 586 | 636 |
| 587 def testParseEmptyText(self): | 637 def testParseEmptyText(self): |
| 588 self.CheckError('', | 638 self.CheckError('', |
| 589 r'Failed to load JSON: (Expecting value)|(No JSON).') | 639 r'Failed to load JSON: (Expecting value)|(No JSON).') |
| 590 | 640 |
| 591 def testParseBadEnumValue(self): | 641 def testParseEnumValue(self): |
| 592 self.CheckError( | 642 message = json_format_proto3_pb2.TestMessage() |
| 593 '{"enumValue": 1}', | 643 text = '{"enumValue": 0}' |
| 594 'Enum value must be a string literal with double quotes. ' | 644 json_format.Parse(text, message) |
| 595 'Type "proto3.EnumType" has no value named 1.') | 645 text = '{"enumValue": 1}' |
| 646 json_format.Parse(text, message) |
| 596 self.CheckError( | 647 self.CheckError( |
| 597 '{"enumValue": "baz"}', | 648 '{"enumValue": "baz"}', |
| 598 'Enum value must be a string literal with double quotes. ' | 649 'Failed to parse enumValue field: Invalid enum value baz ' |
| 599 'Type "proto3.EnumType" has no value named baz.') | 650 'for enum type proto3.EnumType.') |
| 600 | 651 |
| 601 def testParseBadIdentifer(self): | 652 def testParseBadIdentifer(self): |
| 602 self.CheckError('{int32Value: 1}', | 653 self.CheckError('{int32Value: 1}', |
| 603 (r'Failed to load JSON: Expecting property name' | 654 (r'Failed to load JSON: Expecting property name' |
| 604 r'( enclosed in double quotes)?: line 1')) | 655 r'( enclosed in double quotes)?: line 1')) |
| 605 self.CheckError('{"unknownName": 1}', | 656 self.CheckError('{"unknownName": 1}', |
| 606 'Message type "proto3.TestMessage" has no field named ' | 657 'Message type "proto3.TestMessage" has no field named ' |
| 607 '"unknownName".') | 658 '"unknownName".') |
| 608 | 659 |
| 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 |
| 609 def testDuplicateField(self): | 673 def testDuplicateField(self): |
| 610 # Duplicate key check is not supported for python2.6 | 674 # Duplicate key check is not supported for python2.6 |
| 611 if sys.version_info < (2, 7): | 675 if sys.version_info < (2, 7): |
| 612 return | 676 return |
| 613 self.CheckError('{"int32Value": 1,\n"int32Value":2}', | 677 self.CheckError('{"int32Value": 1,\n"int32Value":2}', |
| 614 'Failed to load JSON: duplicate key int32Value.') | 678 'Failed to load JSON: duplicate key int32Value.') |
| 615 | 679 |
| 616 def testInvalidBoolValue(self): | 680 def testInvalidBoolValue(self): |
| 617 self.CheckError('{"boolValue": 1}', | 681 self.CheckError('{"boolValue": 1}', |
| 618 'Failed to parse boolValue field: ' | 682 'Failed to parse boolValue field: ' |
| 619 'Expected true or false without quotes.') | 683 'Expected true or false without quotes.') |
| 620 self.CheckError('{"boolValue": "true"}', | 684 self.CheckError('{"boolValue": "true"}', |
| 621 'Failed to parse boolValue field: ' | 685 'Failed to parse boolValue field: ' |
| 622 'Expected true or false without quotes.') | 686 'Expected true or false without quotes.') |
| 623 | 687 |
| 624 def testInvalidIntegerValue(self): | 688 def testInvalidIntegerValue(self): |
| 625 message = json_format_proto3_pb2.TestMessage() | 689 message = json_format_proto3_pb2.TestMessage() |
| 626 text = '{"int32Value": 0x12345}' | 690 text = '{"int32Value": 0x12345}' |
| 627 self.assertRaises(json_format.ParseError, | 691 self.assertRaises(json_format.ParseError, |
| 628 json_format.Parse, text, message) | 692 json_format.Parse, text, message) |
| 693 self.CheckError('{"int32Value": 1.5}', |
| 694 'Failed to parse int32Value field: ' |
| 695 'Couldn\'t parse integer: 1.5.') |
| 629 self.CheckError('{"int32Value": 012345}', | 696 self.CheckError('{"int32Value": 012345}', |
| 630 (r'Failed to load JSON: Expecting \'?,\'? delimiter: ' | 697 (r'Failed to load JSON: Expecting \'?,\'? delimiter: ' |
| 631 r'line 1.')) | 698 r'line 1.')) |
| 632 self.CheckError('{"int32Value": 1.0}', | |
| 633 'Failed to parse int32Value field: ' | |
| 634 'Couldn\'t parse integer: 1.0.') | |
| 635 self.CheckError('{"int32Value": " 1 "}', | 699 self.CheckError('{"int32Value": " 1 "}', |
| 636 'Failed to parse int32Value field: ' | 700 'Failed to parse int32Value field: ' |
| 637 'Couldn\'t parse integer: " 1 ".') | 701 'Couldn\'t parse integer: " 1 ".') |
| 638 self.CheckError('{"int32Value": "1 "}', | 702 self.CheckError('{"int32Value": "1 "}', |
| 639 'Failed to parse int32Value field: ' | 703 'Failed to parse int32Value field: ' |
| 640 'Couldn\'t parse integer: "1 ".') | 704 'Couldn\'t parse integer: "1 ".') |
| 641 self.CheckError('{"int32Value": 12345678901234567890}', | 705 self.CheckError('{"int32Value": 12345678901234567890}', |
| 642 'Failed to parse int32Value field: Value out of range: ' | 706 'Failed to parse int32Value field: Value out of range: ' |
| 643 '12345678901234567890.') | 707 '12345678901234567890.') |
| 644 self.CheckError('{"int32Value": 1e5}', | |
| 645 'Failed to parse int32Value field: ' | |
| 646 'Couldn\'t parse integer: 100000.0.') | |
| 647 self.CheckError('{"uint32Value": -1}', | 708 self.CheckError('{"uint32Value": -1}', |
| 648 'Failed to parse uint32Value field: ' | 709 'Failed to parse uint32Value field: ' |
| 649 'Value out of range: -1.') | 710 'Value out of range: -1.') |
| 650 | 711 |
| 651 def testInvalidFloatValue(self): | 712 def testInvalidFloatValue(self): |
| 652 self.CheckError('{"floatValue": "nan"}', | 713 self.CheckError('{"floatValue": "nan"}', |
| 653 'Failed to parse floatValue field: Couldn\'t ' | 714 'Failed to parse floatValue field: Couldn\'t ' |
| 654 'parse float "nan", use "NaN" instead.') | 715 'parse float "nan", use "NaN" instead.') |
| 655 | 716 |
| 656 def testInvalidBytesValue(self): | 717 def testInvalidBytesValue(self): |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 757 self.assertRaisesRegexp( | 818 self.assertRaisesRegexp( |
| 758 TypeError, | 819 TypeError, |
| 759 'Can not find message descriptor by type_url: ' | 820 'Can not find message descriptor by type_url: ' |
| 760 'type.googleapis.com/MessageNotExist.', | 821 'type.googleapis.com/MessageNotExist.', |
| 761 json_format.Parse, text, message) | 822 json_format.Parse, text, message) |
| 762 # Only last part is to be used: b/25630112 | 823 # Only last part is to be used: b/25630112 |
| 763 text = (r'{"@type": "incorrect.googleapis.com/google.protobuf.Int32Value",' | 824 text = (r'{"@type": "incorrect.googleapis.com/google.protobuf.Int32Value",' |
| 764 r'"value": 1234}') | 825 r'"value": 1234}') |
| 765 json_format.Parse(text, message) | 826 json_format.Parse(text, message) |
| 766 | 827 |
| 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 |
| 767 | 865 |
| 768 if __name__ == '__main__': | 866 if __name__ == '__main__': |
| 769 unittest.main() | 867 unittest.main() |
| OLD | NEW |