~ubuntu-branches/debian/stretch/protobuf/stretch

« back to all changes in this revision

Viewing changes to python/google/protobuf/internal/reflection_test.py

  • Committer: Package Import Robot
  • Author(s): Robert S. Edmonds
  • Date: 2014-09-11 22:50:10 UTC
  • mfrom: (10.1.9 experimental)
  • Revision ID: package-import@ubuntu.com-20140911225010-wt4yo9dpc1fzuq5g
Tags: 2.6.0-3
Upload to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
37
37
 
38
38
__author__ = 'robinson@google.com (Will Robinson)'
39
39
 
 
40
import copy
40
41
import gc
41
42
import operator
42
43
import struct
43
44
 
44
 
import unittest
 
45
from google.apputils import basetest
45
46
from google.protobuf import unittest_import_pb2
46
47
from google.protobuf import unittest_mset_pb2
47
48
from google.protobuf import unittest_pb2
49
50
from google.protobuf import descriptor
50
51
from google.protobuf import message
51
52
from google.protobuf import reflection
 
53
from google.protobuf import text_format
52
54
from google.protobuf.internal import api_implementation
53
55
from google.protobuf.internal import more_extensions_pb2
54
56
from google.protobuf.internal import more_messages_pb2
102
104
    return self._pos == len(self._bytes)
103
105
 
104
106
 
105
 
class ReflectionTest(unittest.TestCase):
 
107
class ReflectionTest(basetest.TestCase):
106
108
 
107
109
  def assertListsEqual(self, values, others):
108
110
    self.assertEqual(len(values), len(others))
533
535
    self.assertEqual(0.0, proto.optional_double)
534
536
    self.assertEqual(False, proto.optional_bool)
535
537
    self.assertEqual('', proto.optional_string)
536
 
    self.assertEqual('', proto.optional_bytes)
 
538
    self.assertEqual(b'', proto.optional_bytes)
537
539
 
538
540
    self.assertEqual(41, proto.default_int32)
539
541
    self.assertEqual(42, proto.default_int64)
549
551
    self.assertEqual(52e3, proto.default_double)
550
552
    self.assertEqual(True, proto.default_bool)
551
553
    self.assertEqual('hello', proto.default_string)
552
 
    self.assertEqual('world', proto.default_bytes)
 
554
    self.assertEqual(b'world', proto.default_bytes)
553
555
    self.assertEqual(unittest_pb2.TestAllTypes.BAR, proto.default_nested_enum)
554
556
    self.assertEqual(unittest_pb2.FOREIGN_BAR, proto.default_foreign_enum)
