1#! /usr/bin/python 2# 3# Protocol Buffers - Google's data interchange format 4# Copyright 2008 Google Inc. All rights reserved. 5# http://code.google.com/p/protobuf/ 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# TODO(robinson): Flesh this out considerably. We focused on reflection_test.py 34# first, since it's testing the subtler code, and since it provides decent 35# indirect testing of the protocol compiler output. 36 37"""Unittest that directly tests the output of the pure-Python protocol 38compiler. See //google/protobuf/reflection_test.py for a test which 39further ensures that we can use Python protocol message objects as we expect. 40""" 41 42__author__ = 'robinson@google.com (Will Robinson)' 43 44import unittest 45from google.protobuf import unittest_import_pb2 46from google.protobuf import unittest_mset_pb2 47from google.protobuf import unittest_pb2 48from google.protobuf import unittest_no_generic_services_pb2 49 50 51MAX_EXTENSION = 536870912 52 53 54class GeneratorTest(unittest.TestCase): 55 56 def testNestedMessageDescriptor(self): 57 field_name = 'optional_nested_message' 58 proto_type = unittest_pb2.TestAllTypes 59 self.assertEqual( 60 proto_type.NestedMessage.DESCRIPTOR, 61 proto_type.DESCRIPTOR.fields_by_name[field_name].message_type) 62 63 def testEnums(self): 64 # We test only module-level enums here. 65 # TODO(robinson): Examine descriptors directly to check 66 # enum descriptor output. 67 self.assertEqual(4, unittest_pb2.FOREIGN_FOO) 68 self.assertEqual(5, unittest_pb2.FOREIGN_BAR) 69 self.assertEqual(6, unittest_pb2.FOREIGN_BAZ) 70 71 proto = unittest_pb2.TestAllTypes() 72 self.assertEqual(1, proto.FOO) 73 self.assertEqual(1, unittest_pb2.TestAllTypes.FOO) 74 self.assertEqual(2, proto.BAR) 75 self.assertEqual(2, unittest_pb2.TestAllTypes.BAR) 76 self.assertEqual(3, proto.BAZ) 77 self.assertEqual(3, unittest_pb2.TestAllTypes.BAZ) 78 79 def testExtremeDefaultValues(self): 80 message = unittest_pb2.TestExtremeDefaultValues() 81 82 # Python pre-2.6 does not have isinf() or isnan() functions, so we have 83 # to provide our own. 84 def isnan(val): 85 # NaN is never equal to itself. 86 return val != val 87 def isinf(val): 88 # Infinity times zero equals NaN. 89 return not isnan(val) and isnan(val * 0) 90 91 self.assertTrue(isinf(message.inf_double)) 92 self.assertTrue(message.inf_double > 0) 93 self.assertTrue(isinf(message.neg_inf_double)) 94 self.assertTrue(message.neg_inf_double < 0) 95 self.assertTrue(isnan(message.nan_double)) 96 97 self.assertTrue(isinf(message.inf_float)) 98 self.assertTrue(message.inf_float > 0) 99 self.assertTrue(isinf(message.neg_inf_float)) 100 self.assertTrue(message.neg_inf_float < 0) 101 self.assertTrue(isnan(message.nan_float)) 102 103 def testHasDefaultValues(self): 104 desc = unittest_pb2.TestAllTypes.DESCRIPTOR 105 106 expected_has_default_by_name = { 107 'optional_int32': False, 108 'repeated_int32': False, 109 'optional_nested_message': False, 110 'default_int32': True, 111 } 112 113 has_default_by_name = dict( 114 [(f.name, f.has_default_value) 115 for f in desc.fields 116 if f.name in expected_has_default_by_name]) 117 self.assertEqual(expected_has_default_by_name, has_default_by_name) 118 119 def testContainingTypeBehaviorForExtensions(self): 120 self.assertEqual(unittest_pb2.optional_int32_extension.containing_type, 121 unittest_pb2.TestAllExtensions.DESCRIPTOR) 122 self.assertEqual(unittest_pb2.TestRequired.single.containing_type, 123 unittest_pb2.TestAllExtensions.DESCRIPTOR) 124 125 def testExtensionScope(self): 126 self.assertEqual(unittest_pb2.optional_int32_extension.extension_scope, 127 None) 128 self.assertEqual(unittest_pb2.TestRequired.single.extension_scope, 129 unittest_pb2.TestRequired.DESCRIPTOR) 130 131 def testIsExtension(self): 132 self.assertTrue(unittest_pb2.optional_int32_extension.is_extension) 133 self.assertTrue(unittest_pb2.TestRequired.single.is_extension) 134 135 message_descriptor = unittest_pb2.TestRequired.DESCRIPTOR 136 non_extension_descriptor = message_descriptor.fields_by_name['a'] 137 self.assertTrue(not non_extension_descriptor.is_extension) 138 139 def testOptions(self): 140 proto = unittest_mset_pb2.TestMessageSet() 141 self.assertTrue(proto.DESCRIPTOR.GetOptions().message_set_wire_format) 142 143 def testNestedTypes(self): 144 self.assertEquals( 145 set(unittest_pb2.TestAllTypes.DESCRIPTOR.nested_types), 146 set([ 147 unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR, 148 unittest_pb2.TestAllTypes.OptionalGroup.DESCRIPTOR, 149 unittest_pb2.TestAllTypes.RepeatedGroup.DESCRIPTOR, 150 ])) 151 self.assertEqual(unittest_pb2.TestEmptyMessage.DESCRIPTOR.nested_types, []) 152 self.assertEqual( 153 unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR.nested_types, []) 154 155 def testContainingType(self): 156 self.assertTrue( 157 unittest_pb2.TestEmptyMessage.DESCRIPTOR.containing_type is None) 158 self.assertTrue( 159 unittest_pb2.TestAllTypes.DESCRIPTOR.containing_type is None) 160 self.assertEqual( 161 unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR.containing_type, 162 unittest_pb2.TestAllTypes.DESCRIPTOR) 163 self.assertEqual( 164 unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR.containing_type, 165 unittest_pb2.TestAllTypes.DESCRIPTOR) 166 self.assertEqual( 167 unittest_pb2.TestAllTypes.RepeatedGroup.DESCRIPTOR.containing_type, 168 unittest_pb2.TestAllTypes.DESCRIPTOR) 169 170 def testContainingTypeInEnumDescriptor(self): 171 self.assertTrue(unittest_pb2._FOREIGNENUM.containing_type is None) 172 self.assertEqual(unittest_pb2._TESTALLTYPES_NESTEDENUM.containing_type, 173 unittest_pb2.TestAllTypes.DESCRIPTOR) 174 175 def testPackage(self): 176 self.assertEqual( 177 unittest_pb2.TestAllTypes.DESCRIPTOR.file.package, 178 'protobuf_unittest') 179 desc = unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR 180 self.assertEqual(desc.file.package, 'protobuf_unittest') 181 self.assertEqual( 182 unittest_import_pb2.ImportMessage.DESCRIPTOR.file.package, 183 'protobuf_unittest_import') 184 185 self.assertEqual( 186 unittest_pb2._FOREIGNENUM.file.package, 'protobuf_unittest') 187 self.assertEqual( 188 unittest_pb2._TESTALLTYPES_NESTEDENUM.file.package, 189 'protobuf_unittest') 190 self.assertEqual( 191 unittest_import_pb2._IMPORTENUM.file.package, 192 'protobuf_unittest_import') 193 194 def testExtensionRange(self): 195 self.assertEqual( 196 unittest_pb2.TestAllTypes.DESCRIPTOR.extension_ranges, []) 197 self.assertEqual( 198 unittest_pb2.TestAllExtensions.DESCRIPTOR.extension_ranges, 199 [(1, MAX_EXTENSION)]) 200 self.assertEqual( 201 unittest_pb2.TestMultipleExtensionRanges.DESCRIPTOR.extension_ranges, 202 [(42, 43), (4143, 4244), (65536, MAX_EXTENSION)]) 203 204 def testFileDescriptor(self): 205 self.assertEqual(unittest_pb2.DESCRIPTOR.name, 206 'google/protobuf/unittest.proto') 207 self.assertEqual(unittest_pb2.DESCRIPTOR.package, 'protobuf_unittest') 208 self.assertFalse(unittest_pb2.DESCRIPTOR.serialized_pb is None) 209 210 def testNoGenericServices(self): 211 # unittest_no_generic_services.proto should contain defs for everything 212 # except services. 213 self.assertTrue(hasattr(unittest_no_generic_services_pb2, "TestMessage")) 214 self.assertTrue(hasattr(unittest_no_generic_services_pb2, "FOO")) 215 self.assertTrue(hasattr(unittest_no_generic_services_pb2, "test_extension")) 216 self.assertFalse(hasattr(unittest_no_generic_services_pb2, "TestService")) 217 218 219if __name__ == '__main__': 220 unittest.main() 221