aboutsummaryrefslogtreecommitdiff
path: root/python/google/protobuf/internal/descriptor_test.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/google/protobuf/internal/descriptor_test.py')
-rwxr-xr-xpython/google/protobuf/internal/descriptor_test.py381
1 files changed, 298 insertions, 83 deletions
diff --git a/python/google/protobuf/internal/descriptor_test.py b/python/google/protobuf/internal/descriptor_test.py
index fee09a56..02a43d15 100755
--- a/python/google/protobuf/internal/descriptor_test.py
+++ b/python/google/protobuf/internal/descriptor_test.py
@@ -37,9 +37,10 @@ __author__ = 'robinson@google.com (Will Robinson)'
import sys
try:
- import unittest2 as unittest
+ import unittest2 as unittest #PY26
except ImportError:
import unittest
+
from google.protobuf import unittest_custom_options_pb2
from google.protobuf import unittest_import_pb2
from google.protobuf import unittest_pb2
@@ -76,27 +77,24 @@ class DescriptorTest(unittest.TestCase):
enum_proto.value.add(name='FOREIGN_BAR', number=5)
enum_proto.value.add(name='FOREIGN_BAZ', number=6)
+ file_proto.message_type.add(name='ResponseMessage')
+ service_proto = file_proto.service.add(
+ name='Service')
+ method_proto = service_proto.method.add(
+ name='CallMethod',
+ input_type='.protobuf_unittest.NestedMessage',
+ output_type='.protobuf_unittest.ResponseMessage')
+
+ # Note: Calling DescriptorPool.Add() multiple times with the same file only
+ # works if the input is canonical; in particular, all type names must be
+ # fully qualified.
self.pool = self.GetDescriptorPool()
self.pool.Add(file_proto)
self.my_file = self.pool.FindFileByName(file_proto.name)
self.my_message = self.my_file.message_types_by_name[message_proto.name]
self.my_enum = self.my_message.enum_types_by_name[enum_proto.name]
-
- self.my_method = descriptor.MethodDescriptor(
- name='Bar',
- full_name='protobuf_unittest.TestService.Bar',
- index=0,
- containing_service=None,
- input_type=None,
- output_type=None)
- self.my_service = descriptor.ServiceDescriptor(
- name='TestServiceWithOptions',
- full_name='protobuf_unittest.TestServiceWithOptions',
- file=self.my_file,
- index=0,
- methods=[
- self.my_method
- ])
+ self.my_service = self.my_file.services_by_name[service_proto.name]
+ self.my_method = self.my_service.methods_by_name[method_proto.name]
def GetDescriptorPool(self):
return symbol_database.Default().pool
@@ -109,6 +107,12 @@ class DescriptorTest(unittest.TestCase):
self.my_message.enum_types_by_name[
'ForeignEnum'].values_by_number[4].name,
self.my_message.EnumValueName('ForeignEnum', 4))
+ with self.assertRaises(KeyError):
+ self.my_message.EnumValueName('ForeignEnum', 999)
+ with self.assertRaises(KeyError):
+ self.my_message.EnumValueName('NoneEnum', 999)
+ with self.assertRaises(TypeError):
+ self.my_message.EnumValueName()
def testEnumFixups(self):
self.assertEqual(self.my_enum, self.my_enum.values[0].type)
@@ -136,15 +140,18 @@ class DescriptorTest(unittest.TestCase):
def testSimpleCustomOptions(self):
file_descriptor = unittest_custom_options_pb2.DESCRIPTOR
- message_descriptor =\
- unittest_custom_options_pb2.TestMessageWithCustomOptions.DESCRIPTOR
- field_descriptor = message_descriptor.fields_by_name["field1"]
- enum_descriptor = message_descriptor.enum_types_by_name["AnEnum"]
- enum_value_descriptor =\
- message_descriptor.enum_values_by_name["ANENUM_VAL2"]
- service_descriptor =\
- unittest_custom_options_pb2.TestServiceWithCustomOptions.DESCRIPTOR
- method_descriptor = service_descriptor.FindMethodByName("Foo")
+ message_descriptor = (unittest_custom_options_pb2.
+ TestMessageWithCustomOptions.DESCRIPTOR)
+ field_descriptor = message_descriptor.fields_by_name['field1']
+ oneof_descriptor = message_descriptor.oneofs_by_name['AnOneof']
+ enum_descriptor = message_descriptor.enum_types_by_name['AnEnum']
+ enum_value_descriptor = (message_descriptor.
+ enum_values_by_name['ANENUM_VAL2'])
+ other_enum_value_descriptor = (message_descriptor.
+ enum_values_by_name['ANENUM_VAL1'])
+ service_descriptor = (unittest_custom_options_pb2.
+ TestServiceWithCustomOptions.DESCRIPTOR)
+ method_descriptor = service_descriptor.FindMethodByName('Foo')
file_options = file_descriptor.GetOptions()
file_opt1 = unittest_custom_options_pb2.file_opt1
@@ -157,6 +164,9 @@ class DescriptorTest(unittest.TestCase):
self.assertEqual(8765432109, field_options.Extensions[field_opt1])
field_opt2 = unittest_custom_options_pb2.field_opt2
self.assertEqual(42, field_options.Extensions[field_opt2])
+ oneof_options = oneof_descriptor.GetOptions()
+ oneof_opt1 = unittest_custom_options_pb2.oneof_opt1
+ self.assertEqual(-99, oneof_options.Extensions[oneof_opt1])
enum_options = enum_descriptor.GetOptions()
enum_opt1 = unittest_custom_options_pb2.enum_opt1
self.assertEqual(-789, enum_options.Extensions[enum_opt1])
@@ -176,6 +186,11 @@ class DescriptorTest(unittest.TestCase):
unittest_custom_options_pb2.DummyMessageContainingEnum.DESCRIPTOR)
self.assertTrue(file_descriptor.has_options)
self.assertFalse(message_descriptor.has_options)
+ self.assertTrue(field_descriptor.has_options)
+ self.assertTrue(oneof_descriptor.has_options)
+ self.assertTrue(enum_descriptor.has_options)
+ self.assertTrue(enum_value_descriptor.has_options)
+ self.assertFalse(other_enum_value_descriptor.has_options)
def testDifferentCustomOptionTypes(self):
kint32min = -2**31
@@ -398,6 +413,12 @@ class DescriptorTest(unittest.TestCase):
self.assertEqual(self.my_file.name, 'some/filename/some.proto')
self.assertEqual(self.my_file.package, 'protobuf_unittest')
self.assertEqual(self.my_file.pool, self.pool)
+ self.assertFalse(self.my_file.has_options)
+ self.assertEqual('proto2', self.my_file.syntax)
+ file_proto = descriptor_pb2.FileDescriptorProto()
+ self.my_file.CopyToProto(file_proto)
+ self.assertEqual(self.my_file.serialized_pb,
+ file_proto.SerializeToString())
# Generated modules also belong to the default pool.
self.assertEqual(unittest_pb2.DESCRIPTOR.pool, descriptor_pool.Default())
@@ -405,13 +426,31 @@ class DescriptorTest(unittest.TestCase):
api_implementation.Type() != 'cpp' or api_implementation.Version() != 2,
'Immutability of descriptors is only enforced in v2 implementation')
def testImmutableCppDescriptor(self):
+ file_descriptor = unittest_pb2.DESCRIPTOR
message_descriptor = unittest_pb2.TestAllTypes.DESCRIPTOR
+ field_descriptor = message_descriptor.fields_by_name['optional_int32']
+ enum_descriptor = message_descriptor.enum_types_by_name['NestedEnum']
+ oneof_descriptor = message_descriptor.oneofs_by_name['oneof_field']
with self.assertRaises(AttributeError):
message_descriptor.fields_by_name = None
with self.assertRaises(TypeError):
message_descriptor.fields_by_name['Another'] = None
with self.assertRaises(TypeError):
message_descriptor.fields.append(None)
+ with self.assertRaises(AttributeError):
+ field_descriptor.containing_type = message_descriptor
+ with self.assertRaises(AttributeError):
+ file_descriptor.has_options = False
+ with self.assertRaises(AttributeError):
+ field_descriptor.has_options = False
+ with self.assertRaises(AttributeError):
+ oneof_descriptor.has_options = False
+ with self.assertRaises(AttributeError):
+ enum_descriptor.has_options = False
+ with self.assertRaises(AttributeError) as e:
+ message_descriptor.has_options = True
+ self.assertEqual('attribute is not writable: has_options',
+ str(e.exception))
class NewDescriptorTest(DescriptorTest):
@@ -440,6 +479,12 @@ class GeneratedDescriptorTest(unittest.TestCase):
self.CheckDescriptorMapping(message_descriptor.fields_by_name)
self.CheckDescriptorMapping(message_descriptor.fields_by_number)
self.CheckDescriptorMapping(message_descriptor.fields_by_camelcase_name)
+ self.CheckDescriptorMapping(message_descriptor.enum_types_by_name)
+ self.CheckDescriptorMapping(message_descriptor.enum_values_by_name)
+ self.CheckDescriptorMapping(message_descriptor.oneofs_by_name)
+ self.CheckDescriptorMapping(message_descriptor.enum_types[0].values_by_name)
+ # Test extension range
+ self.assertEqual(message_descriptor.extension_ranges, [])
def CheckFieldDescriptor(self, field_descriptor):
# Basic properties
@@ -448,6 +493,7 @@ class GeneratedDescriptorTest(unittest.TestCase):
self.assertEqual(field_descriptor.full_name,
'protobuf_unittest.TestAllTypes.optional_int32')
self.assertEqual(field_descriptor.containing_type.name, 'TestAllTypes')
+ self.assertEqual(field_descriptor.file, unittest_pb2.DESCRIPTOR)
# Test equality and hashability
self.assertEqual(field_descriptor, field_descriptor)
self.assertEqual(
@@ -459,32 +505,73 @@ class GeneratedDescriptorTest(unittest.TestCase):
field_descriptor)
self.assertIn(field_descriptor, [field_descriptor])
self.assertIn(field_descriptor, {field_descriptor: None})
+ self.assertEqual(None, field_descriptor.extension_scope)
+ self.assertEqual(None, field_descriptor.enum_type)
+ if api_implementation.Type() == 'cpp':
+ # For test coverage only
+ self.assertEqual(field_descriptor.id, field_descriptor.id)
def CheckDescriptorSequence(self, sequence):
# Verifies that a property like 'messageDescriptor.fields' has all the
# properties of an immutable abc.Sequence.
+ self.assertNotEqual(sequence,
+ unittest_pb2.TestAllExtensions.DESCRIPTOR.fields)
+ self.assertNotEqual(sequence, [])
+ self.assertNotEqual(sequence, 1)
+ self.assertFalse(sequence == 1) # Only for cpp test coverage
+ self.assertEqual(sequence, sequence)
+ expected_list = list(sequence)
+ self.assertEqual(expected_list, sequence)
self.assertGreater(len(sequence), 0) # Sized
- self.assertEqual(len(sequence), len(list(sequence))) # Iterable
+ self.assertEqual(len(sequence), len(expected_list)) # Iterable
+ self.assertEqual(sequence[len(sequence) -1], sequence[-1])
item = sequence[0]
self.assertEqual(item, sequence[0])
self.assertIn(item, sequence) # Container
self.assertEqual(sequence.index(item), 0)
self.assertEqual(sequence.count(item), 1)
+ other_item = unittest_pb2.NestedTestAllTypes.DESCRIPTOR.fields[0]
+ self.assertNotIn(other_item, sequence)
+ self.assertEqual(sequence.count(other_item), 0)
+ self.assertRaises(ValueError, sequence.index, other_item)
+ self.assertRaises(ValueError, sequence.index, [])
reversed_iterator = reversed(sequence)
self.assertEqual(list(reversed_iterator), list(sequence)[::-1])
self.assertRaises(StopIteration, next, reversed_iterator)
+ expected_list[0] = 'change value'
+ self.assertNotEqual(expected_list, sequence)
+ # TODO(jieluo): Change __repr__ support for DescriptorSequence.
+ if api_implementation.Type() == 'python':
+ self.assertEqual(str(list(sequence)), str(sequence))
+ else:
+ self.assertEqual(str(sequence)[0], '<')
def CheckDescriptorMapping(self, mapping):
# Verifies that a property like 'messageDescriptor.fields' has all the
# properties of an immutable abc.Mapping.
+ self.assertNotEqual(
+ mapping, unittest_pb2.TestAllExtensions.DESCRIPTOR.fields_by_name)
+ self.assertNotEqual(mapping, {})
+ self.assertNotEqual(mapping, 1)
+ self.assertFalse(mapping == 1) # Only for cpp test coverage
+ excepted_dict = dict(mapping.items())
+ self.assertEqual(mapping, excepted_dict)
+ self.assertEqual(mapping, mapping)
self.assertGreater(len(mapping), 0) # Sized
- self.assertEqual(len(mapping), len(list(mapping))) # Iterable
+ self.assertEqual(len(mapping), len(excepted_dict)) # Iterable
if sys.version_info >= (3,):
key, item = next(iter(mapping.items()))
else:
key, item = mapping.items()[0]
self.assertIn(key, mapping) # Container
self.assertEqual(mapping.get(key), item)
+ with self.assertRaises(TypeError):
+ mapping.get()
+ # TODO(jieluo): Fix python and cpp extension diff.
+ if api_implementation.Type() == 'python':
+ self.assertRaises(TypeError, mapping.get, [])
+ else:
+ self.assertEqual(None, mapping.get([]))
# keys(), iterkeys() &co
item = (next(iter(mapping.keys())), next(iter(mapping.values())))
self.assertEqual(item, next(iter(mapping.items())))
@@ -495,6 +582,18 @@ class GeneratedDescriptorTest(unittest.TestCase):
CheckItems(mapping.keys(), mapping.iterkeys())
CheckItems(mapping.values(), mapping.itervalues())
CheckItems(mapping.items(), mapping.iteritems())
+ excepted_dict[key] = 'change value'
+ self.assertNotEqual(mapping, excepted_dict)
+ del excepted_dict[key]
+ excepted_dict['new_key'] = 'new'
+ self.assertNotEqual(mapping, excepted_dict)
+ self.assertRaises(KeyError, mapping.__getitem__, 'key_error')
+ self.assertRaises(KeyError, mapping.__getitem__, len(mapping) + 1)
+ # TODO(jieluo): Add __repr__ support for DescriptorMapping.
+ if api_implementation.Type() == 'python':
+ self.assertEqual(len(str(dict(mapping.items()))), len(str(mapping)))
+ else:
+ self.assertEqual(str(mapping)[0], '<')
def testDescriptor(self):
message_descriptor = unittest_pb2.TestAllTypes.DESCRIPTOR
@@ -504,13 +603,26 @@ class GeneratedDescriptorTest(unittest.TestCase):
field_descriptor = message_descriptor.fields_by_camelcase_name[
'optionalInt32']
self.CheckFieldDescriptor(field_descriptor)
+ enum_descriptor = unittest_pb2.DESCRIPTOR.enum_types_by_name[
+ 'ForeignEnum']
+ self.assertEqual(None, enum_descriptor.containing_type)
+ # Test extension range
+ self.assertEqual(
+ unittest_pb2.TestAllExtensions.DESCRIPTOR.extension_ranges,
+ [(1, 536870912)])
+ self.assertEqual(
+ unittest_pb2.TestMultipleExtensionRanges.DESCRIPTOR.extension_ranges,
+ [(42, 43), (4143, 4244), (65536, 536870912)])
def testCppDescriptorContainer(self):
- # Check that the collection is still valid even if the parent disappeared.
- enum = unittest_pb2.TestAllTypes.DESCRIPTOR.enum_types_by_name['NestedEnum']
- values = enum.values
- del enum
- self.assertEqual('FOO', values[0].name)
+ containing_file = unittest_pb2.DESCRIPTOR
+ self.CheckDescriptorSequence(containing_file.dependencies)
+ self.CheckDescriptorMapping(containing_file.message_types_by_name)
+ self.CheckDescriptorMapping(containing_file.enum_types_by_name)
+ self.CheckDescriptorMapping(containing_file.services_by_name)
+ self.CheckDescriptorMapping(containing_file.extensions_by_name)
+ self.CheckDescriptorMapping(
+ unittest_pb2.TestNestedExtension.DESCRIPTOR.extensions_by_name)
def testCppDescriptorContainer_Iterator(self):
# Same test with the iterator
@@ -519,6 +631,24 @@ class GeneratedDescriptorTest(unittest.TestCase):
del enum
self.assertEqual('FOO', next(values_iter).name)
+ def testServiceDescriptor(self):
+ service_descriptor = unittest_pb2.DESCRIPTOR.services_by_name['TestService']
+ self.assertEqual(service_descriptor.name, 'TestService')
+ self.assertEqual(service_descriptor.methods[0].name, 'Foo')
+ self.assertIs(service_descriptor.file, unittest_pb2.DESCRIPTOR)
+ self.assertEqual(service_descriptor.index, 0)
+ self.CheckDescriptorMapping(service_descriptor.methods_by_name)
+
+ def testOneofDescriptor(self):
+ message_descriptor = unittest_pb2.TestAllTypes.DESCRIPTOR
+ oneof_descriptor = message_descriptor.oneofs_by_name['oneof_field']
+ self.assertFalse(oneof_descriptor.has_options)
+ self.assertEqual(message_descriptor, oneof_descriptor.containing_type)
+ self.assertEqual('oneof_field', oneof_descriptor.name)
+ self.assertEqual('protobuf_unittest.TestAllTypes.oneof_field',
+ oneof_descriptor.full_name)
+ self.assertEqual(0, oneof_descriptor.index)
+
class DescriptorCopyToProtoTest(unittest.TestCase):
"""Tests for CopyTo functions of Descriptor."""
@@ -596,7 +726,7 @@ class DescriptorCopyToProtoTest(unittest.TestCase):
"""
self._InternalTestCopyToProto(
- unittest_pb2._FOREIGNENUM,
+ unittest_pb2.ForeignEnum.DESCRIPTOR,
descriptor_pb2.EnumDescriptorProto,
TEST_FOREIGN_ENUM_ASCII)
@@ -612,6 +742,19 @@ class DescriptorCopyToProtoTest(unittest.TestCase):
deprecated: true
>
>
+ field {
+ name: "deprecated_int32_in_oneof"
+ number: 2
+ label: LABEL_OPTIONAL
+ type: TYPE_INT32
+ options {
+ deprecated: true
+ }
+ oneof_index: 0
+ }
+ oneof_decl {
+ name: "oneof_fields"
+ }
"""
self._InternalTestCopyToProto(
@@ -655,49 +798,64 @@ class DescriptorCopyToProtoTest(unittest.TestCase):
descriptor_pb2.DescriptorProto,
TEST_MESSAGE_WITH_SEVERAL_EXTENSIONS_ASCII)
- # Disable this test so we can make changes to the proto file.
- # TODO(xiaofeng): Enable this test after cl/55530659 is submitted.
- #
- # def testCopyToProto_FileDescriptor(self):
- # UNITTEST_IMPORT_FILE_DESCRIPTOR_ASCII = ("""
- # name: 'google/protobuf/unittest_import.proto'
- # package: 'protobuf_unittest_import'
- # dependency: 'google/protobuf/unittest_import_public.proto'
- # message_type: <
- # name: 'ImportMessage'
- # field: <
- # name: 'd'
- # number: 1
- # label: 1 # Optional
- # type: 5 # TYPE_INT32
- # >
- # >
- # """ +
- # """enum_type: <
- # name: 'ImportEnum'
- # value: <
- # name: 'IMPORT_FOO'
- # number: 7
- # >
- # value: <
- # name: 'IMPORT_BAR'
- # number: 8
- # >
- # value: <
- # name: 'IMPORT_BAZ'
- # number: 9
- # >
- # >
- # options: <
- # java_package: 'com.google.protobuf.test'
- # optimize_for: 1 # SPEED
- # >
- # public_dependency: 0
- # """)
- # self._InternalTestCopyToProto(
- # unittest_import_pb2.DESCRIPTOR,
- # descriptor_pb2.FileDescriptorProto,
- # UNITTEST_IMPORT_FILE_DESCRIPTOR_ASCII)
+ def testCopyToProto_FileDescriptor(self):
+ UNITTEST_IMPORT_FILE_DESCRIPTOR_ASCII = ("""
+ name: 'google/protobuf/unittest_import.proto'
+ package: 'protobuf_unittest_import'
+ dependency: 'google/protobuf/unittest_import_public.proto'
+ message_type: <
+ name: 'ImportMessage'
+ field: <
+ name: 'd'
+ number: 1
+ label: 1 # Optional
+ type: 5 # TYPE_INT32
+ >
+ >
+ """ +
+ """enum_type: <
+ name: 'ImportEnum'
+ value: <
+ name: 'IMPORT_FOO'
+ number: 7
+ >
+ value: <
+ name: 'IMPORT_BAR'
+ number: 8
+ >
+ value: <
+ name: 'IMPORT_BAZ'
+ number: 9
+ >
+ >
+ enum_type: <
+ name: 'ImportEnumForMap'
+ value: <
+ name: 'UNKNOWN'
+ number: 0
+ >
+ value: <
+ name: 'FOO'
+ number: 1
+ >
+ value: <
+ name: 'BAR'
+ number: 2
+ >
+ >
+ options: <
+ java_package: 'com.google.protobuf.test'
+ optimize_for: 1 # SPEED
+ """ +
+ """
+ cc_enable_arenas: true
+ >
+ public_dependency: 0
+ """)
+ self._InternalTestCopyToProto(
+ unittest_import_pb2.DESCRIPTOR,
+ descriptor_pb2.FileDescriptorProto,
+ UNITTEST_IMPORT_FILE_DESCRIPTOR_ASCII)
def testCopyToProto_ServiceDescriptor(self):
TEST_SERVICE_ASCII = """
@@ -713,12 +871,47 @@ class DescriptorCopyToProtoTest(unittest.TestCase):
output_type: '.protobuf_unittest.BarResponse'
>
"""
- # TODO(rocking): enable this test after the proto descriptor change is
- # checked in.
- #self._InternalTestCopyToProto(
- # unittest_pb2.TestService.DESCRIPTOR,
- # descriptor_pb2.ServiceDescriptorProto,
- # TEST_SERVICE_ASCII)
+ self._InternalTestCopyToProto(
+ unittest_pb2.TestService.DESCRIPTOR,
+ descriptor_pb2.ServiceDescriptorProto,
+ TEST_SERVICE_ASCII)
+
+ @unittest.skipIf(
+ api_implementation.Type() == 'python',
+ 'It is not implemented in python.')
+ # TODO(jieluo): Add support for pure python or remove in c extension.
+ def testCopyToProto_MethodDescriptor(self):
+ expected_ascii = """
+ name: 'Foo'
+ input_type: '.protobuf_unittest.FooRequest'
+ output_type: '.protobuf_unittest.FooResponse'
+ """
+ method_descriptor = unittest_pb2.TestService.DESCRIPTOR.FindMethodByName(
+ 'Foo')
+ self._InternalTestCopyToProto(
+ method_descriptor,
+ descriptor_pb2.MethodDescriptorProto,
+ expected_ascii)
+
+ @unittest.skipIf(
+ api_implementation.Type() == 'python',
+ 'Pure python does not raise error.')
+ # TODO(jieluo): Fix pure python to check with the proto type.
+ def testCopyToProto_TypeError(self):
+ file_proto = descriptor_pb2.FileDescriptorProto()
+ self.assertRaises(TypeError,
+ unittest_pb2.TestEmptyMessage.DESCRIPTOR.CopyToProto,
+ file_proto)
+ self.assertRaises(TypeError,
+ unittest_pb2.ForeignEnum.DESCRIPTOR.CopyToProto,
+ file_proto)
+ self.assertRaises(TypeError,
+ unittest_pb2.TestService.DESCRIPTOR.CopyToProto,
+ file_proto)
+ proto = descriptor_pb2.DescriptorProto()
+ self.assertRaises(TypeError,
+ unittest_import_pb2.DESCRIPTOR.CopyToProto,
+ proto)
class MakeDescriptorTest(unittest.TestCase):
@@ -764,6 +957,11 @@ class MakeDescriptorTest(unittest.TestCase):
'Foo2.Sub.bar_field')
self.assertEqual(result.nested_types[0].fields[0].enum_type,
result.nested_types[0].enum_types[0])
+ self.assertFalse(result.has_options)
+ self.assertFalse(result.fields[0].has_options)
+ if api_implementation.Type() == 'cpp':
+ with self.assertRaises(AttributeError):
+ result.fields[0].has_options = False
def testMakeDescriptorWithUnsignedIntField(self):
file_descriptor_proto = descriptor_pb2.FileDescriptorProto()
@@ -816,6 +1014,23 @@ class MakeDescriptorTest(unittest.TestCase):
self.assertEqual(result.fields[index].camelcase_name,
camelcase_names[index])
+ def testJsonName(self):
+ descriptor_proto = descriptor_pb2.DescriptorProto()
+ descriptor_proto.name = 'TestJsonName'
+ names = ['field_name', 'fieldName', 'FieldName',
+ '_field_name', 'FIELD_NAME', 'json_name']
+ json_names = ['fieldName', 'fieldName', 'FieldName',
+ 'FieldName', 'FIELDNAME', '@type']
+ for index in range(len(names)):
+ field = descriptor_proto.field.add()
+ field.number = index + 1
+ field.name = names[index]
+ field.json_name = '@type'
+ result = descriptor.MakeDescriptor(descriptor_proto)
+ for index in range(len(json_names)):
+ self.assertEqual(result.fields[index].json_name,
+ json_names[index])
+
if __name__ == '__main__':
unittest.main()