1# Protocol Buffers - Google's data interchange format 2# Copyright 2008 Google Inc. All rights reserved. 3# https://developers.google.com/protocol-buffers/ 4# 5# Redistribution and use in source and binary forms, with or without 6# modification, are permitted provided that the following conditions are 7# met: 8# 9# * Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# * Redistributions in binary form must reproduce the above 12# copyright notice, this list of conditions and the following disclaimer 13# in the documentation and/or other materials provided with the 14# distribution. 15# * Neither the name of Google Inc. nor the names of its 16# contributors may be used to endorse or promote products derived from 17# this software without specific prior written permission. 18# 19# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31"""Unittest for google.protobuf.internal.descriptor.""" 32 33__author__ = 'robinson@google.com (Will Robinson)' 34 35import unittest 36import warnings 37 38from google.protobuf import unittest_custom_options_pb2 39from google.protobuf import unittest_import_pb2 40from google.protobuf import unittest_pb2 41from google.protobuf import descriptor_pb2 42from google.protobuf.internal import api_implementation 43from google.protobuf.internal import test_util 44from google.protobuf import descriptor 45from google.protobuf import descriptor_pool 46from google.protobuf import symbol_database 47from google.protobuf import text_format 48 49 50TEST_EMPTY_MESSAGE_DESCRIPTOR_ASCII = """ 51name: 'TestEmptyMessage' 52""" 53 54TEST_FILE_DESCRIPTOR_DEBUG = """syntax = "proto2"; 55 56package protobuf_unittest; 57 58message NestedMessage { 59 enum ForeignEnum { 60 FOREIGN_FOO = 4; 61 FOREIGN_BAR = 5; 62 FOREIGN_BAZ = 6; 63 } 64 optional int32 bb = 1; 65} 66 67message ResponseMessage { 68} 69 70service Service { 71 rpc CallMethod(.protobuf_unittest.NestedMessage) returns (.protobuf_unittest.ResponseMessage); 72} 73 74""" 75 76 77warnings.simplefilter('error', DeprecationWarning) 78 79 80class DescriptorTest(unittest.TestCase): 81 82 def setUp(self): 83 file_proto = descriptor_pb2.FileDescriptorProto( 84 name='some/filename/some.proto', 85 package='protobuf_unittest') 86 message_proto = file_proto.message_type.add( 87 name='NestedMessage') 88 message_proto.field.add( 89 name='bb', 90 number=1, 91 type=descriptor_pb2.FieldDescriptorProto.TYPE_INT32, 92 label=descriptor_pb2.FieldDescriptorProto.LABEL_OPTIONAL) 93 enum_proto = message_proto.enum_type.add( 94 name='ForeignEnum') 95 enum_proto.value.add(name='FOREIGN_FOO', number=4) 96 enum_proto.value.add(name='FOREIGN_BAR', number=5) 97 enum_proto.value.add(name='FOREIGN_BAZ', number=6) 98 99 file_proto.message_type.add(name='ResponseMessage') 100 service_proto = file_proto.service.add( 101 name='Service') 102 method_proto = service_proto.method.add( 103 name='CallMethod', 104 input_type='.protobuf_unittest.NestedMessage', 105 output_type='.protobuf_unittest.ResponseMessage') 106 107 # Note: Calling DescriptorPool.Add() multiple times with the same file only 108 # works if the input is canonical; in particular, all type names must be 109 # fully qualified. 110 self.pool = self.GetDescriptorPool() 111 self.pool.Add(file_proto) 112 self.my_file = self.pool.FindFileByName(file_proto.name) 113 self.my_message = self.my_file.message_types_by_name[message_proto.name] 114 self.my_enum = self.my_message.enum_types_by_name[enum_proto.name] 115 self.my_service = self.my_file.services_by_name[service_proto.name] 116 self.my_method = self.my_service.methods_by_name[method_proto.name] 117 118 def GetDescriptorPool(self): 119 return symbol_database.Default().pool 120 121 def testEnumValueName(self): 122 self.assertEqual(self.my_message.EnumValueName('ForeignEnum', 4), 123 'FOREIGN_FOO') 124 125 self.assertEqual( 126 self.my_message.enum_types_by_name[ 127 'ForeignEnum'].values_by_number[4].name, 128 self.my_message.EnumValueName('ForeignEnum', 4)) 129 with self.assertRaises(KeyError): 130 self.my_message.EnumValueName('ForeignEnum', 999) 131 with self.assertRaises(KeyError): 132 self.my_message.EnumValueName('NoneEnum', 999) 133 with self.assertRaises(TypeError): 134 self.my_message.EnumValueName() 135 136 def testEnumFixups(self): 137 self.assertEqual(self.my_enum, self.my_enum.values[0].type) 138 139 def testContainingTypeFixups(self): 140 self.assertEqual(self.my_message, self.my_message.fields[0].containing_type) 141 self.assertEqual(self.my_message, self.my_enum.containing_type) 142 143 def testContainingServiceFixups(self): 144 self.assertEqual(self.my_service, self.my_method.containing_service) 145 146 @unittest.skipIf( 147 api_implementation.Type() != 'cpp', 148 'GetDebugString is only available with the cpp implementation', 149 ) 150 def testGetDebugString(self): 151 self.assertEqual(self.my_file.GetDebugString(), TEST_FILE_DESCRIPTOR_DEBUG) 152 153 def testGetOptions(self): 154 self.assertEqual(self.my_enum.GetOptions(), 155 descriptor_pb2.EnumOptions()) 156 self.assertEqual(self.my_enum.values[0].GetOptions(), 157 descriptor_pb2.EnumValueOptions()) 158 self.assertEqual(self.my_message.GetOptions(), 159 descriptor_pb2.MessageOptions()) 160 self.assertEqual(self.my_message.fields[0].GetOptions(), 161 descriptor_pb2.FieldOptions()) 162 self.assertEqual(self.my_method.GetOptions(), 163 descriptor_pb2.MethodOptions()) 164 self.assertEqual(self.my_service.GetOptions(), 165 descriptor_pb2.ServiceOptions()) 166 167 def testSimpleCustomOptions(self): 168 file_descriptor = unittest_custom_options_pb2.DESCRIPTOR 169 message_descriptor = (unittest_custom_options_pb2. 170 TestMessageWithCustomOptions.DESCRIPTOR) 171 field_descriptor = message_descriptor.fields_by_name['field1'] 172 oneof_descriptor = message_descriptor.oneofs_by_name['AnOneof'] 173 enum_descriptor = message_descriptor.enum_types_by_name['AnEnum'] 174 enum_value_descriptor = (message_descriptor. 175 enum_values_by_name['ANENUM_VAL2']) 176 other_enum_value_descriptor = (message_descriptor. 177 enum_values_by_name['ANENUM_VAL1']) 178 service_descriptor = (unittest_custom_options_pb2. 179 TestServiceWithCustomOptions.DESCRIPTOR) 180 method_descriptor = service_descriptor.FindMethodByName('Foo') 181 182 file_options = file_descriptor.GetOptions() 183 file_opt1 = unittest_custom_options_pb2.file_opt1 184 self.assertEqual(9876543210, file_options.Extensions[file_opt1]) 185 message_options = message_descriptor.GetOptions() 186 message_opt1 = unittest_custom_options_pb2.message_opt1 187 self.assertEqual(-56, message_options.Extensions[message_opt1]) 188 field_options = field_descriptor.GetOptions() 189 field_opt1 = unittest_custom_options_pb2.field_opt1 190 self.assertEqual(8765432109, field_options.Extensions[field_opt1]) 191 field_opt2 = unittest_custom_options_pb2.field_opt2 192 self.assertEqual(42, field_options.Extensions[field_opt2]) 193 oneof_options = oneof_descriptor.GetOptions() 194 oneof_opt1 = unittest_custom_options_pb2.oneof_opt1 195 self.assertEqual(-99, oneof_options.Extensions[oneof_opt1]) 196 enum_options = enum_descriptor.GetOptions() 197 enum_opt1 = unittest_custom_options_pb2.enum_opt1 198 self.assertEqual(-789, enum_options.Extensions[enum_opt1]) 199 enum_value_options = enum_value_descriptor.GetOptions() 200 enum_value_opt1 = unittest_custom_options_pb2.enum_value_opt1 201 self.assertEqual(123, enum_value_options.Extensions[enum_value_opt1]) 202 203 service_options = service_descriptor.GetOptions() 204 service_opt1 = unittest_custom_options_pb2.service_opt1 205 self.assertEqual(-9876543210, service_options.Extensions[service_opt1]) 206 method_options = method_descriptor.GetOptions() 207 method_opt1 = unittest_custom_options_pb2.method_opt1 208 self.assertEqual(unittest_custom_options_pb2.METHODOPT1_VAL2, 209 method_options.Extensions[method_opt1]) 210 211 message_descriptor = ( 212 unittest_custom_options_pb2.DummyMessageContainingEnum.DESCRIPTOR) 213 self.assertTrue(file_descriptor.has_options) 214 self.assertFalse(message_descriptor.has_options) 215 self.assertTrue(field_descriptor.has_options) 216 self.assertTrue(oneof_descriptor.has_options) 217 self.assertTrue(enum_descriptor.has_options) 218 self.assertTrue(enum_value_descriptor.has_options) 219 self.assertFalse(other_enum_value_descriptor.has_options) 220 221 def testCustomOptionsCopyTo(self): 222 message_descriptor = (unittest_custom_options_pb2. 223 TestMessageWithCustomOptions.DESCRIPTOR) 224 message_proto = descriptor_pb2.DescriptorProto() 225 message_descriptor.CopyToProto(message_proto) 226 self.assertEqual(len(message_proto.options.ListFields()), 227 2) 228 229 def testDifferentCustomOptionTypes(self): 230 kint32min = -2**31 231 kint64min = -2**63 232 kint32max = 2**31 - 1 233 kint64max = 2**63 - 1 234 kuint32max = 2**32 - 1 235 kuint64max = 2**64 - 1 236 237 message_descriptor =\ 238 unittest_custom_options_pb2.CustomOptionMinIntegerValues.DESCRIPTOR 239 message_options = message_descriptor.GetOptions() 240 self.assertEqual(False, message_options.Extensions[ 241 unittest_custom_options_pb2.bool_opt]) 242 self.assertEqual(kint32min, message_options.Extensions[ 243 unittest_custom_options_pb2.int32_opt]) 244 self.assertEqual(kint64min, message_options.Extensions[ 245 unittest_custom_options_pb2.int64_opt]) 246 self.assertEqual(0, message_options.Extensions[ 247 unittest_custom_options_pb2.uint32_opt]) 248 self.assertEqual(0, message_options.Extensions[ 249 unittest_custom_options_pb2.uint64_opt]) 250 self.assertEqual(kint32min, message_options.Extensions[ 251 unittest_custom_options_pb2.sint32_opt]) 252 self.assertEqual(kint64min, message_options.Extensions[ 253 unittest_custom_options_pb2.sint64_opt]) 254 self.assertEqual(0, message_options.Extensions[ 255 unittest_custom_options_pb2.fixed32_opt]) 256 self.assertEqual(0, message_options.Extensions[ 257 unittest_custom_options_pb2.fixed64_opt]) 258 self.assertEqual(kint32min, message_options.Extensions[ 259 unittest_custom_options_pb2.sfixed32_opt]) 260 self.assertEqual(kint64min, message_options.Extensions[ 261 unittest_custom_options_pb2.sfixed64_opt]) 262 263 message_descriptor =\ 264 unittest_custom_options_pb2.CustomOptionMaxIntegerValues.DESCRIPTOR 265 message_options = message_descriptor.GetOptions() 266 self.assertEqual(True, message_options.Extensions[ 267 unittest_custom_options_pb2.bool_opt]) 268 self.assertEqual(kint32max, message_options.Extensions[ 269 unittest_custom_options_pb2.int32_opt]) 270 self.assertEqual(kint64max, message_options.Extensions[ 271 unittest_custom_options_pb2.int64_opt]) 272 self.assertEqual(kuint32max, message_options.Extensions[ 273 unittest_custom_options_pb2.uint32_opt]) 274 self.assertEqual(kuint64max, message_options.Extensions[ 275 unittest_custom_options_pb2.uint64_opt]) 276 self.assertEqual(kint32max, message_options.Extensions[ 277 unittest_custom_options_pb2.sint32_opt]) 278 self.assertEqual(kint64max, message_options.Extensions[ 279 unittest_custom_options_pb2.sint64_opt]) 280 self.assertEqual(kuint32max, message_options.Extensions[ 281 unittest_custom_options_pb2.fixed32_opt]) 282 self.assertEqual(kuint64max, message_options.Extensions[ 283 unittest_custom_options_pb2.fixed64_opt]) 284 self.assertEqual(kint32max, message_options.Extensions[ 285 unittest_custom_options_pb2.sfixed32_opt]) 286 self.assertEqual(kint64max, message_options.Extensions[ 287 unittest_custom_options_pb2.sfixed64_opt]) 288 289 message_descriptor =\ 290 unittest_custom_options_pb2.CustomOptionOtherValues.DESCRIPTOR 291 message_options = message_descriptor.GetOptions() 292 self.assertEqual(-100, message_options.Extensions[ 293 unittest_custom_options_pb2.int32_opt]) 294 self.assertAlmostEqual(12.3456789, message_options.Extensions[ 295 unittest_custom_options_pb2.float_opt], 6) 296 self.assertAlmostEqual(1.234567890123456789, message_options.Extensions[ 297 unittest_custom_options_pb2.double_opt]) 298 self.assertEqual("Hello, \"World\"", message_options.Extensions[ 299 unittest_custom_options_pb2.string_opt]) 300 self.assertEqual(b"Hello\0World", message_options.Extensions[ 301 unittest_custom_options_pb2.bytes_opt]) 302 dummy_enum = unittest_custom_options_pb2.DummyMessageContainingEnum 303 self.assertEqual( 304 dummy_enum.TEST_OPTION_ENUM_TYPE2, 305 message_options.Extensions[unittest_custom_options_pb2.enum_opt]) 306 307 message_descriptor =\ 308 unittest_custom_options_pb2.SettingRealsFromPositiveInts.DESCRIPTOR 309 message_options = message_descriptor.GetOptions() 310 self.assertAlmostEqual(12, message_options.Extensions[ 311 unittest_custom_options_pb2.float_opt], 6) 312 self.assertAlmostEqual(154, message_options.Extensions[ 313 unittest_custom_options_pb2.double_opt]) 314 315 message_descriptor =\ 316 unittest_custom_options_pb2.SettingRealsFromNegativeInts.DESCRIPTOR 317 message_options = message_descriptor.GetOptions() 318 self.assertAlmostEqual(-12, message_options.Extensions[ 319 unittest_custom_options_pb2.float_opt], 6) 320 self.assertAlmostEqual(-154, message_options.Extensions[ 321 unittest_custom_options_pb2.double_opt]) 322 323 def testComplexExtensionOptions(self): 324 descriptor =\ 325 unittest_custom_options_pb2.VariousComplexOptions.DESCRIPTOR 326 options = descriptor.GetOptions() 327 self.assertEqual(42, options.Extensions[ 328 unittest_custom_options_pb2.complex_opt1].foo) 329 self.assertEqual(324, options.Extensions[ 330 unittest_custom_options_pb2.complex_opt1].Extensions[ 331 unittest_custom_options_pb2.quux]) 332 self.assertEqual(876, options.Extensions[ 333 unittest_custom_options_pb2.complex_opt1].Extensions[ 334 unittest_custom_options_pb2.corge].qux) 335 self.assertEqual(987, options.Extensions[ 336 unittest_custom_options_pb2.complex_opt2].baz) 337 self.assertEqual(654, options.Extensions[ 338 unittest_custom_options_pb2.complex_opt2].Extensions[ 339 unittest_custom_options_pb2.grault]) 340 self.assertEqual(743, options.Extensions[ 341 unittest_custom_options_pb2.complex_opt2].bar.foo) 342 self.assertEqual(1999, options.Extensions[ 343 unittest_custom_options_pb2.complex_opt2].bar.Extensions[ 344 unittest_custom_options_pb2.quux]) 345 self.assertEqual(2008, options.Extensions[ 346 unittest_custom_options_pb2.complex_opt2].bar.Extensions[ 347 unittest_custom_options_pb2.corge].qux) 348 self.assertEqual(741, options.Extensions[ 349 unittest_custom_options_pb2.complex_opt2].Extensions[ 350 unittest_custom_options_pb2.garply].foo) 351 self.assertEqual(1998, options.Extensions[ 352 unittest_custom_options_pb2.complex_opt2].Extensions[ 353 unittest_custom_options_pb2.garply].Extensions[ 354 unittest_custom_options_pb2.quux]) 355 self.assertEqual(2121, options.Extensions[ 356 unittest_custom_options_pb2.complex_opt2].Extensions[ 357 unittest_custom_options_pb2.garply].Extensions[ 358 unittest_custom_options_pb2.corge].qux) 359 self.assertEqual(1971, options.Extensions[ 360 unittest_custom_options_pb2.ComplexOptionType2 361 .ComplexOptionType4.complex_opt4].waldo) 362 self.assertEqual(321, options.Extensions[ 363 unittest_custom_options_pb2.complex_opt2].fred.waldo) 364 self.assertEqual(9, options.Extensions[ 365 unittest_custom_options_pb2.complex_opt3].qux) 366 self.assertEqual(22, options.Extensions[ 367 unittest_custom_options_pb2.complex_opt3].complexoptiontype5.plugh) 368 self.assertEqual(24, options.Extensions[ 369 unittest_custom_options_pb2.complexopt6].xyzzy) 370 371 # Check that aggregate options were parsed and saved correctly in 372 # the appropriate descriptors. 373 def testAggregateOptions(self): 374 file_descriptor = unittest_custom_options_pb2.DESCRIPTOR 375 message_descriptor =\ 376 unittest_custom_options_pb2.AggregateMessage.DESCRIPTOR 377 field_descriptor = message_descriptor.fields_by_name["fieldname"] 378 enum_descriptor = unittest_custom_options_pb2.AggregateEnum.DESCRIPTOR 379 enum_value_descriptor = enum_descriptor.values_by_name["VALUE"] 380 service_descriptor =\ 381 unittest_custom_options_pb2.AggregateService.DESCRIPTOR 382 method_descriptor = service_descriptor.FindMethodByName("Method") 383 384 # Tests for the different types of data embedded in fileopt 385 file_options = file_descriptor.GetOptions().Extensions[ 386 unittest_custom_options_pb2.fileopt] 387 self.assertEqual(100, file_options.i) 388 self.assertEqual("FileAnnotation", file_options.s) 389 self.assertEqual("NestedFileAnnotation", file_options.sub.s) 390 self.assertEqual("FileExtensionAnnotation", file_options.file.Extensions[ 391 unittest_custom_options_pb2.fileopt].s) 392 self.assertEqual("EmbeddedMessageSetElement", file_options.mset.Extensions[ 393 unittest_custom_options_pb2.AggregateMessageSetElement 394 .message_set_extension].s) 395 396 # Simple tests for all the other types of annotations 397 self.assertEqual( 398 "MessageAnnotation", 399 message_descriptor.GetOptions().Extensions[ 400 unittest_custom_options_pb2.msgopt].s) 401 self.assertEqual( 402 "FieldAnnotation", 403 field_descriptor.GetOptions().Extensions[ 404 unittest_custom_options_pb2.fieldopt].s) 405 self.assertEqual( 406 "EnumAnnotation", 407 enum_descriptor.GetOptions().Extensions[ 408 unittest_custom_options_pb2.enumopt].s) 409 self.assertEqual( 410 "EnumValueAnnotation", 411 enum_value_descriptor.GetOptions().Extensions[ 412 unittest_custom_options_pb2.enumvalopt].s) 413 self.assertEqual( 414 "ServiceAnnotation", 415 service_descriptor.GetOptions().Extensions[ 416 unittest_custom_options_pb2.serviceopt].s) 417 self.assertEqual( 418 "MethodAnnotation", 419 method_descriptor.GetOptions().Extensions[ 420 unittest_custom_options_pb2.methodopt].s) 421 422 def testNestedOptions(self): 423 nested_message =\ 424 unittest_custom_options_pb2.NestedOptionType.NestedMessage.DESCRIPTOR 425 self.assertEqual(1001, nested_message.GetOptions().Extensions[ 426 unittest_custom_options_pb2.message_opt1]) 427 nested_field = nested_message.fields_by_name["nested_field"] 428 self.assertEqual(1002, nested_field.GetOptions().Extensions[ 429 unittest_custom_options_pb2.field_opt1]) 430 outer_message =\ 431 unittest_custom_options_pb2.NestedOptionType.DESCRIPTOR 432 nested_enum = outer_message.enum_types_by_name["NestedEnum"] 433 self.assertEqual(1003, nested_enum.GetOptions().Extensions[ 434 unittest_custom_options_pb2.enum_opt1]) 435 nested_enum_value = outer_message.enum_values_by_name["NESTED_ENUM_VALUE"] 436 self.assertEqual(1004, nested_enum_value.GetOptions().Extensions[ 437 unittest_custom_options_pb2.enum_value_opt1]) 438 nested_extension = outer_message.extensions_by_name["nested_extension"] 439 self.assertEqual(1005, nested_extension.GetOptions().Extensions[ 440 unittest_custom_options_pb2.field_opt2]) 441 442 def testFileDescriptorReferences(self): 443 self.assertEqual(self.my_enum.file, self.my_file) 444 self.assertEqual(self.my_message.file, self.my_file) 445 446 def testFileDescriptor(self): 447 self.assertEqual(self.my_file.name, 'some/filename/some.proto') 448 self.assertEqual(self.my_file.package, 'protobuf_unittest') 449 self.assertEqual(self.my_file.pool, self.pool) 450 self.assertFalse(self.my_file.has_options) 451 self.assertEqual('proto2', self.my_file.syntax) 452 file_proto = descriptor_pb2.FileDescriptorProto() 453 self.my_file.CopyToProto(file_proto) 454 self.assertEqual(self.my_file.serialized_pb, 455 file_proto.SerializeToString()) 456 # Generated modules also belong to the default pool. 457 self.assertEqual(unittest_pb2.DESCRIPTOR.pool, descriptor_pool.Default()) 458 459 @unittest.skipIf( 460 api_implementation.Type() != 'cpp' or api_implementation.Version() != 2, 461 'Immutability of descriptors is only enforced in v2 implementation') 462 def testImmutableCppDescriptor(self): 463 file_descriptor = unittest_pb2.DESCRIPTOR 464 message_descriptor = unittest_pb2.TestAllTypes.DESCRIPTOR 465 field_descriptor = message_descriptor.fields_by_name['optional_int32'] 466 enum_descriptor = message_descriptor.enum_types_by_name['NestedEnum'] 467 oneof_descriptor = message_descriptor.oneofs_by_name['oneof_field'] 468 with self.assertRaises(AttributeError): 469 message_descriptor.fields_by_name = None 470 with self.assertRaises(TypeError): 471 message_descriptor.fields_by_name['Another'] = None 472 with self.assertRaises(TypeError): 473 message_descriptor.fields.append(None) 474 with self.assertRaises(AttributeError): 475 field_descriptor.containing_type = message_descriptor 476 with self.assertRaises(AttributeError): 477 file_descriptor.has_options = False 478 with self.assertRaises(AttributeError): 479 field_descriptor.has_options = False 480 with self.assertRaises(AttributeError): 481 oneof_descriptor.has_options = False 482 with self.assertRaises(AttributeError): 483 enum_descriptor.has_options = False 484 with self.assertRaises(AttributeError) as e: 485 message_descriptor.has_options = True 486 self.assertEqual('attribute is not writable: has_options', 487 str(e.exception)) 488 489 def testDefault(self): 490 message_descriptor = unittest_pb2.TestAllTypes.DESCRIPTOR 491 field = message_descriptor.fields_by_name['repeated_int32'] 492 self.assertEqual(field.default_value, []) 493 field = message_descriptor.fields_by_name['repeated_nested_message'] 494 self.assertEqual(field.default_value, []) 495 field = message_descriptor.fields_by_name['optionalgroup'] 496 self.assertEqual(field.default_value, None) 497 field = message_descriptor.fields_by_name['optional_nested_message'] 498 self.assertEqual(field.default_value, None) 499 500 501class NewDescriptorTest(DescriptorTest): 502 """Redo the same tests as above, but with a separate DescriptorPool.""" 503 504 def GetDescriptorPool(self): 505 return descriptor_pool.DescriptorPool() 506 507 508class GeneratedDescriptorTest(unittest.TestCase): 509 """Tests for the properties of descriptors in generated code.""" 510 511 def CheckMessageDescriptor(self, message_descriptor): 512 # Basic properties 513 self.assertEqual(message_descriptor.name, 'TestAllTypes') 514 self.assertEqual(message_descriptor.full_name, 515 'protobuf_unittest.TestAllTypes') 516 # Test equality and hashability 517 self.assertEqual(message_descriptor, message_descriptor) 518 self.assertEqual(message_descriptor.fields[0].containing_type, 519 message_descriptor) 520 self.assertIn(message_descriptor, [message_descriptor]) 521 self.assertIn(message_descriptor, {message_descriptor: None}) 522 # Test field containers 523 self.CheckDescriptorSequence(message_descriptor.fields) 524 self.CheckDescriptorMapping(message_descriptor.fields_by_name) 525 self.CheckDescriptorMapping(message_descriptor.fields_by_number) 526 self.CheckDescriptorMapping(message_descriptor.fields_by_camelcase_name) 527 self.CheckDescriptorMapping(message_descriptor.enum_types_by_name) 528 self.CheckDescriptorMapping(message_descriptor.enum_values_by_name) 529 self.CheckDescriptorMapping(message_descriptor.oneofs_by_name) 530 self.CheckDescriptorMapping(message_descriptor.enum_types[0].values_by_name) 531 # Test extension range 532 self.assertEqual(message_descriptor.extension_ranges, []) 533 534 def CheckFieldDescriptor(self, field_descriptor): 535 # Basic properties 536 self.assertEqual(field_descriptor.name, 'optional_int32') 537 self.assertEqual(field_descriptor.camelcase_name, 'optionalInt32') 538 self.assertEqual(field_descriptor.full_name, 539 'protobuf_unittest.TestAllTypes.optional_int32') 540 self.assertEqual(field_descriptor.containing_type.name, 'TestAllTypes') 541 self.assertEqual(field_descriptor.file, unittest_pb2.DESCRIPTOR) 542 # Test equality and hashability 543 self.assertEqual(field_descriptor, field_descriptor) 544 self.assertEqual( 545 field_descriptor.containing_type.fields_by_name['optional_int32'], 546 field_descriptor) 547 self.assertEqual( 548 field_descriptor.containing_type.fields_by_camelcase_name[ 549 'optionalInt32'], 550 field_descriptor) 551 self.assertIn(field_descriptor, [field_descriptor]) 552 self.assertIn(field_descriptor, {field_descriptor: None}) 553 self.assertEqual(None, field_descriptor.extension_scope) 554 self.assertEqual(None, field_descriptor.enum_type) 555 self.assertTrue(field_descriptor.has_presence) 556 if api_implementation.Type() == 'cpp': 557 # For test coverage only 558 self.assertEqual(field_descriptor.id, field_descriptor.id) 559 560 def CheckDescriptorSequence(self, sequence): 561 # Verifies that a property like 'messageDescriptor.fields' has all the 562 # properties of an immutable abc.Sequence. 563 self.assertNotEqual(sequence, 564 unittest_pb2.TestAllExtensions.DESCRIPTOR.fields) 565 self.assertNotEqual(sequence, []) 566 self.assertNotEqual(sequence, 1) 567 self.assertFalse(sequence == 1) # Only for cpp test coverage 568 self.assertEqual(sequence, sequence) 569 expected_list = list(sequence) 570 self.assertEqual(expected_list, sequence) 571 self.assertGreater(len(sequence), 0) # Sized 572 self.assertEqual(len(sequence), len(expected_list)) # Iterable 573 self.assertEqual(sequence[len(sequence) -1], sequence[-1]) 574 item = sequence[0] 575 self.assertEqual(item, sequence[0]) 576 self.assertIn(item, sequence) # Container 577 self.assertEqual(sequence.index(item), 0) 578 self.assertEqual(sequence.count(item), 1) 579 other_item = unittest_pb2.NestedTestAllTypes.DESCRIPTOR.fields[0] 580 self.assertNotIn(other_item, sequence) 581 self.assertEqual(sequence.count(other_item), 0) 582 self.assertRaises(ValueError, sequence.index, other_item) 583 self.assertRaises(ValueError, sequence.index, []) 584 reversed_iterator = reversed(sequence) 585 self.assertEqual(list(reversed_iterator), list(sequence)[::-1]) 586 self.assertRaises(StopIteration, next, reversed_iterator) 587 expected_list[0] = 'change value' 588 self.assertNotEqual(expected_list, sequence) 589 # TODO(jieluo): Change __repr__ support for DescriptorSequence. 590 if api_implementation.Type() == 'python': 591 self.assertEqual(str(list(sequence)), str(sequence)) 592 else: 593 self.assertEqual(str(sequence)[0], '<') 594 595 def CheckDescriptorMapping(self, mapping): 596 # Verifies that a property like 'messageDescriptor.fields' has all the 597 # properties of an immutable abc.Mapping. 598 self.assertNotEqual( 599 mapping, unittest_pb2.TestAllExtensions.DESCRIPTOR.fields_by_name) 600 self.assertNotEqual(mapping, {}) 601 self.assertNotEqual(mapping, 1) 602 self.assertFalse(mapping == 1) # Only for cpp test coverage 603 excepted_dict = dict(mapping.items()) 604 self.assertEqual(mapping, excepted_dict) 605 self.assertEqual(mapping, mapping) 606 self.assertGreater(len(mapping), 0) # Sized 607 self.assertEqual(len(mapping), len(excepted_dict)) # Iterable 608 key, item = next(iter(mapping.items())) 609 self.assertIn(key, mapping) # Container 610 self.assertEqual(mapping.get(key), item) 611 with self.assertRaises(TypeError): 612 mapping.get() 613 # TODO(jieluo): Fix python and cpp extension diff. 614 if api_implementation.Type() == 'python': 615 self.assertRaises(TypeError, mapping.get, []) 616 else: 617 self.assertEqual(None, mapping.get([])) 618 # keys(), iterkeys() &co 619 item = (next(iter(mapping.keys())), next(iter(mapping.values()))) 620 self.assertEqual(item, next(iter(mapping.items()))) 621 excepted_dict[key] = 'change value' 622 self.assertNotEqual(mapping, excepted_dict) 623 del excepted_dict[key] 624 excepted_dict['new_key'] = 'new' 625 self.assertNotEqual(mapping, excepted_dict) 626 self.assertRaises(KeyError, mapping.__getitem__, 'key_error') 627 self.assertRaises(KeyError, mapping.__getitem__, len(mapping) + 1) 628 # TODO(jieluo): Add __repr__ support for DescriptorMapping. 629 if api_implementation.Type() == 'python': 630 self.assertEqual(len(str(dict(mapping.items()))), len(str(mapping))) 631 else: 632 self.assertEqual(str(mapping)[0], '<') 633 634 def testDescriptor(self): 635 message_descriptor = unittest_pb2.TestAllTypes.DESCRIPTOR 636 self.CheckMessageDescriptor(message_descriptor) 637 field_descriptor = message_descriptor.fields_by_name['optional_int32'] 638 self.CheckFieldDescriptor(field_descriptor) 639 field_descriptor = message_descriptor.fields_by_camelcase_name[ 640 'optionalInt32'] 641 self.CheckFieldDescriptor(field_descriptor) 642 enum_descriptor = unittest_pb2.DESCRIPTOR.enum_types_by_name[ 643 'ForeignEnum'] 644 self.assertEqual(None, enum_descriptor.containing_type) 645 # Test extension range 646 self.assertEqual( 647 unittest_pb2.TestAllExtensions.DESCRIPTOR.extension_ranges, 648 [(1, 536870912)]) 649 self.assertEqual( 650 unittest_pb2.TestMultipleExtensionRanges.DESCRIPTOR.extension_ranges, 651 [(42, 43), (4143, 4244), (65536, 536870912)]) 652 653 def testCppDescriptorContainer(self): 654 containing_file = unittest_pb2.DESCRIPTOR 655 self.CheckDescriptorSequence(containing_file.dependencies) 656 self.CheckDescriptorMapping(containing_file.message_types_by_name) 657 self.CheckDescriptorMapping(containing_file.enum_types_by_name) 658 self.CheckDescriptorMapping(containing_file.services_by_name) 659 self.CheckDescriptorMapping(containing_file.extensions_by_name) 660 self.CheckDescriptorMapping( 661 unittest_pb2.TestNestedExtension.DESCRIPTOR.extensions_by_name) 662 663 def testCppDescriptorContainer_Iterator(self): 664 # Same test with the iterator 665 enum = unittest_pb2.TestAllTypes.DESCRIPTOR.enum_types_by_name['NestedEnum'] 666 values_iter = iter(enum.values) 667 del enum 668 self.assertEqual('FOO', next(values_iter).name) 669 670 def testDescriptorNestedTypesContainer(self): 671 message_descriptor = unittest_pb2.TestAllTypes.DESCRIPTOR 672 nested_message_descriptor = unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR 673 self.assertEqual(len(message_descriptor.nested_types), 3) 674 self.assertFalse(None in message_descriptor.nested_types) 675 self.assertTrue( 676 nested_message_descriptor in message_descriptor.nested_types) 677 678 def testServiceDescriptor(self): 679 service_descriptor = unittest_pb2.DESCRIPTOR.services_by_name['TestService'] 680 self.assertEqual(service_descriptor.name, 'TestService') 681 self.assertEqual(service_descriptor.methods[0].name, 'Foo') 682 self.assertIs(service_descriptor.file, unittest_pb2.DESCRIPTOR) 683 self.assertEqual(service_descriptor.index, 0) 684 self.CheckDescriptorMapping(service_descriptor.methods_by_name) 685 686 def testOneofDescriptor(self): 687 message_descriptor = unittest_pb2.TestAllTypes.DESCRIPTOR 688 oneof_descriptor = message_descriptor.oneofs_by_name['oneof_field'] 689 self.assertFalse(oneof_descriptor.has_options) 690 self.assertEqual(message_descriptor, oneof_descriptor.containing_type) 691 self.assertEqual('oneof_field', oneof_descriptor.name) 692 self.assertEqual('protobuf_unittest.TestAllTypes.oneof_field', 693 oneof_descriptor.full_name) 694 self.assertEqual(0, oneof_descriptor.index) 695 696 697class DescriptorCopyToProtoTest(unittest.TestCase): 698 """Tests for CopyTo functions of Descriptor.""" 699 700 def _AssertProtoEqual(self, actual_proto, expected_class, expected_ascii): 701 expected_proto = expected_class() 702 text_format.Merge(expected_ascii, expected_proto) 703 704 self.assertEqual( 705 actual_proto, expected_proto, 706 'Not equal,\nActual:\n%s\nExpected:\n%s\n' 707 % (str(actual_proto), str(expected_proto))) 708 709 def _InternalTestCopyToProto(self, desc, expected_proto_class, 710 expected_proto_ascii): 711 actual = expected_proto_class() 712 desc.CopyToProto(actual) 713 self._AssertProtoEqual( 714 actual, expected_proto_class, expected_proto_ascii) 715 716 def testCopyToProto_EmptyMessage(self): 717 self._InternalTestCopyToProto( 718 unittest_pb2.TestEmptyMessage.DESCRIPTOR, 719 descriptor_pb2.DescriptorProto, 720 TEST_EMPTY_MESSAGE_DESCRIPTOR_ASCII) 721 722 def testCopyToProto_NestedMessage(self): 723 TEST_NESTED_MESSAGE_ASCII = """ 724 name: 'NestedMessage' 725 field: < 726 name: 'bb' 727 number: 1 728 label: 1 # Optional 729 type: 5 # TYPE_INT32 730 > 731 """ 732 733 self._InternalTestCopyToProto( 734 unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR, 735 descriptor_pb2.DescriptorProto, 736 TEST_NESTED_MESSAGE_ASCII) 737 738 def testCopyToProto_ForeignNestedMessage(self): 739 TEST_FOREIGN_NESTED_ASCII = """ 740 name: 'TestForeignNested' 741 field: < 742 name: 'foreign_nested' 743 number: 1 744 label: 1 # Optional 745 type: 11 # TYPE_MESSAGE 746 type_name: '.protobuf_unittest.TestAllTypes.NestedMessage' 747 > 748 """ 749 750 self._InternalTestCopyToProto( 751 unittest_pb2.TestForeignNested.DESCRIPTOR, 752 descriptor_pb2.DescriptorProto, 753 TEST_FOREIGN_NESTED_ASCII) 754 755 def testCopyToProto_ForeignEnum(self): 756 TEST_FOREIGN_ENUM_ASCII = """ 757 name: 'ForeignEnum' 758 value: < 759 name: 'FOREIGN_FOO' 760 number: 4 761 > 762 value: < 763 name: 'FOREIGN_BAR' 764 number: 5 765 > 766 value: < 767 name: 'FOREIGN_BAZ' 768 number: 6 769 > 770 """ 771 772 self._InternalTestCopyToProto( 773 unittest_pb2.ForeignEnum.DESCRIPTOR, 774 descriptor_pb2.EnumDescriptorProto, 775 TEST_FOREIGN_ENUM_ASCII) 776 777 def testCopyToProto_Options(self): 778 TEST_DEPRECATED_FIELDS_ASCII = """ 779 name: 'TestDeprecatedFields' 780 field: < 781 name: 'deprecated_int32' 782 number: 1 783 label: 1 # Optional 784 type: 5 # TYPE_INT32 785 options: < 786 deprecated: true 787 > 788 > 789 field { 790 name: "deprecated_int32_in_oneof" 791 number: 2 792 label: LABEL_OPTIONAL 793 type: TYPE_INT32 794 options { 795 deprecated: true 796 } 797 oneof_index: 0 798 } 799 oneof_decl { 800 name: "oneof_fields" 801 } 802 """ 803 804 self._InternalTestCopyToProto( 805 unittest_pb2.TestDeprecatedFields.DESCRIPTOR, 806 descriptor_pb2.DescriptorProto, 807 TEST_DEPRECATED_FIELDS_ASCII) 808 809 def testCopyToProto_AllExtensions(self): 810 TEST_EMPTY_MESSAGE_WITH_EXTENSIONS_ASCII = """ 811 name: 'TestEmptyMessageWithExtensions' 812 extension_range: < 813 start: 1 814 end: 536870912 815 > 816 """ 817 818 self._InternalTestCopyToProto( 819 unittest_pb2.TestEmptyMessageWithExtensions.DESCRIPTOR, 820 descriptor_pb2.DescriptorProto, 821 TEST_EMPTY_MESSAGE_WITH_EXTENSIONS_ASCII) 822 823 def testCopyToProto_SeveralExtensions(self): 824 TEST_MESSAGE_WITH_SEVERAL_EXTENSIONS_ASCII = """ 825 name: 'TestMultipleExtensionRanges' 826 extension_range: < 827 start: 42 828 end: 43 829 > 830 extension_range: < 831 start: 4143 832 end: 4244 833 > 834 extension_range: < 835 start: 65536 836 end: 536870912 837 > 838 """ 839 840 self._InternalTestCopyToProto( 841 unittest_pb2.TestMultipleExtensionRanges.DESCRIPTOR, 842 descriptor_pb2.DescriptorProto, 843 TEST_MESSAGE_WITH_SEVERAL_EXTENSIONS_ASCII) 844 845 def testCopyToProto_FileDescriptor(self): 846 UNITTEST_IMPORT_FILE_DESCRIPTOR_ASCII = (""" 847 name: 'google/protobuf/unittest_import.proto' 848 package: 'protobuf_unittest_import' 849 dependency: 'google/protobuf/unittest_import_public.proto' 850 message_type: < 851 name: 'ImportMessage' 852 field: < 853 name: 'd' 854 number: 1 855 label: 1 # Optional 856 type: 5 # TYPE_INT32 857 > 858 > 859 """ + 860 """enum_type: < 861 name: 'ImportEnum' 862 value: < 863 name: 'IMPORT_FOO' 864 number: 7 865 > 866 value: < 867 name: 'IMPORT_BAR' 868 number: 8 869 > 870 value: < 871 name: 'IMPORT_BAZ' 872 number: 9 873 > 874 > 875 enum_type: < 876 name: 'ImportEnumForMap' 877 value: < 878 name: 'UNKNOWN' 879 number: 0 880 > 881 value: < 882 name: 'FOO' 883 number: 1 884 > 885 value: < 886 name: 'BAR' 887 number: 2 888 > 889 > 890 options: < 891 java_package: 'com.google.protobuf.test' 892 optimize_for: 1 # SPEED 893 """ + 894 """ 895 cc_enable_arenas: true 896 > 897 public_dependency: 0 898 """) 899 self._InternalTestCopyToProto( 900 unittest_import_pb2.DESCRIPTOR, 901 descriptor_pb2.FileDescriptorProto, 902 UNITTEST_IMPORT_FILE_DESCRIPTOR_ASCII) 903 904 def testCopyToProto_ServiceDescriptor(self): 905 TEST_SERVICE_ASCII = """ 906 name: 'TestService' 907 method: < 908 name: 'Foo' 909 input_type: '.protobuf_unittest.FooRequest' 910 output_type: '.protobuf_unittest.FooResponse' 911 > 912 method: < 913 name: 'Bar' 914 input_type: '.protobuf_unittest.BarRequest' 915 output_type: '.protobuf_unittest.BarResponse' 916 > 917 """ 918 self._InternalTestCopyToProto( 919 unittest_pb2.TestService.DESCRIPTOR, 920 descriptor_pb2.ServiceDescriptorProto, 921 TEST_SERVICE_ASCII) 922 923 def testCopyToProto_MethodDescriptor(self): 924 expected_ascii = """ 925 name: 'Foo' 926 input_type: '.protobuf_unittest.FooRequest' 927 output_type: '.protobuf_unittest.FooResponse' 928 """ 929 method_descriptor = unittest_pb2.TestService.DESCRIPTOR.FindMethodByName( 930 'Foo') 931 self._InternalTestCopyToProto( 932 method_descriptor, 933 descriptor_pb2.MethodDescriptorProto, 934 expected_ascii) 935 936 @unittest.skipIf( 937 api_implementation.Type() == 'python', 938 'Pure python does not raise error.') 939 # TODO(jieluo): Fix pure python to check with the proto type. 940 def testCopyToProto_TypeError(self): 941 file_proto = descriptor_pb2.FileDescriptorProto() 942 self.assertRaises(TypeError, 943 unittest_pb2.TestEmptyMessage.DESCRIPTOR.CopyToProto, 944 file_proto) 945 self.assertRaises(TypeError, 946 unittest_pb2.ForeignEnum.DESCRIPTOR.CopyToProto, 947 file_proto) 948 self.assertRaises(TypeError, 949 unittest_pb2.TestService.DESCRIPTOR.CopyToProto, 950 file_proto) 951 proto = descriptor_pb2.DescriptorProto() 952 self.assertRaises(TypeError, 953 unittest_import_pb2.DESCRIPTOR.CopyToProto, 954 proto) 955 956 957class MakeDescriptorTest(unittest.TestCase): 958 959 def testMakeDescriptorWithNestedFields(self): 960 file_descriptor_proto = descriptor_pb2.FileDescriptorProto() 961 file_descriptor_proto.name = 'Foo2' 962 message_type = file_descriptor_proto.message_type.add() 963 message_type.name = file_descriptor_proto.name 964 nested_type = message_type.nested_type.add() 965 nested_type.name = 'Sub' 966 enum_type = nested_type.enum_type.add() 967 enum_type.name = 'FOO' 968 enum_type_val = enum_type.value.add() 969 enum_type_val.name = 'BAR' 970 enum_type_val.number = 3 971 field = message_type.field.add() 972 field.number = 1 973 field.name = 'uint64_field' 974 field.label = descriptor.FieldDescriptor.LABEL_REQUIRED 975 field.type = descriptor.FieldDescriptor.TYPE_UINT64 976 field = message_type.field.add() 977 field.number = 2 978 field.name = 'nested_message_field' 979 field.label = descriptor.FieldDescriptor.LABEL_REQUIRED 980 field.type = descriptor.FieldDescriptor.TYPE_MESSAGE 981 field.type_name = 'Sub' 982 enum_field = nested_type.field.add() 983 enum_field.number = 2 984 enum_field.name = 'bar_field' 985 enum_field.label = descriptor.FieldDescriptor.LABEL_REQUIRED 986 enum_field.type = descriptor.FieldDescriptor.TYPE_ENUM 987 enum_field.type_name = 'Foo2.Sub.FOO' 988 989 result = descriptor.MakeDescriptor(message_type) 990 self.assertEqual(result.fields[0].cpp_type, 991 descriptor.FieldDescriptor.CPPTYPE_UINT64) 992 self.assertEqual(result.fields[1].cpp_type, 993 descriptor.FieldDescriptor.CPPTYPE_MESSAGE) 994 self.assertEqual(result.fields[1].message_type.containing_type, 995 result) 996 self.assertEqual(result.nested_types[0].fields[0].full_name, 997 'Foo2.Sub.bar_field') 998 self.assertEqual(result.nested_types[0].fields[0].enum_type, 999 result.nested_types[0].enum_types[0]) 1000 self.assertFalse(result.has_options) 1001 self.assertFalse(result.fields[0].has_options) 1002 if api_implementation.Type() == 'cpp': 1003 with self.assertRaises(AttributeError): 1004 result.fields[0].has_options = False 1005 1006 def testMakeDescriptorWithUnsignedIntField(self): 1007 file_descriptor_proto = descriptor_pb2.FileDescriptorProto() 1008 file_descriptor_proto.name = 'Foo' 1009 message_type = file_descriptor_proto.message_type.add() 1010 message_type.name = file_descriptor_proto.name 1011 enum_type = message_type.enum_type.add() 1012 enum_type.name = 'FOO' 1013 enum_type_val = enum_type.value.add() 1014 enum_type_val.name = 'BAR' 1015 enum_type_val.number = 3 1016 field = message_type.field.add() 1017 field.number = 1 1018 field.name = 'uint64_field' 1019 field.label = descriptor.FieldDescriptor.LABEL_REQUIRED 1020 field.type = descriptor.FieldDescriptor.TYPE_UINT64 1021 enum_field = message_type.field.add() 1022 enum_field.number = 2 1023 enum_field.name = 'bar_field' 1024 enum_field.label = descriptor.FieldDescriptor.LABEL_REQUIRED 1025 enum_field.type = descriptor.FieldDescriptor.TYPE_ENUM 1026 enum_field.type_name = 'Foo.FOO' 1027 1028 result = descriptor.MakeDescriptor(message_type) 1029 self.assertEqual(result.fields[0].cpp_type, 1030 descriptor.FieldDescriptor.CPPTYPE_UINT64) 1031 1032 1033 def testMakeDescriptorWithOptions(self): 1034 descriptor_proto = descriptor_pb2.DescriptorProto() 1035 aggregate_message = unittest_custom_options_pb2.AggregateMessage 1036 aggregate_message.DESCRIPTOR.CopyToProto(descriptor_proto) 1037 reformed_descriptor = descriptor.MakeDescriptor(descriptor_proto) 1038 1039 options = reformed_descriptor.GetOptions() 1040 self.assertEqual(101, 1041 options.Extensions[unittest_custom_options_pb2.msgopt].i) 1042 1043 def testCamelcaseName(self): 1044 descriptor_proto = descriptor_pb2.DescriptorProto() 1045 descriptor_proto.name = 'Bar' 1046 names = ['foo_foo', 'FooBar', 'fooBaz', 'fooFoo', 'foobar'] 1047 camelcase_names = ['fooFoo', 'fooBar', 'fooBaz', 'fooFoo', 'foobar'] 1048 for index in range(len(names)): 1049 field = descriptor_proto.field.add() 1050 field.number = index + 1 1051 field.name = names[index] 1052 result = descriptor.MakeDescriptor(descriptor_proto) 1053 for index in range(len(camelcase_names)): 1054 self.assertEqual(result.fields[index].camelcase_name, 1055 camelcase_names[index]) 1056 1057 def testJsonName(self): 1058 descriptor_proto = descriptor_pb2.DescriptorProto() 1059 descriptor_proto.name = 'TestJsonName' 1060 names = ['field_name', 'fieldName', 'FieldName', 1061 '_field_name', 'FIELD_NAME', 'json_name'] 1062 json_names = ['fieldName', 'fieldName', 'FieldName', 1063 'FieldName', 'FIELDNAME', '@type'] 1064 for index in range(len(names)): 1065 field = descriptor_proto.field.add() 1066 field.number = index + 1 1067 field.name = names[index] 1068 field.json_name = '@type' 1069 result = descriptor.MakeDescriptor(descriptor_proto) 1070 for index in range(len(json_names)): 1071 self.assertEqual(result.fields[index].json_name, 1072 json_names[index]) 1073 1074 1075if __name__ == '__main__': 1076 unittest.main() 1077