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#import "GPBTestUtilities.h" 32 33#import <objc/runtime.h> 34 35#import "GPBDescriptor_PackagePrivate.h" 36#import "google/protobuf/Unittest.pbobjc.h" 37#import "google/protobuf/UnittestObjc.pbobjc.h" 38#import "google/protobuf/Descriptor.pbobjc.h" 39 40@interface DescriptorTests : GPBTestCase 41@end 42 43@implementation DescriptorTests 44 45- (void)testDescriptor_containingType { 46 GPBDescriptor *testAllTypesDesc = [TestAllTypes descriptor]; 47 GPBDescriptor *nestedMessageDesc = [TestAllTypes_NestedMessage descriptor]; 48 XCTAssertNil(testAllTypesDesc.containingType); 49 XCTAssertNotNil(nestedMessageDesc.containingType); 50 XCTAssertEqual(nestedMessageDesc.containingType, testAllTypesDesc); // Ptr comparison 51} 52 53- (void)testDescriptor_fullName { 54 GPBDescriptor *testAllTypesDesc = [TestAllTypes descriptor]; 55 XCTAssertEqualObjects(testAllTypesDesc.fullName, @"protobuf_unittest.TestAllTypes"); 56 GPBDescriptor *nestedMessageDesc = [TestAllTypes_NestedMessage descriptor]; 57 XCTAssertEqualObjects(nestedMessageDesc.fullName, @"protobuf_unittest.TestAllTypes.NestedMessage"); 58 59 // Prefixes removed. 60 GPBDescriptor *descDesc = [GPBDescriptorProto descriptor]; 61 XCTAssertEqualObjects(descDesc.fullName, @"google.protobuf.DescriptorProto"); 62 GPBDescriptor *descExtRngDesc = [GPBDescriptorProto_ExtensionRange descriptor]; 63 XCTAssertEqualObjects(descExtRngDesc.fullName, @"google.protobuf.DescriptorProto.ExtensionRange"); 64 65 // Things that get "_Class" added. 66 GPBDescriptor *pointDesc = [Point_Class descriptor]; 67 XCTAssertEqualObjects(pointDesc.fullName, @"protobuf_unittest.Point"); 68 GPBDescriptor *pointRectDesc = [Point_Rect descriptor]; 69 XCTAssertEqualObjects(pointRectDesc.fullName, @"protobuf_unittest.Point.Rect"); 70} 71 72- (void)testFieldDescriptor { 73 GPBDescriptor *descriptor = [TestAllTypes descriptor]; 74 75 // Nested Enum 76 GPBFieldDescriptor *fieldDescriptorWithName = 77 [descriptor fieldWithName:@"optionalNestedEnum"]; 78 XCTAssertNotNil(fieldDescriptorWithName); 79 GPBFieldDescriptor *fieldDescriptorWithNumber = 80 [descriptor fieldWithNumber:21]; 81 XCTAssertNotNil(fieldDescriptorWithNumber); 82 XCTAssertEqual(fieldDescriptorWithName, fieldDescriptorWithNumber); 83 XCTAssertNotNil(fieldDescriptorWithNumber.enumDescriptor); 84 XCTAssertEqualObjects(fieldDescriptorWithNumber.enumDescriptor.name, 85 @"TestAllTypes_NestedEnum"); 86 XCTAssertEqual(fieldDescriptorWithName.number, fieldDescriptorWithNumber.number); 87 XCTAssertEqual(fieldDescriptorWithName.dataType, GPBDataTypeEnum); 88 89 // Foreign Enum 90 fieldDescriptorWithName = [descriptor fieldWithName:@"optionalForeignEnum"]; 91 XCTAssertNotNil(fieldDescriptorWithName); 92 fieldDescriptorWithNumber = [descriptor fieldWithNumber:22]; 93 XCTAssertNotNil(fieldDescriptorWithNumber); 94 XCTAssertEqual(fieldDescriptorWithName, fieldDescriptorWithNumber); 95 XCTAssertNotNil(fieldDescriptorWithNumber.enumDescriptor); 96 XCTAssertEqualObjects(fieldDescriptorWithNumber.enumDescriptor.name, 97 @"ForeignEnum"); 98 XCTAssertEqual(fieldDescriptorWithName.number, fieldDescriptorWithNumber.number); 99 XCTAssertEqual(fieldDescriptorWithName.dataType, GPBDataTypeEnum); 100 101 // Import Enum 102 fieldDescriptorWithName = [descriptor fieldWithName:@"optionalImportEnum"]; 103 XCTAssertNotNil(fieldDescriptorWithName); 104 fieldDescriptorWithNumber = [descriptor fieldWithNumber:23]; 105 XCTAssertNotNil(fieldDescriptorWithNumber); 106 XCTAssertEqual(fieldDescriptorWithName, fieldDescriptorWithNumber); 107 XCTAssertNotNil(fieldDescriptorWithNumber.enumDescriptor); 108 XCTAssertEqualObjects(fieldDescriptorWithNumber.enumDescriptor.name, 109 @"ImportEnum"); 110 XCTAssertEqual(fieldDescriptorWithName.number, fieldDescriptorWithNumber.number); 111 XCTAssertEqual(fieldDescriptorWithName.dataType, GPBDataTypeEnum); 112 113 // Nested Message 114 fieldDescriptorWithName = [descriptor fieldWithName:@"optionalNestedMessage"]; 115 XCTAssertNotNil(fieldDescriptorWithName); 116 fieldDescriptorWithNumber = [descriptor fieldWithNumber:18]; 117 XCTAssertNotNil(fieldDescriptorWithNumber); 118 XCTAssertEqual(fieldDescriptorWithName, fieldDescriptorWithNumber); 119 XCTAssertNil(fieldDescriptorWithNumber.enumDescriptor); 120 XCTAssertEqual(fieldDescriptorWithName.number, fieldDescriptorWithNumber.number); 121 XCTAssertEqual(fieldDescriptorWithName.dataType, GPBDataTypeMessage); 122 123 // Foreign Message 124 fieldDescriptorWithName = 125 [descriptor fieldWithName:@"optionalForeignMessage"]; 126 XCTAssertNotNil(fieldDescriptorWithName); 127 fieldDescriptorWithNumber = [descriptor fieldWithNumber:19]; 128 XCTAssertNotNil(fieldDescriptorWithNumber); 129 XCTAssertEqual(fieldDescriptorWithName, fieldDescriptorWithNumber); 130 XCTAssertNil(fieldDescriptorWithNumber.enumDescriptor); 131 XCTAssertEqual(fieldDescriptorWithName.number, fieldDescriptorWithNumber.number); 132 XCTAssertEqual(fieldDescriptorWithName.dataType, GPBDataTypeMessage); 133 134 // Import Message 135 fieldDescriptorWithName = [descriptor fieldWithName:@"optionalImportMessage"]; 136 XCTAssertNotNil(fieldDescriptorWithName); 137 fieldDescriptorWithNumber = [descriptor fieldWithNumber:20]; 138 XCTAssertNotNil(fieldDescriptorWithNumber); 139 XCTAssertEqual(fieldDescriptorWithName, fieldDescriptorWithNumber); 140 XCTAssertNil(fieldDescriptorWithNumber.enumDescriptor); 141 XCTAssertEqual(fieldDescriptorWithName.number, fieldDescriptorWithNumber.number); 142 XCTAssertEqual(fieldDescriptorWithName.dataType, GPBDataTypeMessage); 143 144 // Some failed lookups. 145 XCTAssertNil([descriptor fieldWithName:@"NOT THERE"]); 146 XCTAssertNil([descriptor fieldWithNumber:9876543]); 147} 148 149- (void)testEnumDescriptor { 150 GPBEnumDescriptor *descriptor = TestAllTypes_NestedEnum_EnumDescriptor(); 151 152 NSString *enumName = [descriptor enumNameForValue:1]; 153 XCTAssertNotNil(enumName); 154 int32_t value; 155 XCTAssertTrue( 156 [descriptor getValue:&value forEnumName:@"TestAllTypes_NestedEnum_Foo"]); 157 XCTAssertTrue( 158 [descriptor getValue:NULL forEnumName:@"TestAllTypes_NestedEnum_Foo"]); 159 XCTAssertEqual(value, TestAllTypes_NestedEnum_Foo); 160 161 enumName = [descriptor enumNameForValue:2]; 162 XCTAssertNotNil(enumName); 163 XCTAssertTrue( 164 [descriptor getValue:&value forEnumName:@"TestAllTypes_NestedEnum_Bar"]); 165 XCTAssertEqual(value, TestAllTypes_NestedEnum_Bar); 166 167 enumName = [descriptor enumNameForValue:3]; 168 XCTAssertNotNil(enumName); 169 XCTAssertTrue( 170 [descriptor getValue:&value forEnumName:@"TestAllTypes_NestedEnum_Baz"]); 171 XCTAssertEqual(value, TestAllTypes_NestedEnum_Baz); 172 173 // TextFormat 174 enumName = [descriptor textFormatNameForValue:1]; 175 XCTAssertNotNil(enumName); 176 XCTAssertTrue([descriptor getValue:&value forEnumTextFormatName:@"FOO"]); 177 XCTAssertEqual(value, TestAllTypes_NestedEnum_Foo); 178 XCTAssertNil([descriptor textFormatNameForValue:99999]); 179 180 // Bad values 181 enumName = [descriptor enumNameForValue:0]; 182 XCTAssertNil(enumName); 183 XCTAssertFalse([descriptor getValue:&value forEnumName:@"Unknown"]); 184 XCTAssertFalse([descriptor getValue:NULL forEnumName:@"Unknown"]); 185 XCTAssertFalse([descriptor getValue:&value 186 forEnumName:@"TestAllTypes_NestedEnum_Unknown"]); 187 XCTAssertFalse([descriptor getValue:NULL 188 forEnumName:@"TestAllTypes_NestedEnum_Unknown"]); 189 XCTAssertFalse([descriptor getValue:NULL forEnumTextFormatName:@"Unknown"]); 190 XCTAssertFalse([descriptor getValue:&value forEnumTextFormatName:@"Unknown"]); 191} 192 193- (void)testEnumDescriptorIntrospection { 194 GPBEnumDescriptor *descriptor = TestAllTypes_NestedEnum_EnumDescriptor(); 195 196 XCTAssertEqual(descriptor.enumNameCount, 4U); 197 XCTAssertEqualObjects([descriptor getEnumNameForIndex:0], 198 @"TestAllTypes_NestedEnum_Foo"); 199 XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:0], @"FOO"); 200 XCTAssertEqualObjects([descriptor getEnumNameForIndex:1], 201 @"TestAllTypes_NestedEnum_Bar"); 202 XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:1], @"BAR"); 203 XCTAssertEqualObjects([descriptor getEnumNameForIndex:2], 204 @"TestAllTypes_NestedEnum_Baz"); 205 XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:2], @"BAZ"); 206 XCTAssertEqualObjects([descriptor getEnumNameForIndex:3], 207 @"TestAllTypes_NestedEnum_Neg"); 208 XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:3], @"NEG"); 209} 210 211- (void)testEnumDescriptorIntrospectionWithAlias { 212 GPBEnumDescriptor *descriptor = TestEnumWithDupValue_EnumDescriptor(); 213 NSString *enumName; 214 int32_t value; 215 216 XCTAssertEqual(descriptor.enumNameCount, 5U); 217 218 enumName = [descriptor getEnumNameForIndex:0]; 219 XCTAssertEqualObjects(enumName, @"TestEnumWithDupValue_Foo1"); 220 XCTAssertTrue([descriptor getValue:&value forEnumName:enumName]); 221 XCTAssertEqual(value, 1); 222 XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:0], @"FOO1"); 223 224 enumName = [descriptor getEnumNameForIndex:1]; 225 XCTAssertEqualObjects(enumName, @"TestEnumWithDupValue_Bar1"); 226 XCTAssertTrue([descriptor getValue:&value forEnumName:enumName]); 227 XCTAssertEqual(value, 2); 228 XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:1], @"BAR1"); 229 230 enumName = [descriptor getEnumNameForIndex:2]; 231 XCTAssertEqualObjects(enumName, @"TestEnumWithDupValue_Baz"); 232 XCTAssertTrue([descriptor getValue:&value forEnumName:enumName]); 233 XCTAssertEqual(value, 3); 234 XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:2], @"BAZ"); 235 236 enumName = [descriptor getEnumNameForIndex:3]; 237 XCTAssertEqualObjects(enumName, @"TestEnumWithDupValue_Foo2"); 238 XCTAssertTrue([descriptor getValue:&value forEnumName:enumName]); 239 XCTAssertEqual(value, 1); 240 XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:3], @"FOO2"); 241 242 enumName = [descriptor getEnumNameForIndex:4]; 243 XCTAssertEqualObjects(enumName, @"TestEnumWithDupValue_Bar2"); 244 XCTAssertTrue([descriptor getValue:&value forEnumName:enumName]); 245 XCTAssertEqual(value, 2); 246 XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:4], @"BAR2"); 247} 248 249- (void)testEnumAliasNameCollisions { 250 GPBEnumDescriptor *descriptor = TestEnumObjCNameCollision_EnumDescriptor(); 251 NSString *textFormatName; 252 int32_t value; 253 254 XCTAssertEqual(descriptor.enumNameCount, 5U); 255 256 XCTAssertEqualObjects([descriptor getEnumNameForIndex:0], @"TestEnumObjCNameCollision_Foo"); 257 textFormatName = [descriptor getEnumTextFormatNameForIndex:0]; 258 XCTAssertEqualObjects(textFormatName, @"FOO"); 259 XCTAssertTrue([descriptor getValue:&value forEnumTextFormatName:textFormatName]); 260 XCTAssertEqual(value, 1); 261 262 XCTAssertEqualObjects([descriptor getEnumNameForIndex:1], @"TestEnumObjCNameCollision_Foo"); 263 textFormatName = [descriptor getEnumTextFormatNameForIndex:1]; 264 XCTAssertEqualObjects(textFormatName, @"foo"); 265 XCTAssertTrue([descriptor getValue:&value forEnumTextFormatName:textFormatName]); 266 XCTAssertEqual(value, 1); 267 268 XCTAssertEqualObjects([descriptor getEnumNameForIndex:2], @"TestEnumObjCNameCollision_Bar"); 269 textFormatName = [descriptor getEnumTextFormatNameForIndex:2]; 270 XCTAssertEqualObjects(textFormatName, @"BAR"); 271 XCTAssertTrue([descriptor getValue:&value forEnumTextFormatName:textFormatName]); 272 XCTAssertEqual(value, 2); 273 274 XCTAssertEqualObjects([descriptor getEnumNameForIndex:3], @"TestEnumObjCNameCollision_Mumble"); 275 textFormatName = [descriptor getEnumTextFormatNameForIndex:3]; 276 XCTAssertEqualObjects(textFormatName, @"mumble"); 277 XCTAssertTrue([descriptor getValue:&value forEnumTextFormatName:textFormatName]); 278 XCTAssertEqual(value, 2); 279 280 XCTAssertEqualObjects([descriptor getEnumNameForIndex:4], @"TestEnumObjCNameCollision_Mumble"); 281 textFormatName = [descriptor getEnumTextFormatNameForIndex:4]; 282 XCTAssertEqualObjects(textFormatName, @"MUMBLE"); 283 XCTAssertTrue([descriptor getValue:&value forEnumTextFormatName:textFormatName]); 284 XCTAssertEqual(value, 2); 285} 286 287- (void)testEnumValueValidator { 288 GPBDescriptor *descriptor = [TestAllTypes descriptor]; 289 GPBFieldDescriptor *fieldDescriptor = 290 [descriptor fieldWithName:@"optionalNestedEnum"]; 291 292 // Valid values 293 XCTAssertTrue([fieldDescriptor isValidEnumValue:1]); 294 XCTAssertTrue([fieldDescriptor isValidEnumValue:2]); 295 XCTAssertTrue([fieldDescriptor isValidEnumValue:3]); 296 XCTAssertTrue([fieldDescriptor isValidEnumValue:-1]); 297 298 // Invalid values 299 XCTAssertFalse([fieldDescriptor isValidEnumValue:4]); 300 XCTAssertFalse([fieldDescriptor isValidEnumValue:0]); 301 XCTAssertFalse([fieldDescriptor isValidEnumValue:-2]); 302} 303 304- (void)testOneofDescriptor { 305 GPBDescriptor *descriptor = [TestOneof2 descriptor]; 306 307 // All fields should be listed. 308 XCTAssertEqual(descriptor.fields.count, 17U); 309 310 // There are two oneofs in there. 311 XCTAssertEqual(descriptor.oneofs.count, 2U); 312 313 GPBFieldDescriptor *fooStringField = 314 [descriptor fieldWithNumber:TestOneof2_FieldNumber_FooString]; 315 XCTAssertNotNil(fooStringField); 316 GPBFieldDescriptor *barStringField = 317 [descriptor fieldWithNumber:TestOneof2_FieldNumber_BarString]; 318 XCTAssertNotNil(barStringField); 319 320 // Check the oneofs to have what is expected. 321 322 GPBOneofDescriptor *oneofFoo = [descriptor oneofWithName:@"foo"]; 323 XCTAssertNotNil(oneofFoo); 324 XCTAssertEqual(oneofFoo.fields.count, 9U); 325 326 // Pointer comparisons. 327 XCTAssertEqual([oneofFoo fieldWithNumber:TestOneof2_FieldNumber_FooString], 328 fooStringField); 329 XCTAssertEqual([oneofFoo fieldWithName:@"fooString"], fooStringField); 330 331 GPBOneofDescriptor *oneofBar = [descriptor oneofWithName:@"bar"]; 332 XCTAssertNotNil(oneofBar); 333 XCTAssertEqual(oneofBar.fields.count, 6U); 334 335 // Pointer comparisons. 336 XCTAssertEqual([oneofBar fieldWithNumber:TestOneof2_FieldNumber_BarString], 337 barStringField); 338 XCTAssertEqual([oneofBar fieldWithName:@"barString"], barStringField); 339 340 // Unknown oneof not found. 341 342 XCTAssertNil([descriptor oneofWithName:@"mumble"]); 343 XCTAssertNil([descriptor oneofWithName:@"Foo"]); 344 345 // Unknown oneof item. 346 347 XCTAssertNil([oneofFoo fieldWithName:@"mumble"]); 348 XCTAssertNil([oneofFoo fieldWithNumber:666]); 349 350 // Field exists, but not in this oneof. 351 352 XCTAssertNil([oneofFoo fieldWithName:@"barString"]); 353 XCTAssertNil([oneofFoo fieldWithNumber:TestOneof2_FieldNumber_BarString]); 354 XCTAssertNil([oneofBar fieldWithName:@"fooString"]); 355 XCTAssertNil([oneofBar fieldWithNumber:TestOneof2_FieldNumber_FooString]); 356 357 // Check pointers back to the enclosing oneofs. 358 // (pointer comparisions) 359 XCTAssertEqual(fooStringField.containingOneof, oneofFoo); 360 XCTAssertEqual(barStringField.containingOneof, oneofBar); 361 GPBFieldDescriptor *bazString = 362 [descriptor fieldWithNumber:TestOneof2_FieldNumber_BazString]; 363 XCTAssertNotNil(bazString); 364 XCTAssertNil(bazString.containingOneof); 365} 366 367- (void)testExtensiondDescriptor { 368 Class msgClass = [TestAllExtensions class]; 369 Class packedMsgClass = [TestPackedExtensions class]; 370 371 // Int 372 373 GPBExtensionDescriptor *descriptor = [UnittestRoot optionalInt32Extension]; 374 XCTAssertNotNil(descriptor); 375 XCTAssertEqual(descriptor.containingMessageClass, msgClass); // ptr equality 376 XCTAssertFalse(descriptor.isPackable); 377 XCTAssertEqualObjects(descriptor.defaultValue, @0); 378 XCTAssertNil(descriptor.enumDescriptor); 379 380 descriptor = [UnittestRoot defaultInt32Extension]; 381 XCTAssertNotNil(descriptor); 382 XCTAssertEqual(descriptor.containingMessageClass, msgClass); // ptr equality 383 XCTAssertFalse(descriptor.isPackable); 384 XCTAssertEqualObjects(descriptor.defaultValue, @41); 385 XCTAssertNil(descriptor.enumDescriptor); 386 387 // Enum 388 389 descriptor = [UnittestRoot optionalNestedEnumExtension]; 390 XCTAssertNotNil(descriptor); 391 XCTAssertEqual(descriptor.containingMessageClass, msgClass); // ptr equality 392 XCTAssertFalse(descriptor.isPackable); 393 XCTAssertEqual(descriptor.defaultValue, @1); 394 XCTAssertEqualObjects(descriptor.enumDescriptor.name, @"TestAllTypes_NestedEnum"); 395 396 descriptor = [UnittestRoot defaultNestedEnumExtension]; 397 XCTAssertNotNil(descriptor); 398 XCTAssertEqual(descriptor.containingMessageClass, msgClass); // ptr equality 399 XCTAssertFalse(descriptor.isPackable); 400 XCTAssertEqual(descriptor.defaultValue, @2); 401 XCTAssertEqualObjects(descriptor.enumDescriptor.name, @"TestAllTypes_NestedEnum"); 402 403 // Message 404 405 descriptor = [UnittestRoot optionalNestedMessageExtension]; 406 XCTAssertNotNil(descriptor); 407 XCTAssertEqual(descriptor.containingMessageClass, msgClass); // ptr equality 408 XCTAssertFalse(descriptor.isPackable); 409 XCTAssertNil(descriptor.defaultValue); 410 XCTAssertNil(descriptor.enumDescriptor); 411 412 // Repeated Int 413 414 descriptor = [UnittestRoot repeatedInt32Extension]; 415 XCTAssertNotNil(descriptor); 416 XCTAssertEqual(descriptor.containingMessageClass, msgClass); // ptr equality 417 XCTAssertFalse(descriptor.isPackable); 418 XCTAssertNil(descriptor.defaultValue); 419 XCTAssertNil(descriptor.enumDescriptor); 420 421 descriptor = [UnittestRoot packedInt32Extension]; 422 XCTAssertNotNil(descriptor); 423 XCTAssertEqual(descriptor.containingMessageClass, packedMsgClass); // ptr equality 424 XCTAssertTrue(descriptor.isPackable); 425 XCTAssertNil(descriptor.defaultValue); 426 XCTAssertNil(descriptor.enumDescriptor); 427 428 // Repeated Enum 429 430 descriptor = [UnittestRoot repeatedNestedEnumExtension]; 431 XCTAssertNotNil(descriptor); 432 XCTAssertEqual(descriptor.containingMessageClass, msgClass); // ptr equality 433 XCTAssertFalse(descriptor.isPackable); 434 XCTAssertNil(descriptor.defaultValue); 435 XCTAssertEqualObjects(descriptor.enumDescriptor.name, @"TestAllTypes_NestedEnum"); 436 437 descriptor = [UnittestRoot packedEnumExtension]; 438 XCTAssertNotNil(descriptor); 439 XCTAssertEqual(descriptor.containingMessageClass, packedMsgClass); // ptr equality 440 XCTAssertTrue(descriptor.isPackable); 441 XCTAssertNil(descriptor.defaultValue); 442 XCTAssertEqualObjects(descriptor.enumDescriptor.name, @"ForeignEnum"); 443 444 // Repeated Message 445 446 descriptor = [UnittestRoot repeatedNestedMessageExtension]; 447 XCTAssertNotNil(descriptor); 448 XCTAssertEqual(descriptor.containingMessageClass, msgClass); // ptr equality 449 XCTAssertFalse(descriptor.isPackable); 450 XCTAssertNil(descriptor.defaultValue); 451 XCTAssertNil(descriptor.enumDescriptor); 452 453 // Compare (used internally for serialization). 454 455 GPBExtensionDescriptor *ext1 = [UnittestRoot optionalInt32Extension]; 456 XCTAssertEqual(ext1.fieldNumber, 1u); 457 GPBExtensionDescriptor *ext2 = [UnittestRoot optionalInt64Extension]; 458 XCTAssertEqual(ext2.fieldNumber, 2u); 459 460 XCTAssertEqual([ext1 compareByFieldNumber:ext2], NSOrderedAscending); 461 XCTAssertEqual([ext2 compareByFieldNumber:ext1], NSOrderedDescending); 462 XCTAssertEqual([ext1 compareByFieldNumber:ext1], NSOrderedSame); 463} 464 465@end 466