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