555
557
    self.assertEqual(unittest_import_pb2.IMPORT_BAR,
566
568
    proto = unittest_pb2.TestAllTypes()
567
569
    self.assertRaises(ValueError, proto.ClearField, 'nonexistent_field')
568
570
 
 
571
  def testClearRemovesChildren(self):
 
572
    # Make sure there aren't any implementation bugs that are only partially
 
573
    # clearing the message (which can happen in the more complex C++
 
574
    # implementation which has parallel message lists).
 
575
    proto = unittest_pb2.TestRequiredForeign()
 
576
    for i in range(10):
 
577
      proto.repeated_message.add()
 
578
    proto2 = unittest_pb2.TestRequiredForeign()
 
579
    proto.CopyFrom(proto2)
 
580
    self.assertRaises(IndexError, lambda: proto.repeated_message[5])
 
581
 
569
582
  def testDisallowedAssignments(self):
570
583
    # It's illegal to assign values directly to repeated fields
571
584
    # or to nonrepeated composite fields.  Ensure that this fails.
594
607
    self.assertRaises(TypeError, setattr, proto, 'optional_string', 10)
595
608
    self.assertRaises(TypeError, setattr, proto, 'optional_bytes', 10)
596
609
 
 
610
  def testIntegerTypes(self):
 
611
    def TestGetAndDeserialize(field_name, value, expected_type):
 
612
      proto = unittest_pb2.TestAllTypes()
 
613
      setattr(proto, field_name, value)
 
614
      self.assertTrue(isinstance(getattr(proto, field_name), expected_type))
 
615
      proto2 = unittest_pb2.TestAllTypes()
 
616
      proto2.ParseFromString(proto.SerializeToString())
 
617
      self.assertTrue(isinstance(getattr(proto2, field_name), expected_type))
 
618
 
 
619
    TestGetAndDeserialize('optional_int32', 1, int)
 
620
    TestGetAndDeserialize('optional_int32', 1 << 30, int)
 
621
    TestGetAndDeserialize('optional_uint32', 1 << 30, int)
 
622
    if struct.calcsize('L') == 4:
 
623
      # Python only has signed ints, so 32-bit python can't fit an uint32
 
624
      # in an int.
 
625
      TestGetAndDeserialize('optional_uint32', 1 << 31, long)
 
626
    else:
 
627
      # 64-bit python can fit uint32 inside an int
 
628
      TestGetAndDeserialize('optional_uint32', 1 << 31, int)
 
629
    TestGetAndDeserialize('optional_int64', 1 << 30, long)
 
630
    TestGetAndDeserialize('optional_int64', 1 << 60, long)
 
631
    TestGetAndDeserialize('optional_uint64', 1 << 30, long)
 
632
    TestGetAndDeserialize('optional_uint64', 1 << 60, long)
 
633
 
597
634
  def testSingleScalarBoundsChecking(self):
598
635
    def TestMinAndMaxIntegers(field_name, expected_min, expected_max):
599
636
      pb = unittest_pb2.TestAllTypes()
613
650
    pb.optional_nested_enum = 1
614
651
    self.assertEqual(1, pb.optional_nested_enum)
615
652
 
616
 
    # Invalid enum values.
617
 
    pb.optional_nested_enum = 0
618
 
    self.assertEqual(0, pb.optional_nested_enum)
619
 
 
620
 
    bytes_size_before = pb.ByteSize()
621
 
 
622
 
    pb.optional_nested_enum = 4
623
 
    self.assertEqual(4, pb.optional_nested_enum)
624
 
 
625
 
    pb.optional_nested_enum = 0
626
 
    self.assertEqual(0, pb.optional_nested_enum)
627
 
 
628
 
    # Make sure that setting the same enum field doesn't just add unknown
629
 
    # fields (but overwrites them).
630
 
    self.assertEqual(bytes_size_before, pb.ByteSize())
631
 
 
632
 
    # Is the invalid value preserved after serialization?
633
 
    serialized = pb.SerializeToString()
634
 
    pb2 = unittest_pb2.TestAllTypes()
635
 
    pb2.ParseFromString(serialized)
636
 
    self.assertEqual(0, pb2.optional_nested_enum)
637
 
    self.assertEqual(pb, pb2)
638
 
 
639
653
  def testRepeatedScalarTypeSafety(self):
640
654
    proto = unittest_pb2.TestAllTypes()
641
655
    self.assertRaises(TypeError, proto.repeated_int32.append, 1.1)
749
763
                     unittest_pb2.ForeignEnum.items())
750
764
 
751
765
    proto = unittest_pb2.TestAllTypes()
752
 
    self.assertEqual(['FOO', 'BAR', 'BAZ'], proto.NestedEnum.keys())
753
 
    self.assertEqual([1, 2, 3], proto.NestedEnum.values())
