1# Protocol Buffers - Google's data interchange format 2# Copyright 2008 Google Inc. All rights reserved. 3# 4# Use of this source code is governed by a BSD-style 5# license that can be found in the LICENSE file or at 6# https://developers.google.com/open-source/licenses/bsd 7 8"""Tests for google.protobuf.proto_builder.""" 9 10import collections 11import unittest 12 13from google.protobuf import descriptor 14from google.protobuf import descriptor_pb2 15from google.protobuf import descriptor_pool 16from google.protobuf import proto_builder 17from google.protobuf import text_format 18 19 20class ProtoBuilderTest(unittest.TestCase): 21 22 def setUp(self): 23 super().setUp() 24 25 self.ordered_fields = collections.OrderedDict([ 26 ('foo', descriptor_pb2.FieldDescriptorProto.TYPE_INT64), 27 ('bar', descriptor_pb2.FieldDescriptorProto.TYPE_STRING), 28 ]) 29 self._fields = dict(self.ordered_fields) 30 31 def testMakeSimpleProtoClass(self): 32 """Test that we can create a proto class.""" 33 proto_cls = proto_builder.MakeSimpleProtoClass( 34 self._fields, 35 full_name='net.proto2.python.public.proto_builder_test.Test') 36 proto = proto_cls() 37 proto.foo = 12345 38 proto.bar = 'asdf' 39 self.assertMultiLineEqual( 40 'bar: "asdf"\nfoo: 12345\n', text_format.MessageToString(proto)) 41 42 def testOrderedFields(self): 43 """Test that the field order is maintained when given an OrderedDict.""" 44 proto_cls = proto_builder.MakeSimpleProtoClass( 45 self.ordered_fields, 46 full_name='net.proto2.python.public.proto_builder_test.OrderedTest') 47 proto = proto_cls() 48 proto.foo = 12345 49 proto.bar = 'asdf' 50 self.assertMultiLineEqual( 51 'foo: 12345\nbar: "asdf"\n', text_format.MessageToString(proto)) 52 53 def testMakeSameProtoClassTwice(self): 54 """Test that the DescriptorPool is used.""" 55 pool = descriptor_pool.DescriptorPool() 56 proto_cls1 = proto_builder.MakeSimpleProtoClass( 57 self._fields, 58 full_name='net.proto2.python.public.proto_builder_test.Test', 59 pool=pool) 60 proto_cls2 = proto_builder.MakeSimpleProtoClass( 61 self._fields, 62 full_name='net.proto2.python.public.proto_builder_test.Test', 63 pool=pool) 64 self.assertIs(proto_cls1.DESCRIPTOR, proto_cls2.DESCRIPTOR) 65 66 def testMakeLargeProtoClass(self): 67 """Test that large created protos don't use reserved field numbers.""" 68 num_fields = 123456 69 fields = { 70 'foo%d' % i: descriptor_pb2.FieldDescriptorProto.TYPE_INT64 71 for i in range(num_fields) 72 } 73 proto_cls = proto_builder.MakeSimpleProtoClass( 74 fields, 75 full_name='net.proto2.python.public.proto_builder_test.LargeProtoTest') 76 77 reserved_field_numbers = set( 78 range(descriptor.FieldDescriptor.FIRST_RESERVED_FIELD_NUMBER, 79 descriptor.FieldDescriptor.LAST_RESERVED_FIELD_NUMBER + 1)) 80 proto_field_numbers = set(proto_cls.DESCRIPTOR.fields_by_number) 81 self.assertFalse(reserved_field_numbers.intersection(proto_field_numbers)) 82 83 84if __name__ == '__main__': 85 unittest.main() 86