aboutsummaryrefslogtreecommitdiff
path: root/python/google/protobuf/internal/well_known_types_test.py
diff options
context:
space:
mode:
authorAdam Cozzette <acozzette@google.com>2017-09-12 10:32:01 -0700
committerAdam Cozzette <acozzette@google.com>2017-09-14 10:03:57 -0700
commit13fd045dbb2b4dacea32be162a41d5a4b0d1802f (patch)
treec219e7eb18b82523e36c6748861c403a14ea66ae /python/google/protobuf/internal/well_known_types_test.py
parentd1bc27caef8377a710370189675cb0958443e8f1 (diff)
downloadprotobuf-13fd045dbb2b4dacea32be162a41d5a4b0d1802f.tar.gz
protobuf-13fd045dbb2b4dacea32be162a41d5a4b0d1802f.tar.bz2
protobuf-13fd045dbb2b4dacea32be162a41d5a4b0d1802f.zip
Integrated internal changes from Google
Diffstat (limited to 'python/google/protobuf/internal/well_known_types_test.py')
-rw-r--r--python/google/protobuf/internal/well_known_types_test.py142
1 files changed, 141 insertions, 1 deletions
diff --git a/python/google/protobuf/internal/well_known_types_test.py b/python/google/protobuf/internal/well_known_types_test.py
index 123a537c..70975da1 100644
--- a/python/google/protobuf/internal/well_known_types_test.py
+++ b/python/google/protobuf/internal/well_known_types_test.py
@@ -105,6 +105,10 @@ class TimeUtilTest(TimeUtilTestBase):
self.assertEqual(8 * 3600, message.seconds)
self.assertEqual(0, message.nanos)
+ # It is not easy to check with current time. For test coverage only.
+ message.GetCurrentTime()
+ self.assertNotEqual(8 * 3600, message.seconds)
+
def testDurationSerializeAndParse(self):
message = duration_pb2.Duration()
# Generated output should contain 3, 6, or 9 fractional digits.
@@ -268,6 +272,17 @@ class TimeUtilTest(TimeUtilTestBase):
def testInvalidTimestamp(self):
message = timestamp_pb2.Timestamp()
self.assertRaisesRegexp(
+ well_known_types.ParseError,
+ 'Failed to parse timestamp: missing valid timezone offset.',
+ message.FromJsonString,
+ '')
+ self.assertRaisesRegexp(
+ well_known_types.ParseError,
+ 'Failed to parse timestamp: invalid trailing data '
+ '1970-01-01T00:00:01Ztrail.',
+ message.FromJsonString,
+ '1970-01-01T00:00:01Ztrail')
+ self.assertRaisesRegexp(
ValueError,
'time data \'10000-01-01T00:00:00\' does not match'
' format \'%Y-%m-%dT%H:%M:%S\'',
@@ -322,6 +337,13 @@ class TimeUtilTest(TimeUtilTestBase):
r'Duration is not valid\: Seconds -315576000001 must be in range'
r' \[-315576000000\, 315576000000\].',
message.ToJsonString)
+ message.seconds = 0
+ message.nanos = 999999999 + 1
+ self.assertRaisesRegexp(
+ well_known_types.Error,
+ r'Duration is not valid\: Nanos 1000000000 must be in range'
+ r' \[-999999999\, 999999999\].',
+ message.ToJsonString)
class FieldMaskTest(unittest.TestCase):
@@ -363,10 +385,37 @@ class FieldMaskTest(unittest.TestCase):
self.assertTrue(mask.IsValidForDescriptor(msg_descriptor))
for field in msg_descriptor.fields:
self.assertTrue(field.name in mask.paths)
+
+ def testIsValidForDescriptor(self):
+ msg_descriptor = unittest_pb2.TestAllTypes.DESCRIPTOR
+ # Empty mask
+ mask = field_mask_pb2.FieldMask()
+ self.assertTrue(mask.IsValidForDescriptor(msg_descriptor))
+ # All fields from descriptor
+ mask.AllFieldsFromDescriptor(msg_descriptor)
+ self.assertTrue(mask.IsValidForDescriptor(msg_descriptor))
+ # Child under optional message
mask.paths.append('optional_nested_message.bb')
self.assertTrue(mask.IsValidForDescriptor(msg_descriptor))
+ # Repeated field is only allowed in the last position of path
mask.paths.append('repeated_nested_message.bb')
self.assertFalse(mask.IsValidForDescriptor(msg_descriptor))
+ # Invalid top level field
+ mask = field_mask_pb2.FieldMask()
+ mask.paths.append('xxx')
+ self.assertFalse(mask.IsValidForDescriptor(msg_descriptor))
+ # Invalid field in root
+ mask = field_mask_pb2.FieldMask()
+ mask.paths.append('xxx.zzz')
+ self.assertFalse(mask.IsValidForDescriptor(msg_descriptor))
+ # Invalid field in internal node
+ mask = field_mask_pb2.FieldMask()
+ mask.paths.append('optional_nested_message.xxx.zzz')
+ self.assertFalse(mask.IsValidForDescriptor(msg_descriptor))
+ # Invalid field in leaf
+ mask = field_mask_pb2.FieldMask()
+ mask.paths.append('optional_nested_message.xxx')
+ self.assertFalse(mask.IsValidForDescriptor(msg_descriptor))
def testCanonicalFrom(self):
mask = field_mask_pb2.FieldMask()
@@ -422,6 +471,9 @@ class FieldMaskTest(unittest.TestCase):
mask2.FromJsonString('foo.bar,bar')
out_mask.Union(mask1, mask2)
self.assertEqual('bar,foo.bar,quz', out_mask.ToJsonString())
+ src = unittest_pb2.TestAllTypes()
+ with self.assertRaises(ValueError):
+ out_mask.Union(src, mask2)
def testIntersect(self):
mask1 = field_mask_pb2.FieldMask()
@@ -546,6 +598,19 @@ class FieldMaskTest(unittest.TestCase):
self.assertEqual(1, len(nested_dst.payload.repeated_int32))
self.assertEqual(1234, nested_dst.payload.repeated_int32[0])
+ def testMergeErrors(self):
+ src = unittest_pb2.TestAllTypes()
+ dst = unittest_pb2.TestAllTypes()
+ mask = field_mask_pb2.FieldMask()
+ test_util.SetAllFields(src)
+ mask.FromJsonString('optionalInt32.field')
+ with self.assertRaises(ValueError) as e:
+ mask.MergeMessage(src, dst)
+ self.assertEqual('Error: Field optional_int32 in message '
+ 'protobuf_unittest.TestAllTypes is not a singular '
+ 'message field and cannot have sub-fields.',
+ str(e.exception))
+
def testSnakeCaseToCamelCase(self):
self.assertEqual('fooBar',
well_known_types._SnakeCaseToCamelCase('foo_bar'))
@@ -611,6 +676,8 @@ class StructTest(unittest.TestCase):
struct_list = struct.get_or_create_list('key5')
struct_list.extend([6, 'seven', True, False, None])
struct_list.add_struct()['subkey2'] = 9
+ struct['key6'] = {'subkey': {}}
+ struct['key7'] = [2, False]
self.assertTrue(isinstance(struct, well_known_types.Struct))
self.assertEqual(5, struct['key1'])
@@ -621,9 +688,10 @@ class StructTest(unittest.TestCase):
inner_struct['subkey2'] = 9
self.assertEqual([6, 'seven', True, False, None, inner_struct],
list(struct['key5'].items()))
+ self.assertEqual({}, dict(struct['key6']['subkey'].fields))
+ self.assertEqual([2, False], list(struct['key7'].items()))
serialized = struct.SerializeToString()
-
struct2 = struct_pb2.Struct()
struct2.ParseFromString(serialized)
@@ -651,6 +719,17 @@ class StructTest(unittest.TestCase):
struct_list.add_list().extend([1, 'two', True, False, None])
self.assertEqual([1, 'two', True, False, None],
list(struct_list[6].items()))
+ struct_list.extend([{'nested_struct': 30}, ['nested_list', 99], {}, []])
+ self.assertEqual(11, len(struct_list.values))
+ self.assertEqual(30, struct_list[7]['nested_struct'])
+ self.assertEqual('nested_list', struct_list[8][0])
+ self.assertEqual(99, struct_list[8][1])
+ self.assertEqual({}, dict(struct_list[9].fields))
+ self.assertEqual([], list(struct_list[10].items()))
+ struct_list[0] = {'replace': 'set'}
+ struct_list[1] = ['replace', 'set']
+ self.assertEqual('set', struct_list[0]['replace'])
+ self.assertEqual(['replace', 'set'], list(struct_list[1].items()))
text_serialized = str(struct)
struct3 = struct_pb2.Struct()
@@ -660,6 +739,67 @@ class StructTest(unittest.TestCase):
struct.get_or_create_struct('key3')['replace'] = 12
self.assertEqual(12, struct['key3']['replace'])
+ # Tests empty list.
+ struct.get_or_create_list('empty_list')
+ empty_list = struct['empty_list']
+ self.assertEqual([], list(empty_list.items()))
+ list2 = struct_pb2.ListValue()
+ list2.add_list()
+ empty_list = list2[0]
+ self.assertEqual([], list(empty_list.items()))
+
+ # Tests empty struct.
+ struct.get_or_create_struct('empty_struct')
+ empty_struct = struct['empty_struct']
+ self.assertEqual({}, dict(empty_struct.fields))
+ list2.add_struct()
+ empty_struct = list2[1]
+ self.assertEqual({}, dict(empty_struct.fields))
+
+ def testMergeFrom(self):
+ struct = struct_pb2.Struct()
+ struct_class = struct.__class__
+
+ dictionary = {
+ 'key1': 5,
+ 'key2': 'abc',
+ 'key3': True,
+ 'key4': {'subkey': 11.0},
+ 'key5': [6, 'seven', True, False, None, {'subkey2': 9}],
+ 'key6': [['nested_list', True]],
+ 'empty_struct': {},
+ 'empty_list': []
+ }
+ struct.update(dictionary)
+ self.assertEqual(5, struct['key1'])
+ self.assertEqual('abc', struct['key2'])
+ self.assertIs(True, struct['key3'])
+ self.assertEqual(11, struct['key4']['subkey'])
+ inner_struct = struct_class()
+ inner_struct['subkey2'] = 9
+ self.assertEqual([6, 'seven', True, False, None, inner_struct],
+ list(struct['key5'].items()))
+ self.assertEqual(2, len(struct['key6'][0].values))
+ self.assertEqual('nested_list', struct['key6'][0][0])
+ self.assertEqual(True, struct['key6'][0][1])
+ empty_list = struct['empty_list']
+ self.assertEqual([], list(empty_list.items()))
+ empty_struct = struct['empty_struct']
+ self.assertEqual({}, dict(empty_struct.fields))
+
+ # According to documentation: "When parsing from the wire or when merging,
+ # if there are duplicate map keys the last key seen is used".
+ duplicate = {
+ 'key4': {'replace': 20},
+ 'key5': [[False, 5]]
+ }
+ struct.update(duplicate)
+ self.assertEqual(1, len(struct['key4'].fields))
+ self.assertEqual(20, struct['key4']['replace'])
+ self.assertEqual(1, len(struct['key5'].values))
+ self.assertEqual(False, struct['key5'][0][0])
+ self.assertEqual(5, struct['key5'][0][1])
+
class AnyTest(unittest.TestCase):