754
 
    self.assertEqual([('FOO', 1), ('BAR', 2), ('BAZ', 3)],
 
766
    self.assertEqual(['FOO', 'BAR', 'BAZ', 'NEG'], proto.NestedEnum.keys())
 
767
    self.assertEqual([1, 2, 3, -1], proto.NestedEnum.values())
 
768
    self.assertEqual([('FOO', 1), ('BAR', 2), ('BAZ', 3), ('NEG', -1)],
755
769
                     proto.NestedEnum.items())
756
770
 
757
771
  def testRepeatedScalars(self):
1155
1169
    self.assertTrue(required is not extendee_proto.Extensions[extension])
1156
1170
    self.assertTrue(not extendee_proto.HasExtension(extension))
1157
1171
 
 
1172
  def testRegisteredExtensions(self):
 
1173
    self.assertTrue('protobuf_unittest.optional_int32_extension' in
 
1174
                    unittest_pb2.TestAllExtensions._extensions_by_name)
 
1175
    self.assertTrue(1 in unittest_pb2.TestAllExtensions._extensions_by_number)
 
1176
    # Make sure extensions haven't been registered into types that shouldn't
 
1177
    # have any.
 
1178
    self.assertEquals(0, len(unittest_pb2.TestAllTypes._extensions_by_name))
 
1179
 
1158
1180
  # If message A directly contains message B, and
1159
1181
  # a.HasField('b') is currently False, then mutating any
1160
1182
  # extension in B should change a.HasField('b') to True
1451
1473
    proto2 = unittest_pb2.TestAllExtensions()
1452
1474
    self.assertRaises(TypeError, proto1.CopyFrom, proto2)
1453
1475
 
 
1476
  def testDeepCopy(self):
 
1477
    proto1 = unittest_pb2.TestAllTypes()
 
1478
    proto1.optional_int32 = 1
 
1479
    proto2 = copy.deepcopy(proto1)
 
1480
    self.assertEqual(1, proto2.optional_int32)
 
1481
 
 
1482
    proto1.repeated_int32.append(2)
 
1483
    proto1.repeated_int32.append(3)
 
1484
    container = copy.deepcopy(proto1.repeated_int32)
 
1485
    self.assertEqual([2, 3], container)
 
1486
 
 
1487
    # TODO(anuraag): Implement deepcopy for repeated composite / extension dict
 
1488
 
1454
1489
  def testClear(self):
1455
1490
    proto = unittest_pb2.TestAllTypes()
1456
1491
    # C++ implementation does not support lazy fields right now so leave it
1496
1531
    self.assertEqual(6, foreign.c)
1497
1532
    nested.bb = 15
1498
1533
    foreign.c = 16
1499
 
    self.assertTrue(not proto.HasField('optional_nested_message'))
 
1534
    self.assertFalse(proto.HasField('optional_nested_message'))
1500
1535
    self.assertEqual(0, proto.optional_nested_message.bb)
1501
 
    self.assertTrue(not proto.HasField('optional_foreign_message'))
 
1536
    self.assertFalse(proto.HasField('optional_foreign_message'))
1502
1537
    self.assertEqual(0, proto.optional_foreign_message.c)
1503
1538
 
 
1539
  def testOneOf(self):
 
1540
    proto = unittest_pb2.TestAllTypes()
 
1541
    proto.oneof_uint32 = 10
 
1542
    proto.oneof_nested_message.bb = 11
 
1543
    self.assertEqual(11, proto.oneof_nested_message.bb)
 
1544
    self.assertFalse(proto.HasField('oneof_uint32'))
 
1545
    nested = proto.oneof_nested_message
 
1546
    proto.oneof_string = 'abc'
 
1547
    self.assertEqual('abc', proto.oneof_string)
 
1548
    self.assertEqual(11, nested.bb)
 
1549
    self.assertFalse(proto.HasField('oneof_nested_message'))
 
1550
 
1504
1551
  def assertInitialized(self, proto):
1505
1552
    self.assertTrue(proto.IsInitialized())
1506
1553
    # Neither method should raise an exception.
1571
1618
    self.assertFalse(proto.IsInitialized(errors))
1572
1619
    self.assertEqual(errors, ['a', 'b', 'c'])
1573
1620
 
 
1621
  @basetest.unittest.skipIf(
 
1622
      api_implementation.Type() != 'cpp' or api_implementation.Version() != 2,
 
1623
      'Errors are only available from the most recent C++ implementation.')
 
1624
  def testFileDescriptorErrors(self):
 
1625
    file_name = 'test_file_descriptor_errors.proto'
 
1626
    package_name = 'test_file_descriptor_errors.proto'
 
1627
    file_descriptor_proto = descriptor_pb2.FileDescriptorProto()
 
1628
    file_descriptor_proto.name = file_name
 
1629
    file_descriptor_proto.package = package_name
 
1630
    m1 = file_descriptor_proto.message_type.add()
 
1631
    m1.name = 'msg1'
 
1632
    # Compiles the proto into the C++ descriptor pool
 
1633
    descriptor.FileDescriptor(
 
1634
        file_name,
 
1635
        package_name,
 
1636
        serialized_pb=file_descriptor_proto.SerializeToString())
 
1637
    # Add a FileDescriptorProto that has duplicate symbols
 
1638
    another_file_name = 'another_test_file_descriptor_errors.proto'
 
1639
    file_descriptor_proto.name = another_file_name
 
1640
    m2 = file_descriptor_proto.message_type.add()
 
1641
    m2.name = 'msg2'
 
1642
    with self.assertRaises(TypeError) as cm:
 
1643
      descriptor.FileDescriptor(
 
1644
          another_file_name,
 
1645
          package_name,
 
1646
          serialized_pb=file_descriptor_proto.SerializeToString())
 
1647
      self.assertTrue(hasattr(cm, 'exception'), '%s not raised' %
 
1648
                      getattr(cm.expected, '__name__', cm.expected))
 
1649
      self.assertIn('test_file_descriptor_errors.proto', str(cm.exception))
 
1650
      # Error message will say something about this definition being a
 
1651
      # duplicate, though we don't check the message exactly to avoid a
 
1652
      # dependency on the C++ logging code.
 
1653
      self.assertIn('test_file_descriptor_errors.msg1', str(cm.exception))
 
1654
 
1574
1655
  def testStringUTF8Encoding(self):
1575
1656
    proto = unittest_pb2.TestAllTypes()
1576
1657
 
1588
1669
    proto.optional_string = str('Testing')
1589
1670
    self.assertEqual(proto.optional_string, unicode('Testing'))
1590
1671
 
1591
 
    if api_implementation.Type() == 'python':
1592
 
      # Values of type 'str' are also accepted as long as they can be
1593
 
      # encoded in UTF-8.
1594
 
      self.assertEqual(type(proto.optional_string), str)
1595
 
 
1596
1672
    # Try to assign a 'str' value which contains bytes that aren't 7-bit ASCII.
1597
1673
    self.assertRaises(ValueError,
1598
 
                      setattr, proto, 'optional_string', str('a\x80a'))
1599
 
    # Assign a 'str' object which contains a UTF-8 encoded string.
1600
 
    self.assertRaises(ValueError,
1601
 
                      setattr, proto, 'optional_string', 'Тест')
 
1674
                      setattr, proto, 'optional_string', b'a\x80a')
 
