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 GPBFieldDescriptor *fooStringField = 308 [descriptor fieldWithNumber:TestOneof2_FieldNumber_FooString]; 309 XCTAssertNotNil(fooStringField); 310 GPBFieldDescriptor *barStringField = 311 [descriptor fieldWithNumber:TestOneof2_FieldNumber_BarString]; 312 XCTAssertNotNil(barStringField); 313 314 // Check the oneofs to have what is expected but not other onesofs 315 316 GPBOneofDescriptor *oneofFoo = [descriptor oneofWithName:@"foo"]; 317 XCTAssertNotNil(oneofFoo); 318 XCTAssertNotNil([oneofFoo fieldWithName:@"fooString"]); 319 XCTAssertNil([oneofFoo fieldWithName:@"barString"]); 320 321 GPBOneofDescriptor *oneofBar = [descriptor oneofWithName:@"bar"]; 322 XCTAssertNotNil(oneofBar); 323 XCTAssertNil([oneofBar fieldWithName:@"fooString"]); 324 XCTAssertNotNil([oneofBar fieldWithName:@"barString"]); 325 326 // Pointer comparisons against lookups from message. 327 328 XCTAssertEqual([oneofFoo fieldWithNumber:TestOneof2_FieldNumber_FooString], 329 fooStringField); 330 XCTAssertEqual([oneofFoo fieldWithName:@"fooString"], fooStringField); 331 332 XCTAssertEqual([oneofBar fieldWithNumber:TestOneof2_FieldNumber_BarString], 333 barStringField); 334 XCTAssertEqual([oneofBar fieldWithName:@"barString"], barStringField); 335 336 // Unknown oneof not found. 337 338 XCTAssertNil([descriptor oneofWithName:@"mumble"]); 339 XCTAssertNil([descriptor oneofWithName:@"Foo"]); 340 341 // Unknown oneof item. 342 343 XCTAssertNil([oneofFoo fieldWithName:@"mumble"]); 344 XCTAssertNil([oneofFoo fieldWithNumber:666]); 345 346 // Field exists, but not in this oneof. 347 348 XCTAssertNil([oneofFoo fieldWithName:@"barString"]); 349 XCTAssertNil([oneofFoo fieldWithNumber:TestOneof2_FieldNumber_BarString]); 350 XCTAssertNil([oneofBar fieldWithName:@"fooString"]); 351 XCTAssertNil([oneofBar fieldWithNumber:TestOneof2_FieldNumber_FooString]); 352 353 // Check pointers back to the enclosing oneofs. 354 // (pointer comparisons) 355 XCTAssertEqual(fooStringField.containingOneof, oneofFoo); 356 XCTAssertEqual(barStringField.containingOneof, oneofBar); 357 GPBFieldDescriptor *bazString = 358 [descriptor fieldWithNumber:TestOneof2_FieldNumber_BazString]; 359 XCTAssertNotNil(bazString); 360 XCTAssertNil(bazString.containingOneof); 361} 362 363- (void)testExtensiondDescriptor { 364 Class msgClass = [TestAllExtensions class]; 365 Class packedMsgClass = [TestPackedExtensions class]; 366 367 // Int 368 369 GPBExtensionDescriptor *descriptor = [UnittestRoot optionalInt32Extension]; 370 XCTAssertNotNil(descriptor); 371 XCTAssertEqual(descriptor.containingMessageClass, msgClass); // ptr equality 372 XCTAssertFalse(descriptor.isPackable); 373 XCTAssertEqualObjects(descriptor.defaultValue, @0); 374 XCTAssertNil(descriptor.enumDescriptor); 375 376 descriptor = [UnittestRoot defaultInt32Extension]; 377 XCTAssertNotNil(descriptor); 378 XCTAssertEqual(descriptor.containingMessageClass, msgClass); // ptr equality 379 XCTAssertFalse(descriptor.isPackable); 380 XCTAssertEqualObjects(descriptor.defaultValue, @41); 381 XCTAssertNil(descriptor.enumDescriptor); 382 383 // Enum 384 385 descriptor = [UnittestRoot optionalNestedEnumExtension]; 386 XCTAssertNotNil(descriptor); 387 XCTAssertEqual(descriptor.containingMessageClass, msgClass); // ptr equality 388 XCTAssertFalse(descriptor.isPackable); 389 XCTAssertEqual(descriptor.defaultValue, @1); 390 XCTAssertEqualObjects(descriptor.enumDescriptor.name, @"TestAllTypes_NestedEnum"); 391 392 descriptor = [UnittestRoot defaultNestedEnumExtension]; 393 XCTAssertNotNil(descriptor); 394 XCTAssertEqual(descriptor.containingMessageClass, msgClass); // ptr equality 395 XCTAssertFalse(descriptor.isPackable); 396 XCTAssertEqual(descriptor.defaultValue, @2); 397 XCTAssertEqualObjects(descriptor.enumDescriptor.name, @"TestAllTypes_NestedEnum"); 398 399 // Message 400 401 descriptor = [UnittestRoot optionalNestedMessageExtension]; 402 XCTAssertNotNil(descriptor); 403 XCTAssertEqual(descriptor.containingMessageClass, msgClass); // ptr equality 404 XCTAssertFalse(descriptor.isPackable); 405 XCTAssertNil(descriptor.defaultValue); 406 XCTAssertNil(descriptor.enumDescriptor); 407 408 // Repeated Int 409 410 descriptor = [UnittestRoot repeatedInt32Extension]; 411 XCTAssertNotNil(descriptor); 412 XCTAssertEqual(descriptor.containingMessageClass, msgClass); // ptr equality 413 XCTAssertFalse(descriptor.isPackable); 414 XCTAssertNil(descriptor.defaultValue); 415 XCTAssertNil(descriptor.enumDescriptor); 416 417 descriptor = [UnittestRoot packedInt32Extension]; 418 XCTAssertNotNil(descriptor); 419 XCTAssertEqual(descriptor.containingMessageClass, packedMsgClass); // ptr equality 420 XCTAssertTrue(descriptor.isPackable); 421 XCTAssertNil(descriptor.defaultValue); 422 XCTAssertNil(descriptor.enumDescriptor); 423 424 // Repeated Enum 425 426 descriptor = [UnittestRoot repeatedNestedEnumExtension]; 427 XCTAssertNotNil(descriptor); 428 XCTAssertEqual(descriptor.containingMessageClass, msgClass); // ptr equality 429 XCTAssertFalse(descriptor.isPackable); 430 XCTAssertNil(descriptor.defaultValue); 431 XCTAssertEqualObjects(descriptor.enumDescriptor.name, @"TestAllTypes_NestedEnum"); 432 433 descriptor = [UnittestRoot packedEnumExtension]; 434 XCTAssertNotNil(descriptor); 435 XCTAssertEqual(descriptor.containingMessageClass, packedMsgClass); // ptr equality 436 XCTAssertTrue(descriptor.isPackable); 437 XCTAssertNil(descriptor.defaultValue); 438 XCTAssertEqualObjects(descriptor.enumDescriptor.name, @"ForeignEnum"); 439 440 // Repeated Message 441 442 descriptor = [UnittestRoot repeatedNestedMessageExtension]; 443 XCTAssertNotNil(descriptor); 444 XCTAssertEqual(descriptor.containingMessageClass, msgClass); // ptr equality 445 XCTAssertFalse(descriptor.isPackable); 446 XCTAssertNil(descriptor.defaultValue); 447 XCTAssertNil(descriptor.enumDescriptor); 448 449 // Compare (used internally for serialization). 450 451 GPBExtensionDescriptor *ext1 = [UnittestRoot optionalInt32Extension]; 452 XCTAssertEqual(ext1.fieldNumber, 1u); 453 GPBExtensionDescriptor *ext2 = [UnittestRoot optionalInt64Extension]; 454 XCTAssertEqual(ext2.fieldNumber, 2u); 455 456 XCTAssertEqual([ext1 compareByFieldNumber:ext2], NSOrderedAscending); 457 XCTAssertEqual([ext2 compareByFieldNumber:ext1], NSOrderedDescending); 458 XCTAssertEqual([ext1 compareByFieldNumber:ext1], NSOrderedSame); 459} 460 461@end 462