1675
    if str is bytes:  # PY2
 
1676
      # Assign a 'str' object which contains a UTF-8 encoded string.
 
1677
      self.assertRaises(ValueError,
 
1678
                        setattr, proto, 'optional_string', 'Тест')
 
1679
    else:
 
1680
      proto.optional_string = 'Тест'
1602
1681
    # No exception thrown.
1603
1682
    proto.optional_string = 'abc'
1604
1683
 
1621
1700
    self.assertEqual(proto.ByteSize(), len(serialized))
1622
1701
 
1623
1702
    raw = unittest_mset_pb2.RawMessageSet()
1624
 
    raw.MergeFromString(serialized)
 
1703
    bytes_read = raw.MergeFromString(serialized)
 
1704
    self.assertEqual(len(serialized), bytes_read)
1625
1705
 
1626
1706
    message2 = unittest_mset_pb2.TestMessageSetExtension2()
1627
1707
 
1632
1712
    # Check the actual bytes on the wire.
1633
1713
    self.assertTrue(
1634
1714
        raw.item[0].message.endswith(test_utf8_bytes))
1635
 
    message2.MergeFromString(raw.item[0].message)
 
1715
    bytes_read = message2.MergeFromString(raw.item[0].message)
 
1716
    self.assertEqual(len(raw.item[0].message), bytes_read)
1636
1717
 
1637
1718
    self.assertEqual(type(message2.str), unicode)
1638
1719
    self.assertEqual(message2.str, test_utf8)
1643
1724
    # MergeFromString and thus has no way to throw the exception.
1644
1725
    #
1645
1726
    # The pure Python API always returns objects of type 'unicode' (UTF-8
1646
 
    # encoded), or 'str' (in 7 bit ASCII).
1647
 
    bytes = raw.item[0].message.replace(
1648
 
        test_utf8_bytes, len(test_utf8_bytes) * '\xff')
 
1727
    # encoded), or 'bytes' (in 7 bit ASCII).
 
1728
    badbytes = raw.item[0].message.replace(
 
1729
        test_utf8_bytes, len(test_utf8_bytes) * b'\xff')
1649
1730
 
1650
1731
    unicode_decode_failed = False
1651
1732
    try:
1652
 
      message2.MergeFromString(bytes)
1653
 
    except UnicodeDecodeError as e:
 
1733
      message2.MergeFromString(badbytes)
 
1734
    except UnicodeDecodeError:
1654
1735
      unicode_decode_failed = True
1655
1736
    string_field = message2.str
1656
 
    self.assertTrue(unicode_decode_failed or type(string_field) == str)
 
1737
    self.assertTrue(unicode_decode_failed or type(string_field) is bytes)
 
1738
 
 
1739
  def testBytesInTextFormat(self):
 
1740
    proto = unittest_pb2.TestAllTypes(optional_bytes=b'\x00\x7f\x80\xff')
 
1741
    self.assertEqual(u'optional_bytes: "\\000\\177\\200\\377"\n',
 
1742
                     unicode(proto))
1657
1743
 
1658
1744
  def testEmptyNestedMessage(self):
1659
1745
    proto = unittest_pb2.TestAllTypes()
1667
1753
    self.assertTrue(proto.HasField('optional_nested_message'))
1668
1754
 
1669
1755
    proto = unittest_pb2.TestAllTypes()
1670
 
    proto.optional_nested_message.MergeFromString('')
 
1756
    bytes_read = proto.optional_nested_message.MergeFromString(b'')
 
1757
    self.assertEqual(0, bytes_read)
1671
1758
    self.assertTrue(proto.HasField('optional_nested_message'))
1672
1759
 
1673
1760
    proto = unittest_pb2.TestAllTypes()
1674
 
    proto.optional_nested_message.ParseFromString('')
 
1761
    proto.optional_nested_message.ParseFromString(b'')
1675
1762
    self.assertTrue(proto.HasField('optional_nested_message'))
1676
1763
 
1677
1764
    serialized = proto.SerializeToString()
1678
1765
    proto2 = unittest_pb2.TestAllTypes()
1679
 
    proto2.MergeFromString(serialized)
 
1766
    self.assertEqual(
 
1767
        len(serialized),
 
1768
        proto2.MergeFromString(serialized))
1680
1769
    self.assertTrue(proto2.HasField('optional_nested_message'))
1681
1770
 
1682
1771
  def testSetInParent(self):
1690
1779
#  into separate TestCase classes.
1691
1780
 
1692
1781
 
1693
 
class TestAllTypesEqualityTest(unittest.TestCase):
 
1782
class TestAllTypesEqualityTest(basetest.TestCase):
1694
1783
 
1695
1784
  def setUp(self):
1696
1785
    self.first_proto = unittest_pb2.TestAllTypes()
1706
1795
    self.assertEqual(self.first_proto, self.second_proto)
1707
1796
 
1708
1797
 
1709
 
class FullProtosEqualityTest(unittest.TestCase):
 
1798
class FullProtosEqualityTest(basetest.TestCase):
1710
1799
 
1711
1800
  """Equality tests using completely-full protos as a starting point."""
1712
1801
 
1792
1881
    self.assertEqual(self.first_proto, self.second_proto)
1793
1882
 
1794
1883
 
1795
 
class ExtensionEqualityTest(unittest.TestCase):
 
1884
class ExtensionEqualityTest(basetest.TestCase):
1796
1885
 
1797
1886
  def testExtensionEquality(self):
1798
1887
    first_proto = unittest_pb2.TestAllExtensions()
1825
1914
    self.assertEqual(first_proto, second_proto)
1826
1915
 
1827
1916
 
1828
 
class MutualRecursionEqualityTest(unittest.TestCase):
 
1917
class MutualRecursionEqualityTest(basetest.TestCase):
1829
1918
 
1830
1919
  def testEqualityWithMutualRecursion(self):
1831
1920
    first_proto = unittest_pb2.TestMutualRecursionA()
1837
1926
    self.assertEqual(first_proto, second_proto)
1838
1927
 
1839
1928
 
1840
 
class ByteSizeTest(unittest.TestCase):
 
1929
class ByteSizeTest(basetest.TestCase):
1841
1930
 
1842
1931
  def setUp(self):
1843
1932
    self.proto = unittest_pb2.TestAllTypes()
2133
2222
#   * Handling of empty submessages (with and without "has"
2134
2223
#     bits set).
2135
2224
 
2136
 
class SerializationTest(unittest.TestCase):
 
2225
class SerializationTest(basetest.TestCase):
2137
2226
 
2138
2227
  def testSerializeEmtpyMessage(self):
2139
2228
    first_proto = unittest_pb2.TestAllTypes()
2140
2229
    second_proto = unittest_pb2.TestAllTypes()
2141
2230
    serialized = first_proto.SerializeToString()
2142
2231
    self.assertEqual(first_proto.ByteSize(), len(serialized))
2143
 
    second_proto.MergeFromString(serialized)
 
2232
    self.assertEqual(
 
2233
        len(serialized),
 
2234
        second_proto.MergeFromString(serialized))
2144
2235
    self.assertEqual(first_proto, second_proto)
2145
2236
 
2146
2237
  def testSerializeAllFields(self):
2149
2240
    test_util.SetAllFields(first_proto)
2150
2241
    serialized = first_proto.SerializeToString()
2151
2242
    self.assertEqual(first_proto.ByteSize(), len(serialized))
2152
 
    second_proto.MergeFromString(serialized)
 
2243
    self.assertEqual(
 
2244
        len(serialized),
 
2245
        second_proto.MergeFromString(serialized))
2153
2246
    self.assertEqual(first_proto, second_proto)
2154
2247
 
2155
2248
  def testSerializeAllExtensions(self):
2157
2250
    second_proto = unittest_pb2.TestAllExtensions()
2158
2251
    test_util.SetAllExtensions(first_proto)
2159
2252
    serialized = first_proto.SerializeToString()
2160
 
    second_proto.MergeFromString(serialized)
 
2253
    self.assertEqual(
 
2254
        len(serialized),
 
2255
        second_proto.MergeFromString(serialized))
 
2256
    self.assertEqual(first_proto, second_proto)
 
2257
 
 
2258
  def testSerializeWithOptionalGroup(self):
 
2259
    first_proto = unittest_pb2.TestAllTypes()
 
2260
    second_proto = unittest_pb2.TestAllTypes()
 
2261
    first_proto.optionalgroup.a = 242
 
2262
    serialized = first_proto.SerializeToString()
 
2263
    self.assertEqual(
 
2264
        len(serialized),
 
2265
        second_proto.MergeFromString(serialized))
2161
2266
    self.assertEqual(first_proto, second_proto)
2162
2267
 
2163
2268
  def testSerializeNegativeValues(self):
2249
2354
    second_proto.optional_int32 = 100
2250
2355
    second_proto.optional_nested_message.bb = 999
2251
2356
 
2252
 
    second_proto.MergeFromString(serialized)
 
2357
    bytes_parsed = second_proto.MergeFromString(serialized)
 
2358
    self.assertEqual(len(serialized), bytes_parsed)
 
2359
 
2253
2360
    # Ensure that we append to repeated fields.
2254
2361
    self.assertEqual(['baz', 'foobar'], list(second_proto.repeated_string))
2255
2362
    # Ensure that we overwrite nonrepeatd scalars.
2274
2381
    raw = unittest_mset_pb2.RawMessageSet()
2275
2382
    self.assertEqual(False,
2276
2383
                     raw.DESCRIPTOR.GetOptions().message_set_wire_format)
2277
 
    raw.MergeFromString(serialized)
 
2384
    self.assertEqual(
 
2385
        len(serialized),
 
2386
        raw.MergeFromString(serialized))
2278
2387
    self.assertEqual(2, len(raw.item))
2279
2388
 
2280
2389
    message1 = unittest_mset_pb2.TestMessageSetExtension1()
2281
 
    message1.MergeFromString(raw.item[0].message)
 
2390
    self.assertEqual(
 
2391
        len(raw.item[0].message),
 
2392
        message1.MergeFromString(raw.item[0].message))
2282
2393
    self.assertEqual(123, message1.i)
2283
2394
 
2284
2395
    message2 = unittest_mset_pb2.TestMessageSetExtension2()
2285
 
    message2.MergeFromString(raw.item[1].message)
 
2396
    self.assertEqual(
 
2397
        len(raw.item[1].message),
 
2398
        message2.MergeFromString(raw.item[1].message))
2286
2399
    self.assertEqual('foo', message2.str)
2287
2400
 
2288
2401
    # Deserialize using the MessageSet wire format.
2289
2402
    proto2 = unittest_mset_pb2.TestMessageSet()
2290
 
    proto2.MergeFromString(serialized)
 
2403
    self.assertEqual(
 
2404
        len(serialized),
 
2405
        proto2.MergeFromString(serialized))
2291
2406
    self.assertEqual(123, proto2.Extensions[extension1].i)
2292
2407
    self.assertEqual('foo', proto2.Extensions[extension2].str)
2293
2408
 
2327
2442
 
2328
2443
    # Parse message using the message set wire format.
2329
2444
    proto = unittest_mset_pb2.TestMessageSet()
2330
 
    proto.MergeFromString(serialized)
 
2445
    self.assertEqual(
 
2446
        len(serialized),
 
2447
        proto.MergeFromString(serialized))
2331
2448
 
2332
2449
    # Check that the message parsed well.
2333
2450
    extension_message1 = unittest_mset_pb2.TestMessageSetExtension1
2345
2462
    proto2 = unittest_pb2.TestEmptyMessage()
2346
2463
 
2347
2464
    # Parsing this message should succeed.
2348
 
    proto2.MergeFromString(serialized)
 
2465
    self.assertEqual(
 
2466
        len(serialized),
 
2467
        proto2.MergeFromString(serialized))
2349
2468
 
2350
2469
    # Now test with a int64 field set.
2351
2470
    proto = unittest_pb2.TestAllTypes()
2355
2474
    # unknown.
2356
2475
    proto2 = unittest_pb2.TestEmptyMessage()
2357
2476
    # Parsing this message should succeed.
2358
 
    proto2.MergeFromString(serialized)
 
2477
    self.assertEqual(
 
2478
        len(serialized),
 
2479
        proto2.MergeFromString(serialized))
2359
2480
 
2360
2481
  def _CheckRaises(self, exc_class, callable_obj, exception):
2361
2482
    """This method checks if the excpetion type and message are as expected."""
2406
2527
    partial = proto.SerializePartialToString()
2407
2528
 
2408
2529
    proto2 = unittest_pb2.TestRequired()
2409
 
    proto2.MergeFromString(serialized)
 
2530
    self.assertEqual(
 
2531
        len(serialized),
 
2532
        proto2.MergeFromString(serialized))
2410
2533
    self.assertEqual(1, proto2.a)
2411
2534
    self.assertEqual(2, proto2.b)
2412
2535
    self.assertEqual(3, proto2.c)
2413
 
    proto2.ParseFromString(partial)
 
2536
    self.assertEqual(
 
2537
        len(partial),
 
2538
        proto2.MergeFromString(partial))
2414
2539
    self.assertEqual(1, proto2.a)
2415
2540
    self.assertEqual(2, proto2.b)
2416
2541
    self.assertEqual(3, proto2.c)
2478
2603
    second_proto.packed_double.extend([1.0, 2.0])
2479
2604
    second_proto.packed_sint32.append(4)
2480
2605
 
2481
 
    second_proto.MergeFromString(serialized)
 
2606
    self.assertEqual(
 
2607
        len(serialized),
 
2608
        second_proto.MergeFromString(serialized))
2482
2609
    self.assertEqual([3, 1, 2], second_proto.packed_int32)
2483
2610
    self.assertEqual([1.0, 2.0, 3.0], second_proto.packed_double)
2484
2611
    self.assertEqual([4], second_proto.packed_sint32)
2511
2638
    unpacked = unittest_pb2.TestUnpackedTypes()
2512
2639
    test_util.SetAllUnpackedFields(unpacked)
2513
2640
    packed = unittest_pb2.TestPackedTypes()
2514
 
    packed.MergeFromString(unpacked.SerializeToString())
 
2641
    serialized = unpacked.SerializeToString()
 
2642
    self.assertEqual(
 
2643
        len(serialized),
 
2644
        packed.MergeFromString(serialized))
2515
2645
    expected = unittest_pb2.TestPackedTypes()
2516
2646
    test_util.SetAllPackedFields(expected)
2517
2647
    self.assertEqual(expected, packed)
2520
2650
    packed = unittest_pb2.TestPackedTypes()
2521
2651
    test_util.SetAllPackedFields(packed)
2522
2652
    unpacked = unittest_pb2.TestUnpackedTypes()
2523
 
    unpacked.MergeFromString(packed.SerializeToString())
 
2653
    serialized = packed.SerializeToString()
 
2654
    self.assertEqual(
 
2655
        len(serialized),
 
2656
        unpacked.MergeFromString(serialized))
2524
2657
    expected = unittest_pb2.TestUnpackedTypes()
2525
2658
    test_util.SetAllUnpackedFields(expected)
2526
2659
    self.assertEqual(expected, unpacked)
2572
2705
        optional_int32=1,
2573
2706
        optional_string='foo',
2574
2707
        optional_bool=True,
2575
 
        optional_bytes='bar',
 
2708
        optional_bytes=b'bar',
2576
2709
        optional_nested_message=unittest_pb2.TestAllTypes.NestedMessage(bb=1),
2577
2710
        optional_foreign_message=unittest_pb2.ForeignMessage(c=1),
2578
2711
        optional_nested_enum=unittest_pb2.TestAllTypes.FOO,
2590
2723
    self.assertEqual(1, proto.optional_int32)
2591
2724
    self.assertEqual('foo', proto.optional_string)
2592
2725
    self.assertEqual(True, proto.optional_bool)
2593
 
    self.assertEqual('bar', proto.optional_bytes)
 
2726
    self.assertEqual(b'bar', proto.optional_bytes)
2594
2727
    self.assertEqual(1, proto.optional_nested_message.bb)
2595
2728
    self.assertEqual(1, proto.optional_foreign_message.c)
2596
2729
    self.assertEqual(unittest_pb2.TestAllTypes.FOO,
2640
2773
    self.assertEqual(3, proto.repeated_int32[2])
2641
2774
 
2642
2775
 
2643
 
class OptionsTest(unittest.TestCase):
 
2776
class OptionsTest(basetest.TestCase):
2644
2777
 
2645
2778
  def testMessageOptions(self):
2646
2779
    proto = unittest_mset_pb2.TestMessageSet()
2667
2800
 
2668
2801
 
2669
2802
 
 
2803
class ClassAPITest(basetest.TestCase):
 
2804
 
 
2805
  def testMakeClassWithNestedDescriptor(self):
 
2806
    leaf_desc = descriptor.Descriptor('leaf', 'package.parent.child.leaf', '',
 
2807
                                      containing_type=None, fields=[],
 
2808
                                      nested_types=[], enum_types=[],
 
2809
                                      extensions=[])
 
2810
    child_desc = descriptor.Descriptor('child', 'package.parent.child', '',
 
2811
                                       containing_type=None, fields=[],
 
2812
                                       nested_types=[leaf_desc], enum_types=[],
 
2813
                                       extensions=[])
 
2814
    sibling_desc = descriptor.Descriptor('sibling', 'package.parent.sibling',
 
2815
                                         '', containing_type=None, fields=[],
 
2816
                                         nested_types=[], enum_types=[],
 
2817
                                         extensions=[])
 
2818
    parent_desc = descriptor.Descriptor('parent', 'package.parent', '',
 
2819
                                        containing_type=None, fields=[],
 
2820
                                        nested_types=[child_desc, sibling_desc],
 
2821
                                        enum_types=[], extensions=[])
 
2822
    message_class = reflection.MakeClass(parent_desc)
 
2823
    self.assertIn('child', message_class.__dict__)
 
2824
    self.assertIn('sibling', message_class.__dict__)
 
2825
    self.assertIn('leaf', message_class.child.__dict__)
 
2826
 
 
2827
  def _GetSerializedFileDescriptor(self, name):
 
2828
    """Get a serialized representation of a test FileDescriptorProto.
 
2829
 
 
2830
    Args:
 
2831
      name: All calls to this must use a unique message name, to avoid
 
2832
          collisions in the cpp descriptor pool.
 
2833
    Returns:
 
2834
      A string containing the serialized form of a test FileDescriptorProto.
 
2835
    """
 
2836
    file_descriptor_str = (
 
2837
        'message_type {'
 
2838
        '  name: "' + name + '"'
 
2839
        '  field {'
 
2840
        '    name: "flat"'
 
2841
        '    number: 1'
 
2842
        '    label: LABEL_REPEATED'
 
2843
        '    type: TYPE_UINT32'
 
2844
        '  }'
 
2845
        '  field {'
 
2846
        '    name: "bar"'
 
2847
        '    number: 2'
 
2848
        '    label: LABEL_OPTIONAL'
 
2849
        '    type: TYPE_MESSAGE'
 
2850
        '    type_name: "Bar"'
 
2851
        '  }'
 
2852
        '  nested_type {'
 
2853
        '    name: "Bar"'
 
2854
        '    field {'
 
2855
        '      name: "baz"'
 
2856
        '      number: 3'
 
2857
        '      label: LABEL_OPTIONAL'
 
2858
        '      type: TYPE_MESSAGE'
 
2859
        '      type_name: "Baz"'
 
2860
        '    }'
 
2861
        '    nested_type {'
 
2862
        '      name: "Baz"'
 
2863
        '      enum_type {'
 
2864
        '        name: "deep_enum"'
 
2865
        '        value {'
 
2866
        '          name: "VALUE_A"'
 
2867
        '          number: 0'
 
2868
        '        }'
 
2869
        '      }'
 
2870
        '      field {'
 
2871
        '        name: "deep"'
 
2872
        '        number: 4'
 
2873
        '        label: LABEL_OPTIONAL'
 
2874
        '        type: TYPE_UINT32'
 
2875
        '      }'
 
2876
        '    }'
 
2877
        '  }'
 
2878
        '}')
 
2879
    file_descriptor = descriptor_pb2.FileDescriptorProto()
 
2880
    text_format.Merge(file_descriptor_str, file_descriptor)
 
2881
    return file_descriptor.SerializeToString()
 
2882
 
 
2883
  def testParsingFlatClassWithExplicitClassDeclaration(self):
 
2884
    """Test that the generated class can parse a flat message."""
 
2885
    file_descriptor = descriptor_pb2.FileDescriptorProto()
 
2886
    file_descriptor.ParseFromString(self._GetSerializedFileDescriptor('A'))
 
2887
    msg_descriptor = descriptor.MakeDescriptor(
 
2888
        file_descriptor.message_type[0])
 
2889
 
 
2890
    class MessageClass(message.Message):
 
2891
      __metaclass__ = reflection.GeneratedProtocolMessageType
 
2892
      DESCRIPTOR = msg_descriptor
 
2893
    msg = MessageClass()
 
2894
    msg_str = (
 
2895
        'flat: 0 '
 
2896
        'flat: 1 '
 
2897
        'flat: 2 ')
 
2898
    text_format.Merge(msg_str, msg)
 
2899
    self.assertEqual(msg.flat, [0, 1, 2])
 
2900
 
 
2901
  def testParsingFlatClass(self):
 
2902
    """Test that the generated class can parse a flat message."""
 
2903
    file_descriptor = descriptor_pb2.FileDescriptorProto()
 
2904
    file_descriptor.ParseFromString(self._GetSerializedFileDescriptor('B'))
 
2905
    msg_descriptor = descriptor.MakeDescriptor(
 
2906
        file_descriptor.message_type[0])
 
2907
    msg_class = reflection.MakeClass(msg_descriptor)
 
2908
    msg = msg_class()
 
2909
    msg_str = (
 
2910
        'flat: 0 '
 
2911
        'flat: 1 '
 
2912
        'flat: 2 ')
 
2913
    text_format.Merge(msg_str, msg)
 
2914
    self.assertEqual(msg.flat, [0, 1, 2])
 
2915
 
 
2916
  def testParsingNestedClass(self):
 
2917
    """Test that the generated class can parse a nested message."""
 
2918
    file_descriptor = descriptor_pb2.FileDescriptorProto()
 
2919
    file_descriptor.ParseFromString(self._GetSerializedFileDescriptor('C'))
 
2920
    msg_descriptor = descriptor.MakeDescriptor(
 
2921
        file_descriptor.message_type[0])
 
2922
    msg_class = reflection.MakeClass(msg_descriptor)
 
2923
    msg = msg_class()
 
2924
    msg_str = (
 
2925
        'bar {'
 
2926
        '  baz {'
 
2927
        '    deep: 4'
 
2928
        '  }'
 
2929
        '}')
 
2930
    text_format.Merge(msg_str, msg)
 
2931
    self.assertEqual(msg.bar.baz.deep, 4)
 
2932
 
2670
2933
if __name__ == '__main__':
2671
 
  unittest.main()
 
2934
  basetest.main()