1// Protocol Buffers - Google's data interchange format 2// Copyright 2008 Google Inc. All rights reserved. 3// 4// Use of this source code is governed by a BSD-style 5// license that can be found in the LICENSE file or at 6// https://developers.google.com/open-source/licenses/bsd 7 8#import <objc/runtime.h> 9 10#import "GPBArray.h" 11#import "GPBArray_PackagePrivate.h" 12#import "GPBDescriptor.h" 13#import "GPBDictionary.h" 14#import "GPBDictionary_PackagePrivate.h" 15#import "GPBMessage.h" 16#import "GPBMessage_PackagePrivate.h" 17#import "GPBTestUtilities.h" 18#import "GPBUnknownField.h" 19#import "GPBUnknownFieldSet.h" 20#import "GPBUnknownFieldSet_PackagePrivate.h" 21#import "GPBUnknownField_PackagePrivate.h" 22#import "GPBUnknownFields.h" 23#import "objectivec/Tests/Unittest.pbobjc.h" 24#import "objectivec/Tests/UnittestImport.pbobjc.h" 25#import "objectivec/Tests/UnittestObjc.pbobjc.h" 26#import "objectivec/Tests/UnittestObjcOptions.pbobjc.h" 27 28// Helper class to test KVO. 29@interface GPBKVOTestObserver : NSObject { 30 id observee_; 31 NSString *keyPath_; 32} 33 34@property(nonatomic) BOOL didObserve; 35- (id)initWithObservee:(id)observee keyPath:(NSString *)keyPath; 36@end 37 38@implementation GPBKVOTestObserver 39 40@synthesize didObserve; 41 42- (id)initWithObservee:(id)observee keyPath:(NSString *)keyPath { 43 if (self = [super init]) { 44 observee_ = [observee retain]; 45 keyPath_ = [keyPath copy]; 46 [observee_ addObserver:self forKeyPath:keyPath_ options:0 context:NULL]; 47 } 48 return self; 49} 50 51- (void)dealloc { 52 [observee_ removeObserver:self forKeyPath:keyPath_]; 53 [observee_ release]; 54 [keyPath_ release]; 55 [super dealloc]; 56} 57 58- (void)observeValueForKeyPath:(NSString *)keyPath 59 ofObject:(__unused id)object 60 change:(__unused NSDictionary *)change 61 context:(__unused void *)context { 62 if ([keyPath isEqualToString:keyPath_]) { 63 self.didObserve = YES; 64 } 65} 66 67@end 68 69@interface MessageTests : GPBTestCase 70@end 71 72@implementation MessageTests 73 74// TODO: this should get split into a few files of logic junks, it is 75// a jumble of things at the moment (and the testutils have a bunch of the real 76// assertions). 77 78- (TestAllTypes *)mergeSource { 79 TestAllTypes *message = [TestAllTypes message]; 80 [message setOptionalInt32:1]; 81 [message setOptionalString:@"foo"]; 82 [message setOptionalForeignMessage:[ForeignMessage message]]; 83 [message.repeatedStringArray addObject:@"bar"]; 84 return message; 85} 86 87- (TestAllTypes *)mergeDestination { 88 TestAllTypes *message = [TestAllTypes message]; 89 [message setOptionalInt64:2]; 90 [message setOptionalString:@"baz"]; 91 ForeignMessage *foreignMessage = [ForeignMessage message]; 92 [foreignMessage setC:3]; 93 [message setOptionalForeignMessage:foreignMessage]; 94 [message.repeatedStringArray addObject:@"qux"]; 95 return message; 96} 97 98- (TestAllTypes *)mergeDestinationWithoutForeignMessageIvar { 99 TestAllTypes *message = [TestAllTypes message]; 100 [message setOptionalInt64:2]; 101 [message setOptionalString:@"baz"]; 102 [message.repeatedStringArray addObject:@"qux"]; 103 return message; 104} 105 106- (TestAllTypes *)mergeResult { 107 TestAllTypes *message = [TestAllTypes message]; 108 [message setOptionalInt32:1]; 109 [message setOptionalInt64:2]; 110 [message setOptionalString:@"foo"]; 111 ForeignMessage *foreignMessage = [ForeignMessage message]; 112 [foreignMessage setC:3]; 113 [message setOptionalForeignMessage:foreignMessage]; 114 [message.repeatedStringArray addObject:@"qux"]; 115 [message.repeatedStringArray addObject:@"bar"]; 116 return message; 117} 118 119- (TestAllTypes *)mergeResultForDestinationWithoutForeignMessageIvar { 120 TestAllTypes *message = [TestAllTypes message]; 121 [message setOptionalInt32:1]; 122 [message setOptionalInt64:2]; 123 [message setOptionalString:@"foo"]; 124 ForeignMessage *foreignMessage = [ForeignMessage message]; 125 [message setOptionalForeignMessage:foreignMessage]; 126 [message.repeatedStringArray addObject:@"qux"]; 127 [message.repeatedStringArray addObject:@"bar"]; 128 return message; 129} 130 131- (TestAllExtensions *)mergeExtensionsDestination { 132 TestAllExtensions *message = [TestAllExtensions message]; 133 [message setExtension:[UnittestRoot optionalInt32Extension] value:@5]; 134 [message setExtension:[UnittestRoot optionalStringExtension] value:@"foo"]; 135 ForeignMessage *foreignMessage = [ForeignMessage message]; 136 foreignMessage.c = 4; 137 [message setExtension:[UnittestRoot optionalForeignMessageExtension] value:foreignMessage]; 138 TestAllTypes_NestedMessage *nestedMessage = [TestAllTypes_NestedMessage message]; 139 [message setExtension:[UnittestRoot optionalNestedMessageExtension] value:nestedMessage]; 140 return message; 141} 142 143- (TestAllExtensions *)mergeExtensionsSource { 144 TestAllExtensions *message = [TestAllExtensions message]; 145 [message setExtension:[UnittestRoot optionalInt64Extension] value:@6]; 146 [message setExtension:[UnittestRoot optionalStringExtension] value:@"bar"]; 147 ForeignMessage *foreignMessage = [ForeignMessage message]; 148 [message setExtension:[UnittestRoot optionalForeignMessageExtension] value:foreignMessage]; 149 TestAllTypes_NestedMessage *nestedMessage = [TestAllTypes_NestedMessage message]; 150 nestedMessage.bb = 7; 151 [message setExtension:[UnittestRoot optionalNestedMessageExtension] value:nestedMessage]; 152 return message; 153} 154 155- (TestAllExtensions *)mergeExtensionsResult { 156 TestAllExtensions *message = [TestAllExtensions message]; 157 [message setExtension:[UnittestRoot optionalInt32Extension] value:@5]; 158 [message setExtension:[UnittestRoot optionalInt64Extension] value:@6]; 159 [message setExtension:[UnittestRoot optionalStringExtension] value:@"bar"]; 160 ForeignMessage *foreignMessage = [ForeignMessage message]; 161 foreignMessage.c = 4; 162 [message setExtension:[UnittestRoot optionalForeignMessageExtension] value:foreignMessage]; 163 TestAllTypes_NestedMessage *nestedMessage = [TestAllTypes_NestedMessage message]; 164 nestedMessage.bb = 7; 165 [message setExtension:[UnittestRoot optionalNestedMessageExtension] value:nestedMessage]; 166 return message; 167} 168 169- (void)testMergeFrom { 170 TestAllTypes *result = [[self.mergeDestination copy] autorelease]; 171 [result mergeFrom:self.mergeSource]; 172 NSData *resultData = [result data]; 173 NSData *mergeResultData = [self.mergeResult data]; 174 XCTAssertEqualObjects(resultData, mergeResultData); 175 XCTAssertEqualObjects(result, self.mergeResult); 176 177 // Test when destination does not have an Ivar (type is an object) but source 178 // has such Ivar. 179 // The result must has the Ivar which is same as the one in source. 180 result = [[self.mergeDestinationWithoutForeignMessageIvar copy] autorelease]; 181 [result mergeFrom:self.mergeSource]; 182 resultData = [result data]; 183 mergeResultData = [self.mergeResultForDestinationWithoutForeignMessageIvar data]; 184 XCTAssertEqualObjects(resultData, mergeResultData); 185 XCTAssertEqualObjects(result, self.mergeResultForDestinationWithoutForeignMessageIvar); 186 187 // Test when destination is empty. 188 // The result must is same as the source. 189 result = [TestAllTypes message]; 190 [result mergeFrom:self.mergeSource]; 191 resultData = [result data]; 192 mergeResultData = [self.mergeSource data]; 193 XCTAssertEqualObjects(resultData, mergeResultData); 194 XCTAssertEqualObjects(result, self.mergeSource); 195} 196 197- (void)testMergeFromWithExtensions { 198 TestAllExtensions *result = [self mergeExtensionsDestination]; 199 [result mergeFrom:[self mergeExtensionsSource]]; 200 NSData *resultData = [result data]; 201 NSData *mergeResultData = [[self mergeExtensionsResult] data]; 202 XCTAssertEqualObjects(resultData, mergeResultData); 203 XCTAssertEqualObjects(result, [self mergeExtensionsResult]); 204 205 // Test merging from data. 206 result = [self mergeExtensionsDestination]; 207 NSData *data = [[self mergeExtensionsSource] data]; 208 XCTAssertNotNil(data); 209 NSError *error = nil; 210 XCTAssertTrue([result mergeFromData:data 211 extensionRegistry:[UnittestRoot extensionRegistry] 212 error:&error]); 213 XCTAssertNil(error); 214 resultData = [result data]; 215 XCTAssertEqualObjects(resultData, mergeResultData); 216 XCTAssertEqualObjects(result, [self mergeExtensionsResult]); 217} 218 219- (void)testIsEquals { 220 TestAllTypes *result = [[self.mergeDestination copy] autorelease]; 221 [result mergeFrom:self.mergeSource]; 222 XCTAssertEqualObjects(result.data, self.mergeResult.data); 223 XCTAssertEqualObjects(result, self.mergeResult); 224 TestAllTypes *result2 = [[self.mergeDestination copy] autorelease]; 225 XCTAssertNotEqualObjects(result2.data, self.mergeResult.data); 226 XCTAssertNotEqualObjects(result2, self.mergeResult); 227} 228 229// ================================================================= 230// Required-field-related tests. 231 232- (TestRequired *)testRequiredInitialized { 233 TestRequired *message = [TestRequired message]; 234 [message setA:1]; 235 [message setB:2]; 236 [message setC:3]; 237 return message; 238} 239 240- (void)testRequired { 241 TestRequired *message = [TestRequired message]; 242 243 XCTAssertFalse(message.initialized); 244 [message setA:1]; 245 XCTAssertFalse(message.initialized); 246 [message setB:1]; 247 XCTAssertFalse(message.initialized); 248 [message setC:1]; 249 XCTAssertTrue(message.initialized); 250} 251 252- (void)testRequiredForeign { 253 TestRequiredForeign *message = [TestRequiredForeign message]; 254 255 XCTAssertTrue(message.initialized); 256 257 [message setOptionalMessage:[TestRequired message]]; 258 XCTAssertFalse(message.initialized); 259 260 [message setOptionalMessage:self.testRequiredInitialized]; 261 XCTAssertTrue(message.initialized); 262 263 [message.repeatedMessageArray addObject:[TestRequired message]]; 264 XCTAssertFalse(message.initialized); 265 266 [message.repeatedMessageArray removeAllObjects]; 267 [message.repeatedMessageArray addObject:self.testRequiredInitialized]; 268 XCTAssertTrue(message.initialized); 269} 270 271- (void)testRequiredExtension { 272 TestAllExtensions *message = [TestAllExtensions message]; 273 274 XCTAssertTrue(message.initialized); 275 276 [message setExtension:[TestRequired single] value:[TestRequired message]]; 277 XCTAssertFalse(message.initialized); 278 279 [message setExtension:[TestRequired single] value:self.testRequiredInitialized]; 280 XCTAssertTrue(message.initialized); 281 282 [message addExtension:[TestRequired multi] value:[TestRequired message]]; 283 XCTAssertFalse(message.initialized); 284 285 [message setExtension:[TestRequired multi] index:0 value:self.testRequiredInitialized]; 286 XCTAssertTrue(message.initialized); 287} 288 289- (void)testDataFromUninitialized { 290 TestRequired *message = [TestRequired message]; 291 NSData *data = [message data]; 292 // In DEBUG, the data generation will fail, but in non DEBUG, it passes 293 // because the check isn't done (for speed). 294#ifdef DEBUG 295 XCTAssertNil(data); 296#else 297 XCTAssertNotNil(data); 298 XCTAssertFalse(message.initialized); 299#endif // DEBUG 300} 301 302- (void)testInitialized { 303 // We're mostly testing that no exception is thrown. 304 TestRequired *message = [TestRequired message]; 305 XCTAssertFalse(message.initialized); 306} 307 308- (void)testDataFromNestedUninitialized { 309 TestRequiredForeign *message = [TestRequiredForeign message]; 310 [message setOptionalMessage:[TestRequired message]]; 311 [message.repeatedMessageArray addObject:[TestRequired message]]; 312 [message.repeatedMessageArray addObject:[TestRequired message]]; 313 NSData *data = [message data]; 314 // In DEBUG, the data generation will fail, but in non DEBUG, it passes 315 // because the check isn't done (for speed). 316#ifdef DEBUG 317 XCTAssertNil(data); 318#else 319 XCTAssertNotNil(data); 320 XCTAssertFalse(message.initialized); 321#endif // DEBUG 322} 323 324- (void)testNestedInitialized { 325 // We're mostly testing that no exception is thrown. 326 327 TestRequiredForeign *message = [TestRequiredForeign message]; 328 [message setOptionalMessage:[TestRequired message]]; 329 [message.repeatedMessageArray addObject:[TestRequired message]]; 330 [message.repeatedMessageArray addObject:[TestRequired message]]; 331 332 XCTAssertFalse(message.initialized); 333} 334 335- (void)testParseUninitialized { 336 NSError *error = nil; 337 TestRequired *msg = [TestRequired parseFromData:GPBEmptyNSData() error:&error]; 338 // In DEBUG, the parse will fail, but in non DEBUG, it passes because 339 // the check isn't done (for speed). 340#ifdef DEBUG 341 XCTAssertNil(msg); 342 XCTAssertNotNil(error); 343 XCTAssertEqualObjects(error.domain, GPBMessageErrorDomain); 344 XCTAssertEqual(error.code, GPBMessageErrorCodeMissingRequiredField); 345#else 346 XCTAssertNotNil(msg); 347 XCTAssertNil(error); 348 XCTAssertFalse(msg.initialized); 349#endif // DEBUG 350} 351 352#pragma clang diagnostic push 353#pragma clang diagnostic ignored "-Wdeprecated-declarations" 354 355- (void)testCoding { 356 GPBMessage *original = [self mergeResult]; 357 NSData *data = [NSKeyedArchiver archivedDataWithRootObject:original]; 358 id unarchivedObject = [NSKeyedUnarchiver unarchiveObjectWithData:data]; 359 360 XCTAssertEqualObjects(unarchivedObject, original); 361 362 // Intentionally doing a pointer comparison. 363 XCTAssertNotEqual(unarchivedObject, original); 364} 365 366- (void)testSecureCoding { 367 GPBMessage *original = [self mergeResult]; 368 369 NSString *key = @"testing123"; 370 371 NSMutableData *data = [NSMutableData data]; 372 NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; 373 [archiver setRequiresSecureCoding:YES]; 374 [archiver encodeObject:original forKey:key]; 375 [archiver finishEncoding]; 376 377 NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; 378 [unarchiver setRequiresSecureCoding:YES]; 379 id unarchivedObject = [unarchiver decodeObjectOfClass:[GPBMessage class] forKey:key]; 380 [unarchiver finishDecoding]; 381 382 XCTAssertEqualObjects(unarchivedObject, original); 383 384 // Intentionally doing a pointer comparison. 385 XCTAssertNotEqual(unarchivedObject, original); 386} 387 388#pragma clang diagnostic pop 389 390- (void)testObjectReset { 391 // Tests a failure where clearing out defaults values caused an over release. 392 TestAllTypes *message = [TestAllTypes message]; 393 message.hasOptionalNestedMessage = NO; 394 [message setOptionalNestedMessage:[TestAllTypes_NestedMessage message]]; 395 message.hasOptionalNestedMessage = NO; 396 [message setOptionalNestedMessage:[TestAllTypes_NestedMessage message]]; 397 [message setOptionalNestedMessage:nil]; 398 message.hasOptionalNestedMessage = NO; 399} 400 401- (void)testSettingHasToYes { 402 TestAllTypes *message = [TestAllTypes message]; 403 XCTAssertThrows([message setHasOptionalNestedMessage:YES]); 404} 405 406- (void)testRoot { 407 XCTAssertNotNil([UnittestRoot extensionRegistry]); 408} 409 410- (void)testGPBMessageSize { 411 // See the note in GPBMessage_PackagePrivate.h about why we want to keep the 412 // base instance size pointer size aligned. 413 size_t messageSize = class_getInstanceSize([GPBMessage class]); 414 XCTAssertEqual((messageSize % sizeof(void *)), (size_t)0, 415 @"Base size isn't pointer size aligned"); 416 417 // Since we add storage ourselves (see +allocWithZone: in GPBMessage), confirm 418 // that the size of some generated classes is still the same as the base for 419 // that logic to work as desired. 420 size_t testMessageSize = class_getInstanceSize([TestAllTypes class]); 421 XCTAssertEqual(testMessageSize, messageSize); 422} 423 424- (void)testInit { 425 TestAllTypes *message = [TestAllTypes message]; 426 [self assertClear:message]; 427} 428 429- (void)testAccessors { 430 TestAllTypes *message = [TestAllTypes message]; 431 [self setAllFields:message repeatedCount:kGPBDefaultRepeatCount]; 432 [self assertAllFieldsSet:message repeatedCount:kGPBDefaultRepeatCount]; 433} 434 435- (void)testKVC_ValueForKey { 436 TestAllTypes *message = [TestAllTypes message]; 437 [self setAllFields:message repeatedCount:kGPBDefaultRepeatCount]; 438 [self assertAllFieldsKVCMatch:message]; 439} 440 441- (void)testKVC_SetValue_ForKey { 442 TestAllTypes *message = [TestAllTypes message]; 443 [self setAllFieldsViaKVC:message repeatedCount:kGPBDefaultRepeatCount]; 444 [self assertAllFieldsKVCMatch:message]; 445 [self assertAllFieldsSet:message repeatedCount:kGPBDefaultRepeatCount]; 446 [self assertAllFieldsKVCMatch:message]; 447} 448 449- (void)testKVOBasic { 450 TestAllTypes *message = [TestAllTypes message]; 451 GPBKVOTestObserver *observer = 452 [[[GPBKVOTestObserver alloc] initWithObservee:message keyPath:@"optionalString"] autorelease]; 453 XCTAssertFalse(observer.didObserve); 454 message.defaultString = @"Hello"; 455 XCTAssertFalse(observer.didObserve); 456 message.optionalString = @"Hello"; 457 XCTAssertTrue(observer.didObserve); 458} 459 460- (void)testKVOAutocreate { 461 TestAllTypes *message = [TestAllTypes message]; 462 GPBKVOTestObserver *autocreateObserver = 463 [[[GPBKVOTestObserver alloc] initWithObservee:message 464 keyPath:@"optionalImportMessage"] autorelease]; 465 GPBKVOTestObserver *innerFieldObserver = 466 [[[GPBKVOTestObserver alloc] initWithObservee:message 467 keyPath:@"optionalImportMessage.d"] autorelease]; 468 XCTAssertFalse(autocreateObserver.didObserve); 469 XCTAssertFalse(innerFieldObserver.didObserve); 470 471 int a = message.optionalImportMessage.d; 472 XCTAssertEqual(a, 0); 473 474 // Autocreation of fields is not observed by KVO when getting values. 475 XCTAssertFalse(autocreateObserver.didObserve); 476 XCTAssertFalse(innerFieldObserver.didObserve); 477 478 message.optionalImportMessage.d = 2; 479 480 // Autocreation of fields is not observed by KVO. 481 // This is undefined behavior. The library makes no guarantees with regards 482 // to KVO firing if an autocreation occurs as part of a setter. 483 // This test exists just to be aware if the behavior changes. 484 XCTAssertFalse(autocreateObserver.didObserve); 485 486 // Values set inside of an autocreated field are observed. 487 XCTAssertTrue(innerFieldObserver.didObserve); 488 489 // Explicit setting of a message field is observed. 490 message.optionalImportMessage = [ImportMessage message]; 491 XCTAssertTrue(autocreateObserver.didObserve); 492} 493 494- (void)testDescription { 495 // No real test, just exercise code 496 TestAllTypes *message = [TestAllTypes message]; 497 [self setAllFields:message repeatedCount:kGPBDefaultRepeatCount]; 498 499#pragma clang diagnostic push 500#pragma clang diagnostic ignored "-Wdeprecated-declarations" 501 GPBUnknownFieldSet *unknownFields = [[[GPBUnknownFieldSet alloc] init] autorelease]; 502 GPBUnknownField *field = [[[GPBUnknownField alloc] initWithNumber:2] autorelease]; 503 [field addVarint:2]; 504 [unknownFields addField:field]; 505 field = [[[GPBUnknownField alloc] initWithNumber:3] autorelease]; 506 [field addVarint:4]; 507 [unknownFields addField:field]; 508 509 [message setUnknownFields:unknownFields]; 510#pragma clang diagnostic pop 511 512 GPBUnknownFields *ufs = [[[GPBUnknownFields alloc] init] autorelease]; 513 [ufs addFieldNumber:1234 fixed32:1234]; 514 [ufs addFieldNumber:2345 varint:54321]; 515 XCTAssertTrue([message mergeUnknownFields:ufs extensionRegistry:nil error:NULL]); 516 517 NSString *description = [message description]; 518 XCTAssertGreaterThan([description length], 0U); 519 520 GPBMessage *message2 = [TestAllExtensions message]; 521 [message2 setExtension:[UnittestRoot optionalInt32Extension] value:@1]; 522 523 [message2 addExtension:[UnittestRoot repeatedInt32Extension] value:@2]; 524 525 description = [message2 description]; 526 XCTAssertGreaterThan([description length], 0U); 527} 528 529- (void)testSetter { 530 // Test to make sure that if we set a value that has a default value 531 // with the default, that the has is set, and the value gets put into the 532 // message correctly. 533 TestAllTypes *message = [TestAllTypes message]; 534 GPBDescriptor *descriptor = [[message class] descriptor]; 535 XCTAssertNotNil(descriptor); 536 GPBFieldDescriptor *fieldDescriptor = [descriptor fieldWithName:@"defaultInt32"]; 537 XCTAssertNotNil(fieldDescriptor); 538 GPBGenericValue defaultValue = [fieldDescriptor defaultValue]; 539 [message setDefaultInt32:defaultValue.valueInt32]; 540 XCTAssertTrue(message.hasDefaultInt32); 541 XCTAssertEqual(message.defaultInt32, defaultValue.valueInt32); 542 543 // Do the same thing with an object type. 544 message = [TestAllTypes message]; 545 fieldDescriptor = [descriptor fieldWithName:@"defaultString"]; 546 XCTAssertNotNil(fieldDescriptor); 547 defaultValue = [fieldDescriptor defaultValue]; 548 [message setDefaultString:defaultValue.valueString]; 549 XCTAssertTrue(message.hasDefaultString); 550 XCTAssertEqualObjects(message.defaultString, defaultValue.valueString); 551 552 // Test default string type. 553 message = [TestAllTypes message]; 554 XCTAssertEqualObjects(message.defaultString, @"hello"); 555 XCTAssertFalse(message.hasDefaultString); 556 fieldDescriptor = [descriptor fieldWithName:@"defaultString"]; 557 XCTAssertNotNil(fieldDescriptor); 558 defaultValue = [fieldDescriptor defaultValue]; 559 [message setDefaultString:defaultValue.valueString]; 560 XCTAssertEqualObjects(message.defaultString, @"hello"); 561 XCTAssertTrue(message.hasDefaultString); 562 [message setDefaultString:nil]; 563 XCTAssertEqualObjects(message.defaultString, @"hello"); 564 XCTAssertFalse(message.hasDefaultString); 565 message.hasDefaultString = NO; 566 XCTAssertFalse(message.hasDefaultString); 567 XCTAssertEqualObjects(message.defaultString, @"hello"); 568 569 // Test default bytes type. 570 NSData *defaultBytes = [@"world" dataUsingEncoding:NSUTF8StringEncoding]; 571 XCTAssertEqualObjects(message.defaultBytes, defaultBytes); 572 XCTAssertFalse(message.hasDefaultString); 573 fieldDescriptor = [descriptor fieldWithName:@"defaultBytes"]; 574 XCTAssertNotNil(fieldDescriptor); 575 defaultValue = [fieldDescriptor defaultValue]; 576 [message setDefaultBytes:defaultValue.valueData]; 577 XCTAssertEqualObjects(message.defaultBytes, defaultBytes); 578 XCTAssertTrue(message.hasDefaultBytes); 579 [message setDefaultBytes:nil]; 580 XCTAssertEqualObjects(message.defaultBytes, defaultBytes); 581 XCTAssertFalse(message.hasDefaultBytes); 582 message.hasDefaultBytes = NO; 583 XCTAssertFalse(message.hasDefaultBytes); 584 XCTAssertEqualObjects(message.defaultBytes, defaultBytes); 585 586 // Test optional string. 587 XCTAssertFalse(message.hasOptionalString); 588 XCTAssertEqualObjects(message.optionalString, @""); 589 XCTAssertFalse(message.hasOptionalString); 590 message.optionalString = nil; 591 XCTAssertFalse(message.hasOptionalString); 592 XCTAssertEqualObjects(message.optionalString, @""); 593 NSString *string = @"string"; 594 message.optionalString = string; 595 XCTAssertEqualObjects(message.optionalString, string); 596 XCTAssertTrue(message.hasOptionalString); 597 message.optionalString = nil; 598 XCTAssertFalse(message.hasOptionalString); 599 XCTAssertEqualObjects(message.optionalString, @""); 600 601 // Test optional data. 602 XCTAssertFalse(message.hasOptionalBytes); 603 XCTAssertEqualObjects(message.optionalBytes, GPBEmptyNSData()); 604 XCTAssertFalse(message.hasOptionalBytes); 605 message.optionalBytes = nil; 606 XCTAssertFalse(message.hasOptionalBytes); 607 XCTAssertEqualObjects(message.optionalBytes, GPBEmptyNSData()); 608 NSData *data = [@"bytes" dataUsingEncoding:NSUTF8StringEncoding]; 609 message.optionalBytes = data; 610 XCTAssertEqualObjects(message.optionalBytes, data); 611 XCTAssertTrue(message.hasOptionalBytes); 612 message.optionalBytes = nil; 613 XCTAssertFalse(message.hasOptionalBytes); 614 XCTAssertEqualObjects(message.optionalBytes, GPBEmptyNSData()); 615 616 // Test lazy message setting 617 XCTAssertFalse(message.hasOptionalLazyMessage); 618 XCTAssertNotNil(message.optionalLazyMessage); 619 XCTAssertFalse(message.hasOptionalLazyMessage); 620 message.hasOptionalLazyMessage = NO; 621 XCTAssertFalse(message.hasOptionalLazyMessage); 622 XCTAssertNotNil(message.optionalLazyMessage); 623 XCTAssertFalse(message.hasOptionalLazyMessage); 624 message.optionalLazyMessage = nil; 625 XCTAssertFalse(message.hasOptionalLazyMessage); 626 627 // Test nested messages 628 XCTAssertFalse(message.hasOptionalLazyMessage); 629 message.optionalLazyMessage.bb = 1; 630 XCTAssertTrue(message.hasOptionalLazyMessage); 631 XCTAssertEqual(message.optionalLazyMessage.bb, 1); 632 XCTAssertNotNil(message.optionalLazyMessage); 633 message.optionalLazyMessage = nil; 634 XCTAssertFalse(message.hasOptionalLazyMessage); 635 XCTAssertEqual(message.optionalLazyMessage.bb, 0); 636 XCTAssertFalse(message.hasOptionalLazyMessage); 637 XCTAssertNotNil(message.optionalLazyMessage); 638 639 // -testDefaultSubMessages tests the "defaulting" handling of fields 640 // containing messages. 641} 642 643- (void)testRepeatedSetters { 644 TestAllTypes *message = [TestAllTypes message]; 645 [self setAllFields:message repeatedCount:kGPBDefaultRepeatCount]; 646 [self modifyRepeatedFields:message]; 647 [self assertRepeatedFieldsModified:message repeatedCount:kGPBDefaultRepeatCount]; 648} 649 650- (void)testClear { 651 TestAllTypes *message = [TestAllTypes message]; 652 [self setAllFields:message repeatedCount:kGPBDefaultRepeatCount]; 653 [self clearAllFields:message]; 654 [self assertClear:message]; 655 TestAllTypes *message2 = [TestAllTypes message]; 656 XCTAssertEqualObjects(message, message2); 657} 658 659- (void)testClearKVC { 660 TestAllTypes *message = [TestAllTypes message]; 661 [self setAllFields:message repeatedCount:kGPBDefaultRepeatCount]; 662 [self clearAllFields:message]; 663 [self assertClear:message]; 664 [self assertClearKVC:message]; 665} 666 667- (void)testClearExtension { 668 // clearExtension() is not actually used in TestUtil, so try it manually. 669 GPBMessage *message1 = [TestAllExtensions message]; 670 [message1 setExtension:[UnittestRoot optionalInt32Extension] value:@1]; 671 672 XCTAssertTrue([message1 hasExtension:[UnittestRoot optionalInt32Extension]]); 673 [message1 clearExtension:[UnittestRoot optionalInt32Extension]]; 674 XCTAssertFalse([message1 hasExtension:[UnittestRoot optionalInt32Extension]]); 675 676 GPBMessage *message2 = [TestAllExtensions message]; 677 [message2 addExtension:[UnittestRoot repeatedInt32Extension] value:@1]; 678 679 XCTAssertEqual([[message2 getExtension:[UnittestRoot repeatedInt32Extension]] count], 680 (NSUInteger)1); 681 [message2 clearExtension:[UnittestRoot repeatedInt32Extension]]; 682 XCTAssertEqual([[message2 getExtension:[UnittestRoot repeatedInt32Extension]] count], 683 (NSUInteger)0); 684 685 // Clearing an unset extension field shouldn't make the target message 686 // visible. 687 GPBMessage *message3 = [TestAllExtensions message]; 688 GPBMessage *extension_msg = [message3 getExtension:[UnittestObjcRoot recursiveExtension]]; 689 XCTAssertFalse([message3 hasExtension:[UnittestObjcRoot recursiveExtension]]); 690 [extension_msg clearExtension:[UnittestRoot optionalInt32Extension]]; 691 XCTAssertFalse([message3 hasExtension:[UnittestObjcRoot recursiveExtension]]); 692} 693 694- (void)testDefaultingSubMessages { 695 TestAllTypes *message = [TestAllTypes message]; 696 697 // Initially they should all not have values. 698 699 XCTAssertFalse(message.hasOptionalGroup); 700 XCTAssertFalse(message.hasOptionalNestedMessage); 701 XCTAssertFalse(message.hasOptionalForeignMessage); 702 XCTAssertFalse(message.hasOptionalImportMessage); 703 XCTAssertFalse(message.hasOptionalPublicImportMessage); 704 XCTAssertFalse(message.hasOptionalLazyMessage); 705 706 // They should auto create something when fetched. 707 708 TestAllTypes_OptionalGroup *optionalGroup = [message.optionalGroup retain]; 709 TestAllTypes_NestedMessage *optionalNestedMessage = [message.optionalNestedMessage retain]; 710 ForeignMessage *optionalForeignMessage = [message.optionalForeignMessage retain]; 711 ImportMessage *optionalImportMessage = [message.optionalImportMessage retain]; 712 PublicImportMessage *optionalPublicImportMessage = [message.optionalPublicImportMessage retain]; 713 TestAllTypes_NestedMessage *optionalLazyMessage = [message.optionalLazyMessage retain]; 714 715 XCTAssertNotNil(optionalGroup); 716 XCTAssertNotNil(optionalNestedMessage); 717 XCTAssertNotNil(optionalForeignMessage); 718 XCTAssertNotNil(optionalImportMessage); 719 XCTAssertNotNil(optionalPublicImportMessage); 720 XCTAssertNotNil(optionalLazyMessage); 721 722 // Although they were created, they should not respond to hasValue until that 723 // submessage is mutated. 724 725 XCTAssertFalse(message.hasOptionalGroup); 726 XCTAssertFalse(message.hasOptionalNestedMessage); 727 XCTAssertFalse(message.hasOptionalForeignMessage); 728 XCTAssertFalse(message.hasOptionalImportMessage); 729 XCTAssertFalse(message.hasOptionalPublicImportMessage); 730 XCTAssertFalse(message.hasOptionalLazyMessage); 731 732 // And they set that value back in to the message since the value created was 733 // mutable (so a second fetch should give the same object). 734 735 XCTAssertEqual(message.optionalGroup, optionalGroup); 736 XCTAssertEqual(message.optionalNestedMessage, optionalNestedMessage); 737 XCTAssertEqual(message.optionalForeignMessage, optionalForeignMessage); 738 XCTAssertEqual(message.optionalImportMessage, optionalImportMessage); 739 XCTAssertEqual(message.optionalPublicImportMessage, optionalPublicImportMessage); 740 XCTAssertEqual(message.optionalLazyMessage, optionalLazyMessage); 741 742 // And the default objects for a second message should be distinct (again, 743 // since they are mutable, each needs their own copy). 744 745 TestAllTypes *message2 = [TestAllTypes message]; 746 747 // Intentionally doing a pointer comparison. 748 XCTAssertNotEqual(message2.optionalGroup, optionalGroup); 749 XCTAssertNotEqual(message2.optionalNestedMessage, optionalNestedMessage); 750 XCTAssertNotEqual(message2.optionalForeignMessage, optionalForeignMessage); 751 XCTAssertNotEqual(message2.optionalImportMessage, optionalImportMessage); 752 XCTAssertNotEqual(message2.optionalPublicImportMessage, optionalPublicImportMessage); 753 XCTAssertNotEqual(message2.optionalLazyMessage, optionalLazyMessage); 754 755 // Setting the values to nil will clear the has flag, and on next access you 756 // get back new submessages. 757 758 message.optionalGroup = nil; 759 message.optionalNestedMessage = nil; 760 message.optionalForeignMessage = nil; 761 message.optionalImportMessage = nil; 762 message.optionalPublicImportMessage = nil; 763 message.optionalLazyMessage = nil; 764 765 XCTAssertFalse(message.hasOptionalGroup); 766 XCTAssertFalse(message.hasOptionalNestedMessage); 767 XCTAssertFalse(message.hasOptionalForeignMessage); 768 XCTAssertFalse(message.hasOptionalImportMessage); 769 XCTAssertFalse(message.hasOptionalPublicImportMessage); 770 XCTAssertFalse(message.hasOptionalLazyMessage); 771 772 // Intentionally doing a pointer comparison. 773 XCTAssertNotEqual(message.optionalGroup, optionalGroup); 774 XCTAssertNotEqual(message.optionalNestedMessage, optionalNestedMessage); 775 XCTAssertNotEqual(message.optionalForeignMessage, optionalForeignMessage); 776 XCTAssertNotEqual(message.optionalImportMessage, optionalImportMessage); 777 XCTAssertNotEqual(message.optionalPublicImportMessage, optionalPublicImportMessage); 778 XCTAssertNotEqual(message.optionalLazyMessage, optionalLazyMessage); 779 780 [optionalGroup release]; 781 [optionalNestedMessage release]; 782 [optionalForeignMessage release]; 783 [optionalImportMessage release]; 784 [optionalPublicImportMessage release]; 785 [optionalLazyMessage release]; 786} 787 788- (void)testMultiplePointersToAutocreatedMessage { 789 // Multiple objects pointing to the same autocreated message. 790 TestAllTypes *message = [TestAllTypes message]; 791 TestAllTypes *message2 = [TestAllTypes message]; 792 message2.optionalGroup = message.optionalGroup; 793 XCTAssertTrue([message2 hasOptionalGroup]); 794 XCTAssertFalse([message hasOptionalGroup]); 795 message2.optionalGroup.a = 42; 796 XCTAssertTrue([message hasOptionalGroup]); 797 XCTAssertTrue([message2 hasOptionalGroup]); 798} 799 800- (void)testCopyWithAutocreatedMessage { 801 // Mutable copy should not copy autocreated messages. 802 TestAllTypes *message = [TestAllTypes message]; 803 message.optionalGroup.a = 42; 804 XCTAssertNotNil(message.optionalNestedMessage); 805 TestAllTypes *message2 = [[message copy] autorelease]; 806 XCTAssertTrue([message2 hasOptionalGroup]); 807 XCTAssertFalse([message2 hasOptionalNestedMessage]); 808 809 // Intentionally doing a pointer comparison. 810 XCTAssertNotEqual(message.optionalNestedMessage, message2.optionalNestedMessage); 811} 812 813- (void)testClearAutocreatedSubmessage { 814 // Call clear on an intermediate submessage should cause it to get recreated 815 // on the next call. 816 TestRecursiveMessage *message = [TestRecursiveMessage message]; 817 TestRecursiveMessage *message_inner = [message.a.a.a retain]; 818 XCTAssertNotNil(message_inner); 819 XCTAssertTrue(GPBWasMessageAutocreatedBy(message_inner, message.a.a)); 820 [message.a.a clear]; 821 XCTAssertFalse(GPBWasMessageAutocreatedBy(message_inner, message.a.a)); 822 823 // Intentionally doing a pointer comparison. 824 XCTAssertNotEqual(message.a.a.a, message_inner); 825 [message_inner release]; 826} 827 828- (void)testRetainAutocreatedSubmessage { 829 // Should be able to retain autocreated submessage while the creator is 830 // dealloced. 831 TestAllTypes *message = [TestAllTypes message]; 832 833 ForeignMessage *subMessage; 834 @autoreleasepool { 835 TestAllTypes *message2 = [TestAllTypes message]; 836 subMessage = message2.optionalForeignMessage; // Autocreated 837 message.optionalForeignMessage = subMessage; 838 XCTAssertTrue(GPBWasMessageAutocreatedBy(message.optionalForeignMessage, message2)); 839 } 840 841 // Should be the same object, and should still be live. 842 XCTAssertEqual(message.optionalForeignMessage, subMessage); 843 XCTAssertNotNil([subMessage description]); 844} 845 846- (void)testSetNilAutocreatedSubmessage { 847 TestRecursiveMessage *message = [TestRecursiveMessage message]; 848 TestRecursiveMessage *message_inner = [message.a.a retain]; 849 XCTAssertFalse([message hasA]); 850 XCTAssertFalse([message.a hasA]); 851 message.a.a = nil; 852 853 // |message.a| has to be made visible, but |message.a.a| was set to nil so 854 // shouldn't be. 855 XCTAssertTrue([message hasA]); 856 XCTAssertFalse([message.a hasA]); 857 858 // Setting submessage to nil should cause it to lose its creator. 859 XCTAssertFalse(GPBWasMessageAutocreatedBy(message_inner, message.a)); 860 861 // After setting to nil, getting it again should create a new autocreated 862 // message. 863 // Intentionally doing a pointer comparison. 864 XCTAssertNotEqual(message.a.a, message_inner); 865 866 [message_inner release]; 867} 868 869- (void)testSetDoesntHaveAutocreatedSubmessage { 870 // Clearing submessage (set has == NO) should NOT cause it to lose its 871 // creator. 872 TestAllTypes *message = [TestAllTypes message]; 873 TestAllTypes_NestedMessage *nestedMessage = message.optionalNestedMessage; 874 XCTAssertFalse([message hasOptionalNestedMessage]); 875 [message setHasOptionalNestedMessage:NO]; 876 XCTAssertFalse([message hasOptionalNestedMessage]); 877 XCTAssertEqual(message.optionalNestedMessage, nestedMessage); 878} 879 880- (void)testSetAutocreatedMessageBecomesVisible { 881 // Setting a value should cause the submessage to appear to its creator. 882 // Test this several levels deep. 883 TestRecursiveMessage *message = [TestRecursiveMessage message]; 884 message.a.a.a.a.i = 42; 885 XCTAssertTrue([message hasA]); 886 XCTAssertTrue([message.a hasA]); 887 XCTAssertTrue([message.a.a hasA]); 888 XCTAssertTrue([message.a.a.a hasA]); 889 XCTAssertFalse([message.a.a.a.a hasA]); 890 XCTAssertEqual(message.a.a.a.a.i, 42); 891} 892 893- (void)testClearUnsetFieldOfAutocreatedMessage { 894 // Clearing an unset field should not cause the submessage to appear to its 895 // creator. 896 TestRecursiveMessage *message = [TestRecursiveMessage message]; 897 message.a.a.a.a.hasI = NO; 898 XCTAssertFalse([message hasA]); 899 XCTAssertFalse([message.a hasA]); 900 XCTAssertFalse([message.a.a hasA]); 901 XCTAssertFalse([message.a.a.a hasA]); 902} 903 904- (void)testAutocreatedSubmessageAssignSkip { 905 TestRecursiveMessage *message = [TestRecursiveMessage message]; 906 TestRecursiveMessage *messageLevel1 = [message.a retain]; 907 TestRecursiveMessage *messageLevel2 = [message.a.a retain]; 908 TestRecursiveMessage *messageLevel3 = [message.a.a.a retain]; 909 TestRecursiveMessage *messageLevel4 = [message.a.a.a.a retain]; 910 XCTAssertTrue(GPBWasMessageAutocreatedBy(messageLevel1, message)); 911 XCTAssertTrue(GPBWasMessageAutocreatedBy(messageLevel2, messageLevel1)); 912 XCTAssertTrue(GPBWasMessageAutocreatedBy(messageLevel3, messageLevel2)); 913 XCTAssertTrue(GPBWasMessageAutocreatedBy(messageLevel4, messageLevel3)); 914 915 // Test skipping over an autocreated submessage and ensure it gets unset. 916 message.a = message.a.a; 917 XCTAssertEqual(message.a, messageLevel2); 918 XCTAssertTrue([message hasA]); 919 XCTAssertEqual(message.a.a, messageLevel3); 920 XCTAssertFalse([message.a hasA]); 921 XCTAssertEqual(message.a.a.a, messageLevel4); 922 XCTAssertFalse(GPBWasMessageAutocreatedBy(messageLevel1, 923 message)); // Because it was orphaned. 924 XCTAssertTrue(GPBWasMessageAutocreatedBy(messageLevel2, messageLevel1)); 925 XCTAssertTrue(GPBWasMessageAutocreatedBy(messageLevel3, messageLevel2)); 926 927 [messageLevel1 release]; 928 [messageLevel2 release]; 929 [messageLevel3 release]; 930 [messageLevel4 release]; 931} 932 933- (void)testAutocreatedSubmessageAssignLoop { 934 TestRecursiveMessage *message = [TestRecursiveMessage message]; 935 TestRecursiveMessage *messageLevel1 = [message.a retain]; 936 TestRecursiveMessage *messageLevel2 = [message.a.a retain]; 937 TestRecursiveMessage *messageLevel3 = [message.a.a.a retain]; 938 TestRecursiveMessage *messageLevel4 = [message.a.a.a.a retain]; 939 XCTAssertTrue(GPBWasMessageAutocreatedBy(messageLevel1, message)); 940 XCTAssertTrue(GPBWasMessageAutocreatedBy(messageLevel2, messageLevel1)); 941 XCTAssertTrue(GPBWasMessageAutocreatedBy(messageLevel3, messageLevel2)); 942 XCTAssertTrue(GPBWasMessageAutocreatedBy(messageLevel4, messageLevel3)); 943 944 // Test a property with a loop. You'd never do this but at least ensure the 945 // autocreated submessages behave sanely. 946 message.a.a = message.a; 947 XCTAssertTrue([message hasA]); 948 XCTAssertEqual(message.a, messageLevel1); 949 XCTAssertTrue([message.a hasA]); 950 XCTAssertEqual(message.a.a, messageLevel1); 951 XCTAssertTrue([message.a.a hasA]); 952 XCTAssertEqual(message.a.a.a, messageLevel1); 953 XCTAssertFalse(GPBWasMessageAutocreatedBy(messageLevel1, 954 message)); // Because it was assigned. 955 XCTAssertFalse(GPBWasMessageAutocreatedBy(messageLevel2, 956 messageLevel1)); // Because it was orphaned. 957 XCTAssertFalse([messageLevel2 hasA]); 958 959 // Break the retain loop. 960 message.a.a = nil; 961 XCTAssertTrue([message hasA]); 962 XCTAssertFalse([message.a hasA]); 963 964 [messageLevel1 release]; 965 [messageLevel2 release]; 966 [messageLevel3 release]; 967 [messageLevel4 release]; 968} 969 970- (void)testSetAutocreatedSubmessage { 971 // Setting autocreated submessage to another value should cause the old one to 972 // lose its creator. 973 TestAllTypes *message = [TestAllTypes message]; 974 TestAllTypes_NestedMessage *nestedMessage = [message.optionalNestedMessage retain]; 975 976 message.optionalNestedMessage = [TestAllTypes_NestedMessage message]; 977 XCTAssertTrue([message hasOptionalNestedMessage]); 978 XCTAssertTrue(message.optionalNestedMessage != nestedMessage); 979 XCTAssertFalse(GPBWasMessageAutocreatedBy(nestedMessage, message)); 980 981 [nestedMessage release]; 982} 983 984- (void)testAutocreatedUnknownFields { 985#pragma clang diagnostic push 986#pragma clang diagnostic ignored "-Wdeprecated-declarations" 987 988 // Doing anything with (except reading) unknown fields should cause the 989 // submessage to become visible. 990 TestAllTypes *message = [TestAllTypes message]; 991 XCTAssertNotNil(message.optionalNestedMessage); 992 XCTAssertFalse([message hasOptionalNestedMessage]); 993 XCTAssertNil(message.optionalNestedMessage.unknownFields); 994 XCTAssertFalse([message hasOptionalNestedMessage]); 995 996 GPBUnknownFieldSet *unknownFields = [[[GPBUnknownFieldSet alloc] init] autorelease]; 997 message.optionalNestedMessage.unknownFields = unknownFields; 998 XCTAssertTrue([message hasOptionalNestedMessage]); 999 1000 message.optionalNestedMessage = nil; 1001 XCTAssertFalse([message hasOptionalNestedMessage]); 1002 [message.optionalNestedMessage setUnknownFields:unknownFields]; 1003 XCTAssertTrue([message hasOptionalNestedMessage]); 1004 1005 message.optionalNestedMessage = nil; 1006 XCTAssertFalse([message hasOptionalNestedMessage]); 1007 GPBUnknownFields *ufs = [[[GPBUnknownFields alloc] init] autorelease]; 1008 [ufs addFieldNumber:1 varint:1]; 1009 XCTAssertTrue([message.optionalNestedMessage mergeUnknownFields:ufs 1010 extensionRegistry:nil 1011 error:NULL]); 1012 XCTAssertTrue([message hasOptionalNestedMessage]); 1013 1014 message.optionalNestedMessage = nil; 1015 XCTAssertFalse([message hasOptionalNestedMessage]); 1016 [ufs clear]; // Also make sure merging zero length forces it to become visible. 1017 XCTAssertTrue([message.optionalNestedMessage mergeUnknownFields:ufs 1018 extensionRegistry:nil 1019 error:NULL]); 1020 XCTAssertTrue([message hasOptionalNestedMessage]); 1021 1022#pragma clang diagnostic pop 1023} 1024 1025- (void)testSetAutocreatedSubmessageToSelf { 1026 // Setting submessage to itself should cause it to become visible. 1027 TestAllTypes *message = [TestAllTypes message]; 1028 XCTAssertNotNil(message.optionalNestedMessage); 1029 XCTAssertFalse([message hasOptionalNestedMessage]); 1030 message.optionalNestedMessage = message.optionalNestedMessage; 1031 XCTAssertTrue([message hasOptionalNestedMessage]); 1032} 1033 1034- (void)testAutocreatedSubmessageMemoryLeaks { 1035 // Test for memory leaks with autocreated submessages. 1036 TestRecursiveMessage *message; 1037 TestRecursiveMessage *messageLevel1; 1038 TestRecursiveMessage *messageLevel2; 1039 TestRecursiveMessage *messageLevel3; 1040 TestRecursiveMessage *messageLevel4; 1041 @autoreleasepool { 1042 message = [[TestRecursiveMessage alloc] init]; 1043 messageLevel1 = [message.a retain]; 1044 messageLevel2 = [message.a.a retain]; 1045 messageLevel3 = [message.a.a.a retain]; 1046 messageLevel4 = [message.a.a.a.a retain]; 1047 message.a.i = 1; 1048 } 1049 1050 XCTAssertEqual(message.retainCount, (NSUInteger)1); 1051 [message release]; 1052 XCTAssertEqual(messageLevel1.retainCount, (NSUInteger)1); 1053 [messageLevel1 release]; 1054 XCTAssertEqual(messageLevel2.retainCount, (NSUInteger)1); 1055 [messageLevel2 release]; 1056 XCTAssertEqual(messageLevel3.retainCount, (NSUInteger)1); 1057 [messageLevel3 release]; 1058 XCTAssertEqual(messageLevel4.retainCount, (NSUInteger)1); 1059 [messageLevel4 release]; 1060} 1061 1062- (void)testDefaultingArrays { 1063 // Basic tests for default creation of arrays in a message. 1064 TestRecursiveMessageWithRepeatedField *message = [TestRecursiveMessageWithRepeatedField message]; 1065 TestRecursiveMessageWithRepeatedField *message2 = [TestRecursiveMessageWithRepeatedField message]; 1066 1067 // Simply accessing the array should not make any fields visible. 1068 XCTAssertNotNil(message.a.a.iArray); 1069 XCTAssertFalse([message hasA]); 1070 XCTAssertFalse([message.a hasA]); 1071 XCTAssertNotNil(message2.a.a.strArray); 1072 XCTAssertFalse([message2 hasA]); 1073 XCTAssertFalse([message2.a hasA]); 1074 1075 // But adding an element to the array should. 1076 [message.a.a.iArray addValue:42]; 1077 XCTAssertTrue([message hasA]); 1078 XCTAssertTrue([message.a hasA]); 1079 XCTAssertEqual([message.a.a.iArray count], (NSUInteger)1); 1080 [message2.a.a.strArray addObject:@"foo"]; 1081 XCTAssertTrue([message2 hasA]); 1082 XCTAssertTrue([message2.a hasA]); 1083 XCTAssertEqual([message2.a.a.strArray count], (NSUInteger)1); 1084} 1085 1086- (void)testAutocreatedArrayShared { 1087 // Multiple objects pointing to the same array. 1088 TestRecursiveMessageWithRepeatedField *message1a = 1089 [TestRecursiveMessageWithRepeatedField message]; 1090 TestRecursiveMessageWithRepeatedField *message1b = 1091 [TestRecursiveMessageWithRepeatedField message]; 1092 message1a.a.iArray = message1b.a.iArray; 1093 XCTAssertTrue([message1a hasA]); 1094 XCTAssertFalse([message1b hasA]); 1095 [message1a.a.iArray addValue:1]; 1096 XCTAssertTrue([message1a hasA]); 1097 XCTAssertTrue([message1b hasA]); 1098 XCTAssertEqual(message1a.a.iArray, message1b.a.iArray); 1099 1100 TestRecursiveMessageWithRepeatedField *message2a = 1101 [TestRecursiveMessageWithRepeatedField message]; 1102 TestRecursiveMessageWithRepeatedField *message2b = 1103 [TestRecursiveMessageWithRepeatedField message]; 1104 message2a.a.strArray = message2b.a.strArray; 1105 XCTAssertTrue([message2a hasA]); 1106 XCTAssertFalse([message2b hasA]); 1107 [message2a.a.strArray addObject:@"bar"]; 1108 XCTAssertTrue([message2a hasA]); 1109 XCTAssertTrue([message2b hasA]); 1110 XCTAssertEqual(message2a.a.strArray, message2b.a.strArray); 1111} 1112 1113- (void)testAutocreatedArrayCopy { 1114 // Copy should not copy autocreated arrays. 1115 TestAllTypes *message = [TestAllTypes message]; 1116 XCTAssertNotNil(message.repeatedStringArray); 1117 XCTAssertNotNil(message.repeatedInt32Array); 1118 TestAllTypes *message2 = [[message copy] autorelease]; 1119 // Pointer conparisions. 1120 XCTAssertNotEqual(message.repeatedStringArray, message2.repeatedStringArray); 1121 XCTAssertNotEqual(message.repeatedInt32Array, message2.repeatedInt32Array); 1122 1123 // Mutable copy should copy empty arrays that were explicitly set (end up 1124 // with different objects that are equal). 1125 TestAllTypes *message3 = [TestAllTypes message]; 1126 message3.repeatedInt32Array = [GPBInt32Array arrayWithValue:42]; 1127 message3.repeatedStringArray = [NSMutableArray arrayWithObject:@"wee"]; 1128 XCTAssertNotNil(message.repeatedInt32Array); 1129 XCTAssertNotNil(message.repeatedStringArray); 1130 TestAllTypes *message4 = [[message3 copy] autorelease]; 1131 XCTAssertNotEqual(message3.repeatedInt32Array, message4.repeatedInt32Array); 1132 XCTAssertEqualObjects(message3.repeatedInt32Array, message4.repeatedInt32Array); 1133 XCTAssertNotEqual(message3.repeatedStringArray, message4.repeatedStringArray); 1134 XCTAssertEqualObjects(message3.repeatedStringArray, message4.repeatedStringArray); 1135} 1136 1137- (void)testAutocreatedArrayRetain { 1138 // Should be able to retain autocreated array while the creator is dealloced. 1139 TestAllTypes *message = [TestAllTypes message]; 1140 1141 @autoreleasepool { 1142 TestAllTypes *message2 = [TestAllTypes message]; 1143 message.repeatedInt32Array = message2.repeatedInt32Array; 1144 message.repeatedStringArray = message2.repeatedStringArray; 1145 // Pointer conparision 1146 XCTAssertEqual(message.repeatedInt32Array->_autocreator, message2); 1147 XCTAssertTrue([message.repeatedStringArray isKindOfClass:[GPBAutocreatedArray class]]); 1148 XCTAssertEqual(((GPBAutocreatedArray *)message.repeatedStringArray)->_autocreator, message2); 1149 } 1150 1151 XCTAssertNil(message.repeatedInt32Array->_autocreator); 1152 XCTAssertTrue([message.repeatedStringArray isKindOfClass:[GPBAutocreatedArray class]]); 1153 XCTAssertNil(((GPBAutocreatedArray *)message.repeatedStringArray)->_autocreator); 1154} 1155 1156- (void)testSetNilAutocreatedArray { 1157 // Setting array to nil should cause it to lose its delegate. 1158 TestAllTypes *message = [TestAllTypes message]; 1159 GPBInt32Array *repeatedInt32Array = [message.repeatedInt32Array retain]; 1160 GPBAutocreatedArray *repeatedStringArray = 1161 (GPBAutocreatedArray *)[message.repeatedStringArray retain]; 1162 XCTAssertTrue([repeatedStringArray isKindOfClass:[GPBAutocreatedArray class]]); 1163 XCTAssertEqual(repeatedInt32Array->_autocreator, message); 1164 XCTAssertEqual(repeatedStringArray->_autocreator, message); 1165 message.repeatedInt32Array = nil; 1166 message.repeatedStringArray = nil; 1167 XCTAssertNil(repeatedInt32Array->_autocreator); 1168 XCTAssertNil(repeatedStringArray->_autocreator); 1169 [repeatedInt32Array release]; 1170 [repeatedStringArray release]; 1171} 1172 1173- (void)testSetOverAutocreatedArrayAndSetAgain { 1174 // Ensure when dealing with replacing an array it is handled being either 1175 // an autocreated one or a straight NSArray. 1176 1177 // The real test here is that nothing crashes while doing the work. 1178 TestAllTypes *message = [TestAllTypes message]; 1179 [message.repeatedStringArray addObject:@"foo"]; 1180 XCTAssertEqual(message.repeatedStringArray_Count, (NSUInteger)1); 1181 message.repeatedStringArray = [NSMutableArray arrayWithObjects:@"bar", @"bar2", nil]; 1182 XCTAssertEqual(message.repeatedStringArray_Count, (NSUInteger)2); 1183 message.repeatedStringArray = [NSMutableArray arrayWithObject:@"baz"]; 1184 XCTAssertEqual(message.repeatedStringArray_Count, (NSUInteger)1); 1185} 1186 1187- (void)testReplaceAutocreatedArray { 1188 // Replacing array should orphan the old one and cause its creator to become 1189 // visible. 1190 { 1191 TestRecursiveMessageWithRepeatedField *message = 1192 [TestRecursiveMessageWithRepeatedField message]; 1193 XCTAssertNotNil(message.a); 1194 XCTAssertNotNil(message.a.iArray); 1195 XCTAssertFalse([message hasA]); 1196 GPBInt32Array *iArray = [message.a.iArray retain]; 1197 XCTAssertEqual(iArray->_autocreator, message.a); // Pointer comparison 1198 message.a.iArray = [GPBInt32Array arrayWithValue:1]; 1199 XCTAssertTrue([message hasA]); 1200 XCTAssertNotEqual(message.a.iArray, iArray); // Pointer comparison 1201 XCTAssertNil(iArray->_autocreator); 1202 [iArray release]; 1203 } 1204 1205 { 1206 TestRecursiveMessageWithRepeatedField *message = 1207 [TestRecursiveMessageWithRepeatedField message]; 1208 XCTAssertNotNil(message.a); 1209 XCTAssertNotNil(message.a.strArray); 1210 XCTAssertFalse([message hasA]); 1211 GPBAutocreatedArray *strArray = (GPBAutocreatedArray *)[message.a.strArray retain]; 1212 XCTAssertTrue([strArray isKindOfClass:[GPBAutocreatedArray class]]); 1213 XCTAssertEqual(strArray->_autocreator, message.a); // Pointer comparison 1214 message.a.strArray = [NSMutableArray arrayWithObject:@"foo"]; 1215 XCTAssertTrue([message hasA]); 1216 XCTAssertNotEqual(message.a.strArray, strArray); // Pointer comparison 1217 XCTAssertNil(strArray->_autocreator); 1218 [strArray release]; 1219 } 1220} 1221 1222- (void)testSetAutocreatedArrayToSelf { 1223 // Setting array to itself should cause it to become visible. 1224 { 1225 TestRecursiveMessageWithRepeatedField *message = 1226 [TestRecursiveMessageWithRepeatedField message]; 1227 XCTAssertNotNil(message.a); 1228 XCTAssertNotNil(message.a.iArray); 1229 XCTAssertFalse([message hasA]); 1230 message.a.iArray = message.a.iArray; 1231 XCTAssertTrue([message hasA]); 1232 XCTAssertNil(message.a.iArray->_autocreator); 1233 } 1234 1235 { 1236 TestRecursiveMessageWithRepeatedField *message = 1237 [TestRecursiveMessageWithRepeatedField message]; 1238 XCTAssertNotNil(message.a); 1239 XCTAssertNotNil(message.a.strArray); 1240 XCTAssertFalse([message hasA]); 1241 message.a.strArray = message.a.strArray; 1242 XCTAssertTrue([message hasA]); 1243 XCTAssertTrue([message.a.strArray isKindOfClass:[GPBAutocreatedArray class]]); 1244 XCTAssertNil(((GPBAutocreatedArray *)message.a.strArray)->_autocreator); 1245 } 1246} 1247 1248- (void)testAutocreatedArrayRemoveAllValues { 1249 // Calling removeAllValues on autocreated array should not cause it to be 1250 // visible. 1251 TestRecursiveMessageWithRepeatedField *message = [TestRecursiveMessageWithRepeatedField message]; 1252 [message.a.iArray removeAll]; 1253 XCTAssertFalse([message hasA]); 1254 [message.a.strArray removeAllObjects]; 1255 XCTAssertFalse([message hasA]); 1256} 1257 1258- (void)testDefaultingMaps { 1259 // Basic tests for default creation of maps in a message. 1260 TestRecursiveMessageWithRepeatedField *message = [TestRecursiveMessageWithRepeatedField message]; 1261 TestRecursiveMessageWithRepeatedField *message2 = [TestRecursiveMessageWithRepeatedField message]; 1262 1263 // Simply accessing the map should not make any fields visible. 1264 XCTAssertNotNil(message.a.a.iToI); 1265 XCTAssertFalse([message hasA]); 1266 XCTAssertFalse([message.a hasA]); 1267 XCTAssertNotNil(message2.a.a.strToStr); 1268 XCTAssertFalse([message2 hasA]); 1269 XCTAssertFalse([message2.a hasA]); 1270 1271 // But adding an element to the map should. 1272 [message.a.a.iToI setInt32:100 forKey:200]; 1273 XCTAssertTrue([message hasA]); 1274 XCTAssertTrue([message.a hasA]); 1275 XCTAssertEqual([message.a.a.iToI count], (NSUInteger)1); 1276 [message2.a.a.strToStr setObject:@"foo" forKey:@"bar"]; 1277 XCTAssertTrue([message2 hasA]); 1278 XCTAssertTrue([message2.a hasA]); 1279 XCTAssertEqual([message2.a.a.strToStr count], (NSUInteger)1); 1280} 1281 1282- (void)testAutocreatedMapShared { 1283 // Multiple objects pointing to the same map. 1284 TestRecursiveMessageWithRepeatedField *message1a = 1285 [TestRecursiveMessageWithRepeatedField message]; 1286 TestRecursiveMessageWithRepeatedField *message1b = 1287 [TestRecursiveMessageWithRepeatedField message]; 1288 message1a.a.iToI = message1b.a.iToI; 1289 XCTAssertTrue([message1a hasA]); 1290 XCTAssertFalse([message1b hasA]); 1291 [message1a.a.iToI setInt32:1 forKey:2]; 1292 XCTAssertTrue([message1a hasA]); 1293 XCTAssertTrue([message1b hasA]); 1294 XCTAssertEqual(message1a.a.iToI, message1b.a.iToI); 1295 1296 TestRecursiveMessageWithRepeatedField *message2a = 1297 [TestRecursiveMessageWithRepeatedField message]; 1298 TestRecursiveMessageWithRepeatedField *message2b = 1299 [TestRecursiveMessageWithRepeatedField message]; 1300 message2a.a.strToStr = message2b.a.strToStr; 1301 XCTAssertTrue([message2a hasA]); 1302 XCTAssertFalse([message2b hasA]); 1303 [message2a.a.strToStr setObject:@"bar" forKey:@"foo"]; 1304 XCTAssertTrue([message2a hasA]); 1305 XCTAssertTrue([message2b hasA]); 1306 XCTAssertEqual(message2a.a.strToStr, message2b.a.strToStr); 1307} 1308 1309- (void)testAutocreatedMapCopy { 1310 // Copy should not copy autocreated maps. 1311 TestRecursiveMessageWithRepeatedField *message = [TestRecursiveMessageWithRepeatedField message]; 1312 XCTAssertNotNil(message.strToStr); 1313 XCTAssertNotNil(message.iToI); 1314 TestRecursiveMessageWithRepeatedField *message2 = [[message copy] autorelease]; 1315 // Pointer conparisions. 1316 XCTAssertNotEqual(message.strToStr, message2.strToStr); 1317 XCTAssertNotEqual(message.iToI, message2.iToI); 1318 1319 // Mutable copy should copy empty arrays that were explicitly set (end up 1320 // with different objects that are equal). 1321 TestRecursiveMessageWithRepeatedField *message3 = [TestRecursiveMessageWithRepeatedField message]; 1322 message3.iToI = [[[GPBInt32Int32Dictionary alloc] init] autorelease]; 1323 [message3.iToI setInt32:10 forKey:20]; 1324 message3.strToStr = [NSMutableDictionary dictionaryWithObject:@"abc" forKey:@"123"]; 1325 XCTAssertNotNil(message.iToI); 1326 XCTAssertNotNil(message.iToI); 1327 TestRecursiveMessageWithRepeatedField *message4 = [[message3 copy] autorelease]; 1328 XCTAssertNotEqual(message3.iToI, message4.iToI); 1329 XCTAssertEqualObjects(message3.iToI, message4.iToI); 1330 XCTAssertNotEqual(message3.strToStr, message4.strToStr); 1331 XCTAssertEqualObjects(message3.strToStr, message4.strToStr); 1332} 1333 1334- (void)testAutocreatedMapRetain { 1335 // Should be able to retain autocreated map while the creator is dealloced. 1336 TestRecursiveMessageWithRepeatedField *message = [TestRecursiveMessageWithRepeatedField message]; 1337 1338 @autoreleasepool { 1339 TestRecursiveMessageWithRepeatedField *message2 = 1340 [TestRecursiveMessageWithRepeatedField message]; 1341 message.iToI = message2.iToI; 1342 message.strToStr = message2.strToStr; 1343 // Pointer conparision 1344 XCTAssertEqual(message.iToI->_autocreator, message2); 1345 XCTAssertTrue([message.strToStr isKindOfClass:[GPBAutocreatedDictionary class]]); 1346 XCTAssertEqual(((GPBAutocreatedDictionary *)message.strToStr)->_autocreator, message2); 1347 } 1348 1349 XCTAssertNil(message.iToI->_autocreator); 1350 XCTAssertTrue([message.strToStr isKindOfClass:[GPBAutocreatedDictionary class]]); 1351 XCTAssertNil(((GPBAutocreatedDictionary *)message.strToStr)->_autocreator); 1352} 1353 1354- (void)testSetNilAutocreatedMap { 1355 // Setting map to nil should cause it to lose its delegate. 1356 TestRecursiveMessageWithRepeatedField *message = [TestRecursiveMessageWithRepeatedField message]; 1357 GPBInt32Int32Dictionary *iToI = [message.iToI retain]; 1358 GPBAutocreatedDictionary *strToStr = (GPBAutocreatedDictionary *)[message.strToStr retain]; 1359 XCTAssertTrue([strToStr isKindOfClass:[GPBAutocreatedDictionary class]]); 1360 XCTAssertEqual(iToI->_autocreator, message); 1361 XCTAssertEqual(strToStr->_autocreator, message); 1362 message.iToI = nil; 1363 message.strToStr = nil; 1364 XCTAssertNil(iToI->_autocreator); 1365 XCTAssertNil(strToStr->_autocreator); 1366 [iToI release]; 1367 [strToStr release]; 1368} 1369 1370- (void)testSetOverAutocreatedMapAndSetAgain { 1371 // Ensure when dealing with replacing a map it is handled being either 1372 // an autocreated one or a straight NSDictionary. 1373 1374 // The real test here is that nothing crashes while doing the work. 1375 TestRecursiveMessageWithRepeatedField *message = [TestRecursiveMessageWithRepeatedField message]; 1376 message.strToStr[@"foo"] = @"bar"; 1377 XCTAssertEqual(message.strToStr_Count, (NSUInteger)1); 1378 message.strToStr = 1379 [NSMutableDictionary dictionaryWithObjectsAndKeys:@"bar", @"key1", @"baz", @"key2", nil]; 1380 XCTAssertEqual(message.strToStr_Count, (NSUInteger)2); 1381 message.strToStr = [NSMutableDictionary dictionaryWithObject:@"baz" forKey:@"mumble"]; 1382 XCTAssertEqual(message.strToStr_Count, (NSUInteger)1); 1383} 1384 1385- (void)testReplaceAutocreatedMap { 1386 // Replacing map should orphan the old one and cause its creator to become 1387 // visible. 1388 { 1389 TestRecursiveMessageWithRepeatedField *message = 1390 [TestRecursiveMessageWithRepeatedField message]; 1391 XCTAssertNotNil(message.a); 1392 XCTAssertNotNil(message.a.iToI); 1393 XCTAssertFalse([message hasA]); 1394 GPBInt32Int32Dictionary *iToI = [message.a.iToI retain]; 1395 XCTAssertEqual(iToI->_autocreator, message.a); // Pointer comparison 1396 message.a.iToI = [[[GPBInt32Int32Dictionary alloc] init] autorelease]; 1397 [message.a.iToI setInt32:6 forKey:7]; 1398 XCTAssertTrue([message hasA]); 1399 XCTAssertNotEqual(message.a.iToI, iToI); // Pointer comparison 1400 XCTAssertNil(iToI->_autocreator); 1401 [iToI release]; 1402 } 1403 1404 { 1405 TestRecursiveMessageWithRepeatedField *message = 1406 [TestRecursiveMessageWithRepeatedField message]; 1407 XCTAssertNotNil(message.a); 1408 XCTAssertNotNil(message.a.strToStr); 1409 XCTAssertFalse([message hasA]); 1410 GPBAutocreatedDictionary *strToStr = (GPBAutocreatedDictionary *)[message.a.strToStr retain]; 1411 XCTAssertTrue([strToStr isKindOfClass:[GPBAutocreatedDictionary class]]); 1412 XCTAssertEqual(strToStr->_autocreator, message.a); // Pointer comparison 1413 message.a.strToStr = [NSMutableDictionary dictionaryWithObject:@"abc" forKey:@"def"]; 1414 XCTAssertTrue([message hasA]); 1415 XCTAssertNotEqual(message.a.strToStr, strToStr); // Pointer comparison 1416 XCTAssertNil(strToStr->_autocreator); 1417 [strToStr release]; 1418 } 1419} 1420 1421- (void)testSetAutocreatedMapToSelf { 1422 // Setting map to itself should cause it to become visible. 1423 { 1424 TestRecursiveMessageWithRepeatedField *message = 1425 [TestRecursiveMessageWithRepeatedField message]; 1426 XCTAssertNotNil(message.a); 1427 XCTAssertNotNil(message.a.iToI); 1428 XCTAssertFalse([message hasA]); 1429 message.a.iToI = message.a.iToI; 1430 XCTAssertTrue([message hasA]); 1431 XCTAssertNil(message.a.iToI->_autocreator); 1432 } 1433 1434 { 1435 TestRecursiveMessageWithRepeatedField *message = 1436 [TestRecursiveMessageWithRepeatedField message]; 1437 XCTAssertNotNil(message.a); 1438 XCTAssertNotNil(message.a.strToStr); 1439 XCTAssertFalse([message hasA]); 1440 message.a.strToStr = message.a.strToStr; 1441 XCTAssertTrue([message hasA]); 1442 XCTAssertTrue([message.a.strToStr isKindOfClass:[GPBAutocreatedDictionary class]]); 1443 XCTAssertNil(((GPBAutocreatedDictionary *)message.a.strToStr)->_autocreator); 1444 } 1445} 1446 1447- (void)testAutocreatedMapRemoveAllValues { 1448 // Calling removeAll on autocreated map should not cause it to be visible. 1449 TestRecursiveMessageWithRepeatedField *message = [TestRecursiveMessageWithRepeatedField message]; 1450 [message.a.iToI removeAll]; 1451 XCTAssertFalse([message hasA]); 1452 [message.a.strToStr removeAllObjects]; 1453 XCTAssertFalse([message hasA]); 1454} 1455 1456- (void)testExtensionAccessors { 1457 TestAllExtensions *message = [TestAllExtensions message]; 1458 [self setAllExtensions:message repeatedCount:kGPBDefaultRepeatCount]; 1459 [self assertAllExtensionsSet:message repeatedCount:kGPBDefaultRepeatCount]; 1460} 1461 1462- (void)testExtensionRepeatedSetters { 1463 TestAllExtensions *message = [TestAllExtensions message]; 1464 [self setAllExtensions:message repeatedCount:kGPBDefaultRepeatCount]; 1465 [self modifyRepeatedExtensions:message]; 1466 [self assertRepeatedExtensionsModified:message repeatedCount:kGPBDefaultRepeatCount]; 1467} 1468 1469- (void)testExtensionDefaults { 1470 [self assertExtensionsClear:[TestAllExtensions message]]; 1471} 1472 1473- (void)testExtensionIsEquals { 1474 TestAllExtensions *message = [TestAllExtensions message]; 1475 [self setAllExtensions:message repeatedCount:kGPBDefaultRepeatCount]; 1476 [self modifyRepeatedExtensions:message]; 1477 TestAllExtensions *message2 = [TestAllExtensions message]; 1478 [self setAllExtensions:message2 repeatedCount:kGPBDefaultRepeatCount]; 1479 XCTAssertFalse([message isEqual:message2]); 1480 message2 = [TestAllExtensions message]; 1481 [self setAllExtensions:message2 repeatedCount:kGPBDefaultRepeatCount]; 1482 [self modifyRepeatedExtensions:message2]; 1483 XCTAssertEqualObjects(message, message2); 1484} 1485 1486- (void)testExtensionsMergeFrom { 1487 TestAllExtensions *message = [TestAllExtensions message]; 1488 [self setAllExtensions:message repeatedCount:kGPBDefaultRepeatCount]; 1489 [self modifyRepeatedExtensions:message]; 1490 1491 message = [TestAllExtensions message]; 1492 [self setAllExtensions:message repeatedCount:kGPBDefaultRepeatCount]; 1493 TestAllExtensions *message2 = [TestAllExtensions message]; 1494 [self modifyRepeatedExtensions:message2]; 1495 [message2 mergeFrom:message]; 1496 1497 XCTAssertEqualObjects(message, message2); 1498} 1499 1500- (void)testClosedEnumsInExtensions { 1501 // Only unknown values. 1502 1503 NSData *data = 1504 DataFromCStr("\xA8\x01\x0A" // optional_nested_enum_extension set to 10 1505 "\x98\x03\x0B" // repeated_nested_enum_extension set to 11 1506 "\xA2\x03\x01\x0C" // repeated_foreign_enum_extension set to 12 (packed) 1507 ); 1508 NSError *error = nil; 1509 1510 TestAllExtensions *msg = [TestAllExtensions parseFromData:data 1511 extensionRegistry:[self extensionRegistry] 1512 error:&error]; 1513 XCTAssertNil(error); 1514 1515 XCTAssertFalse([msg hasExtension:[UnittestRoot optionalNestedEnumExtension]]); 1516 XCTAssertFalse([msg hasExtension:[UnittestRoot repeatedNestedEnumExtension]]); 1517 XCTAssertFalse([msg hasExtension:[UnittestRoot repeatedForeignEnumExtension]]); 1518 1519 GPBUnknownFields *ufs = [[[GPBUnknownFields alloc] initFromMessage:msg] autorelease]; 1520 XCTAssertEqual(ufs.count, 3); 1521 uint64_t varint; 1522 XCTAssertTrue([ufs getFirst:[UnittestRoot optionalNestedEnumExtension].fieldNumber 1523 varint:&varint]); 1524 XCTAssertEqual(varint, 10); 1525 XCTAssertTrue([ufs getFirst:[UnittestRoot repeatedNestedEnumExtension].fieldNumber 1526 varint:&varint]); 1527 XCTAssertEqual(varint, 11); 1528 XCTAssertTrue([ufs getFirst:[UnittestRoot repeatedForeignEnumExtension].fieldNumber 1529 varint:&varint]); 1530 XCTAssertEqual(varint, 12); 1531 1532#pragma clang diagnostic push 1533#pragma clang diagnostic ignored "-Wdeprecated-declarations" 1534 GPBUnknownFieldSet *unknownFields = msg.unknownFields; 1535 GPBUnknownField *field = 1536 [unknownFields getField:[UnittestRoot optionalNestedEnumExtension].fieldNumber]; 1537 XCTAssertNotNil(field); 1538 XCTAssertEqual(field.varintList.count, 1); 1539 XCTAssertEqual([field.varintList valueAtIndex:0], 10); 1540 field = [unknownFields getField:[UnittestRoot repeatedNestedEnumExtension].fieldNumber]; 1541 XCTAssertNotNil(field); 1542 XCTAssertEqual(field.varintList.count, 1); 1543 XCTAssertEqual([field.varintList valueAtIndex:0], 11); 1544 field = [unknownFields getField:[UnittestRoot repeatedForeignEnumExtension].fieldNumber]; 1545 XCTAssertNotNil(field); 1546 XCTAssertEqual(field.varintList.count, 1); 1547 XCTAssertEqual([field.varintList valueAtIndex:0], 12); 1548#pragma clang diagnostic pop 1549 1550 // Unknown and known, the known come though an unknown go to unknown fields. 1551 1552 data = DataFromCStr( 1553 "\xA8\x01\x01" // optional_nested_enum_extension set to 1 1554 "\xA8\x01\x0A" // optional_nested_enum_extension set to 10 1555 "\xA8\x01\x02" // optional_nested_enum_extension set to 2 1556 "\x98\x03\x02" // repeated_nested_enum_extension set to 2 1557 "\x98\x03\x0B" // repeated_nested_enum_extension set to 11 1558 "\x98\x03\x03" // repeated_nested_enum_extension set to 3 1559 "\xA2\x03\x03\x04\x0C\x06" // repeated_foreign_enum_extension set to 4, 12, 6 (packed) 1560 ); 1561 error = nil; 1562 1563 msg = [TestAllExtensions parseFromData:data 1564 extensionRegistry:[self extensionRegistry] 1565 error:&error]; 1566 XCTAssertNil(error); 1567 1568 XCTAssertTrue([msg hasExtension:[UnittestRoot optionalNestedEnumExtension]]); 1569 XCTAssertEqualObjects([msg getExtension:[UnittestRoot optionalNestedEnumExtension]], @2); 1570 XCTAssertTrue([msg hasExtension:[UnittestRoot repeatedNestedEnumExtension]]); 1571 id expected = @[ @2, @3 ]; 1572 XCTAssertEqualObjects([msg getExtension:[UnittestRoot repeatedNestedEnumExtension]], expected); 1573 XCTAssertTrue([msg hasExtension:[UnittestRoot repeatedForeignEnumExtension]]); 1574 expected = @[ @4, @6 ]; 1575 XCTAssertEqualObjects([msg getExtension:[UnittestRoot repeatedForeignEnumExtension]], expected); 1576 1577 ufs = [[[GPBUnknownFields alloc] initFromMessage:msg] autorelease]; 1578 XCTAssertEqual(ufs.count, 3); 1579 XCTAssertTrue([ufs getFirst:[UnittestRoot optionalNestedEnumExtension].fieldNumber 1580 varint:&varint]); 1581 XCTAssertEqual(varint, 10); 1582 XCTAssertTrue([ufs getFirst:[UnittestRoot repeatedNestedEnumExtension].fieldNumber 1583 varint:&varint]); 1584 XCTAssertEqual(varint, 11); 1585 XCTAssertTrue([ufs getFirst:[UnittestRoot repeatedForeignEnumExtension].fieldNumber 1586 varint:&varint]); 1587 XCTAssertEqual(varint, 12); 1588 1589#pragma clang diagnostic push 1590#pragma clang diagnostic ignored "-Wdeprecated-declarations" 1591 unknownFields = msg.unknownFields; 1592 field = [unknownFields getField:[UnittestRoot optionalNestedEnumExtension].fieldNumber]; 1593 XCTAssertNotNil(field); 1594 XCTAssertEqual(field.varintList.count, 1); 1595 XCTAssertEqual([field.varintList valueAtIndex:0], 10); 1596 field = [unknownFields getField:[UnittestRoot repeatedNestedEnumExtension].fieldNumber]; 1597 XCTAssertNotNil(field); 1598 XCTAssertEqual(field.varintList.count, 1); 1599 XCTAssertEqual([field.varintList valueAtIndex:0], 11); 1600 field = [unknownFields getField:[UnittestRoot repeatedForeignEnumExtension].fieldNumber]; 1601 XCTAssertNotNil(field); 1602 XCTAssertEqual(field.varintList.count, 1); 1603 XCTAssertEqual([field.varintList valueAtIndex:0], 12); 1604#pragma clang diagnostic pop 1605} 1606 1607- (void)testDefaultingExtensionMessages { 1608 TestAllExtensions *message = [TestAllExtensions message]; 1609 1610 // Initially they should all not have values. 1611 1612 XCTAssertFalse([message hasExtension:[UnittestRoot optionalGroupExtension]]); 1613 XCTAssertFalse([message hasExtension:[UnittestRoot optionalGroupExtension]]); 1614 XCTAssertFalse([message hasExtension:[UnittestRoot optionalNestedMessageExtension]]); 1615 XCTAssertFalse([message hasExtension:[UnittestRoot optionalForeignMessageExtension]]); 1616 XCTAssertFalse([message hasExtension:[UnittestRoot optionalImportMessageExtension]]); 1617 XCTAssertFalse([message hasExtension:[UnittestRoot optionalPublicImportMessageExtension]]); 1618 XCTAssertFalse([message hasExtension:[UnittestRoot optionalLazyMessageExtension]]); 1619 1620 // They should auto create something when fetched. 1621 1622 TestAllTypes_OptionalGroup *optionalGroup = 1623 [message getExtension:[UnittestRoot optionalGroupExtension]]; 1624 TestAllTypes_NestedMessage *optionalNestedMessage = 1625 [message getExtension:[UnittestRoot optionalNestedMessageExtension]]; 1626 ForeignMessage *optionalForeignMessage = 1627 [message getExtension:[UnittestRoot optionalForeignMessageExtension]]; 1628 ImportMessage *optionalImportMessage = 1629 [message getExtension:[UnittestRoot optionalImportMessageExtension]]; 1630 PublicImportMessage *optionalPublicImportMessage = 1631 [message getExtension:[UnittestRoot optionalPublicImportMessageExtension]]; 1632 TestAllTypes_NestedMessage *optionalLazyMessage = 1633 [message getExtension:[UnittestRoot optionalLazyMessageExtension]]; 1634 1635 XCTAssertNotNil(optionalGroup); 1636 XCTAssertNotNil(optionalNestedMessage); 1637 XCTAssertNotNil(optionalForeignMessage); 1638 XCTAssertNotNil(optionalImportMessage); 1639 XCTAssertNotNil(optionalPublicImportMessage); 1640 XCTAssertNotNil(optionalLazyMessage); 1641 1642 // Although it auto-created empty messages, it should not show that it has 1643 // them. 1644 1645 XCTAssertFalse([message hasExtension:[UnittestRoot optionalGroupExtension]]); 1646 XCTAssertFalse([message hasExtension:[UnittestRoot optionalGroupExtension]]); 1647 XCTAssertFalse([message hasExtension:[UnittestRoot optionalNestedMessageExtension]]); 1648 XCTAssertFalse([message hasExtension:[UnittestRoot optionalForeignMessageExtension]]); 1649 XCTAssertFalse([message hasExtension:[UnittestRoot optionalImportMessageExtension]]); 1650 XCTAssertFalse([message hasExtension:[UnittestRoot optionalPublicImportMessageExtension]]); 1651 XCTAssertFalse([message hasExtension:[UnittestRoot optionalLazyMessageExtension]]); 1652 1653 // And they set that value back in to the message since the value created was 1654 // mutable (so a second fetch should give the same object). 1655 1656 XCTAssertEqual([message getExtension:[UnittestRoot optionalGroupExtension]], optionalGroup); 1657 XCTAssertEqual([message getExtension:[UnittestRoot optionalNestedMessageExtension]], 1658 optionalNestedMessage); 1659 XCTAssertEqual([message getExtension:[UnittestRoot optionalForeignMessageExtension]], 1660 optionalForeignMessage); 1661 XCTAssertEqual([message getExtension:[UnittestRoot optionalImportMessageExtension]], 1662 optionalImportMessage); 1663 XCTAssertEqual([message getExtension:[UnittestRoot optionalPublicImportMessageExtension]], 1664 optionalPublicImportMessage); 1665 XCTAssertEqual([message getExtension:[UnittestRoot optionalLazyMessageExtension]], 1666 optionalLazyMessage); 1667 1668 // And the default objects for a second message should be distinct (again, 1669 // since they are mutable, each needs their own copy). 1670 1671 TestAllExtensions *message2 = [TestAllExtensions message]; 1672 1673 // Intentionally doing a pointer comparison. 1674 XCTAssertNotEqual([message2 getExtension:[UnittestRoot optionalGroupExtension]], optionalGroup); 1675 XCTAssertNotEqual([message2 getExtension:[UnittestRoot optionalNestedMessageExtension]], 1676 optionalNestedMessage); 1677 XCTAssertNotEqual([message2 getExtension:[UnittestRoot optionalForeignMessageExtension]], 1678 optionalForeignMessage); 1679 XCTAssertNotEqual([message2 getExtension:[UnittestRoot optionalImportMessageExtension]], 1680 optionalImportMessage); 1681 XCTAssertNotEqual([message2 getExtension:[UnittestRoot optionalPublicImportMessageExtension]], 1682 optionalPublicImportMessage); 1683 XCTAssertNotEqual([message2 getExtension:[UnittestRoot optionalLazyMessageExtension]], 1684 optionalLazyMessage); 1685 1686 // Clear values, and on next access you get back new submessages. 1687 1688 [message setExtension:[UnittestRoot optionalGroupExtension] value:nil]; 1689 [message setExtension:[UnittestRoot optionalGroupExtension] value:nil]; 1690 [message setExtension:[UnittestRoot optionalNestedMessageExtension] value:nil]; 1691 [message setExtension:[UnittestRoot optionalForeignMessageExtension] value:nil]; 1692 [message setExtension:[UnittestRoot optionalImportMessageExtension] value:nil]; 1693 [message setExtension:[UnittestRoot optionalPublicImportMessageExtension] value:nil]; 1694 [message setExtension:[UnittestRoot optionalLazyMessageExtension] value:nil]; 1695 1696 XCTAssertFalse([message hasExtension:[UnittestRoot optionalGroupExtension]]); 1697 XCTAssertFalse([message hasExtension:[UnittestRoot optionalGroupExtension]]); 1698 XCTAssertFalse([message hasExtension:[UnittestRoot optionalNestedMessageExtension]]); 1699 XCTAssertFalse([message hasExtension:[UnittestRoot optionalForeignMessageExtension]]); 1700 XCTAssertFalse([message hasExtension:[UnittestRoot optionalImportMessageExtension]]); 1701 XCTAssertFalse([message hasExtension:[UnittestRoot optionalPublicImportMessageExtension]]); 1702 XCTAssertFalse([message hasExtension:[UnittestRoot optionalLazyMessageExtension]]); 1703 1704 XCTAssertEqual([message getExtension:[UnittestRoot optionalGroupExtension]], optionalGroup); 1705 XCTAssertEqual([message getExtension:[UnittestRoot optionalNestedMessageExtension]], 1706 optionalNestedMessage); 1707 XCTAssertEqual([message getExtension:[UnittestRoot optionalForeignMessageExtension]], 1708 optionalForeignMessage); 1709 XCTAssertEqual([message getExtension:[UnittestRoot optionalImportMessageExtension]], 1710 optionalImportMessage); 1711 XCTAssertEqual([message getExtension:[UnittestRoot optionalPublicImportMessageExtension]], 1712 optionalPublicImportMessage); 1713 XCTAssertEqual([message getExtension:[UnittestRoot optionalLazyMessageExtension]], 1714 optionalLazyMessage); 1715} 1716 1717- (void)testMultiplePointersToAutocreatedExtension { 1718 // 2 objects point to the same auto-created extension. One should "has" it. 1719 // The other should not. 1720 TestAllExtensions *message = [TestAllExtensions message]; 1721 TestAllExtensions *message2 = [TestAllExtensions message]; 1722 GPBExtensionDescriptor *extension = [UnittestRoot optionalGroupExtension]; 1723 [message setExtension:extension value:[message2 getExtension:extension]]; 1724 XCTAssertEqual([message getExtension:extension], [message2 getExtension:extension]); 1725 XCTAssertFalse([message2 hasExtension:extension]); 1726 XCTAssertTrue([message hasExtension:extension]); 1727 1728 TestAllTypes_OptionalGroup *extensionValue = [message2 getExtension:extension]; 1729 extensionValue.a = 1; 1730 XCTAssertTrue([message2 hasExtension:extension]); 1731 XCTAssertTrue([message hasExtension:extension]); 1732} 1733 1734- (void)testCopyWithAutocreatedExtension { 1735 // Mutable copy shouldn't copy autocreated extensions. 1736 TestAllExtensions *message = [TestAllExtensions message]; 1737 GPBExtensionDescriptor *optionalGroupExtension = [UnittestRoot optionalGroupExtension]; 1738 GPBExtensionDescriptor *optionalNestedMessageExtension = 1739 [UnittestRoot optionalNestedMessageExtension]; 1740 TestAllTypes_OptionalGroup *optionalGroup = [message getExtension:optionalGroupExtension]; 1741 optionalGroup.a = 42; 1742 XCTAssertNotNil(optionalGroup); 1743 XCTAssertNotNil([message getExtension:optionalNestedMessageExtension]); 1744 XCTAssertTrue([message hasExtension:optionalGroupExtension]); 1745 XCTAssertFalse([message hasExtension:optionalNestedMessageExtension]); 1746 1747 TestAllExtensions *message2 = [[message copy] autorelease]; 1748 1749 // message2 should end up with its own copy of the optional group. 1750 XCTAssertTrue([message2 hasExtension:optionalGroupExtension]); 1751 XCTAssertEqualObjects([message getExtension:optionalGroupExtension], 1752 [message2 getExtension:optionalGroupExtension]); 1753 // Intentionally doing a pointer comparison. 1754 XCTAssertNotEqual([message getExtension:optionalGroupExtension], 1755 [message2 getExtension:optionalGroupExtension]); 1756 1757 XCTAssertFalse([message2 hasExtension:optionalNestedMessageExtension]); 1758 // Intentionally doing a pointer comparison (auto creation should be 1759 // different) 1760 XCTAssertNotEqual([message getExtension:optionalNestedMessageExtension], 1761 [message2 getExtension:optionalNestedMessageExtension]); 1762} 1763 1764- (void)testClearMessageAutocreatedExtension { 1765 // Call clear should cause it to recreate its autocreated extensions. 1766 TestAllExtensions *message = [TestAllExtensions message]; 1767 GPBExtensionDescriptor *optionalGroupExtension = [UnittestRoot optionalGroupExtension]; 1768 TestAllTypes_OptionalGroup *optionalGroup = 1769 [[message getExtension:optionalGroupExtension] retain]; 1770 [message clear]; 1771 TestAllTypes_OptionalGroup *optionalGroupNew = [message getExtension:optionalGroupExtension]; 1772 1773 // Intentionally doing a pointer comparison. 1774 XCTAssertNotEqual(optionalGroup, optionalGroupNew); 1775 [optionalGroup release]; 1776} 1777 1778- (void)testRetainAutocreatedExtension { 1779 // Should be able to retain autocreated extension while the creator is 1780 // dealloced. 1781 TestAllExtensions *message = [TestAllExtensions message]; 1782 GPBExtensionDescriptor *optionalGroupExtension = [UnittestRoot optionalGroupExtension]; 1783 1784 @autoreleasepool { 1785 TestAllExtensions *message2 = [TestAllExtensions message]; 1786 [message setExtension:optionalGroupExtension 1787 value:[message2 getExtension:optionalGroupExtension]]; 1788 XCTAssertTrue( 1789 GPBWasMessageAutocreatedBy([message getExtension:optionalGroupExtension], message2)); 1790 } 1791 1792 XCTAssertFalse( 1793 GPBWasMessageAutocreatedBy([message getExtension:optionalGroupExtension], message)); 1794} 1795 1796- (void)testClearAutocreatedExtension { 1797 // Clearing autocreated extension should NOT cause it to lose its creator. 1798 TestAllExtensions *message = [TestAllExtensions message]; 1799 GPBExtensionDescriptor *optionalGroupExtension = [UnittestRoot optionalGroupExtension]; 1800 TestAllTypes_OptionalGroup *optionalGroup = 1801 [[message getExtension:optionalGroupExtension] retain]; 1802 [message clearExtension:optionalGroupExtension]; 1803 TestAllTypes_OptionalGroup *optionalGroupNew = [message getExtension:optionalGroupExtension]; 1804 XCTAssertEqual(optionalGroup, optionalGroupNew); 1805 XCTAssertFalse([message hasExtension:optionalGroupExtension]); 1806 [optionalGroup release]; 1807 1808 // Clearing autocreated extension should not cause its creator to become 1809 // visible 1810 GPBExtensionDescriptor *recursiveExtension = [UnittestObjcRoot recursiveExtension]; 1811 TestAllExtensions *message_lvl2 = [message getExtension:recursiveExtension]; 1812 TestAllExtensions *message_lvl3 = [message_lvl2 getExtension:recursiveExtension]; 1813 [message_lvl3 clearExtension:recursiveExtension]; 1814 XCTAssertFalse([message hasExtension:recursiveExtension]); 1815} 1816 1817- (void)testSetAutocreatedExtensionBecomesVisible { 1818 // Setting an extension should cause the extension to appear to its creator. 1819 // Test this several levels deep. 1820 TestAllExtensions *message = [TestAllExtensions message]; 1821 GPBExtensionDescriptor *recursiveExtension = [UnittestObjcRoot recursiveExtension]; 1822 TestAllExtensions *message_lvl2 = [message getExtension:recursiveExtension]; 1823 TestAllExtensions *message_lvl3 = [message_lvl2 getExtension:recursiveExtension]; 1824 TestAllExtensions *message_lvl4 = [message_lvl3 getExtension:recursiveExtension]; 1825 XCTAssertFalse([message hasExtension:recursiveExtension]); 1826 XCTAssertFalse([message_lvl2 hasExtension:recursiveExtension]); 1827 XCTAssertFalse([message_lvl3 hasExtension:recursiveExtension]); 1828 XCTAssertFalse([message_lvl4 hasExtension:recursiveExtension]); 1829 [message_lvl4 setExtension:[UnittestRoot optionalInt32Extension] value:@(1)]; 1830 XCTAssertTrue([message hasExtension:recursiveExtension]); 1831 XCTAssertTrue([message_lvl2 hasExtension:recursiveExtension]); 1832 XCTAssertTrue([message_lvl3 hasExtension:recursiveExtension]); 1833 XCTAssertFalse([message_lvl4 hasExtension:recursiveExtension]); 1834 XCTAssertFalse(GPBWasMessageAutocreatedBy(message_lvl4, message_lvl3)); 1835 XCTAssertFalse(GPBWasMessageAutocreatedBy(message_lvl3, message_lvl2)); 1836 XCTAssertFalse(GPBWasMessageAutocreatedBy(message_lvl2, message)); 1837} 1838 1839- (void)testSetAutocreatedExtensionToSelf { 1840 // Setting extension to itself should cause it to become visible. 1841 TestAllExtensions *message = [TestAllExtensions message]; 1842 GPBExtensionDescriptor *optionalGroupExtension = [UnittestRoot optionalGroupExtension]; 1843 XCTAssertNotNil([message getExtension:optionalGroupExtension]); 1844 XCTAssertFalse([message hasExtension:optionalGroupExtension]); 1845 [message setExtension:optionalGroupExtension value:[message getExtension:optionalGroupExtension]]; 1846 XCTAssertTrue([message hasExtension:optionalGroupExtension]); 1847} 1848 1849- (void)testAutocreatedExtensionMemoryLeaks { 1850 GPBExtensionDescriptor *recursiveExtension = [UnittestObjcRoot recursiveExtension]; 1851 1852 // Test for memory leaks with autocreated extensions. 1853 TestAllExtensions *message; 1854 TestAllExtensions *message_lvl2; 1855 TestAllExtensions *message_lvl3; 1856 TestAllExtensions *message_lvl4; 1857 @autoreleasepool { 1858 message = [[TestAllExtensions alloc] init]; 1859 message_lvl2 = [[message getExtension:recursiveExtension] retain]; 1860 message_lvl3 = [[message_lvl2 getExtension:recursiveExtension] retain]; 1861 message_lvl4 = [[message_lvl3 getExtension:recursiveExtension] retain]; 1862 [message_lvl2 setExtension:[UnittestRoot optionalInt32Extension] value:@(1)]; 1863 } 1864 1865 XCTAssertEqual(message.retainCount, (NSUInteger)1); 1866 @autoreleasepool { 1867 [message release]; 1868 } 1869 XCTAssertEqual(message_lvl2.retainCount, (NSUInteger)1); 1870 @autoreleasepool { 1871 [message_lvl2 release]; 1872 } 1873 XCTAssertEqual(message_lvl3.retainCount, (NSUInteger)1); 1874 @autoreleasepool { 1875 [message_lvl3 release]; 1876 } 1877 XCTAssertEqual(message_lvl4.retainCount, (NSUInteger)1); 1878 [message_lvl4 release]; 1879} 1880 1881- (void)testSetExtensionWithAutocreatedValue { 1882 GPBExtensionDescriptor *recursiveExtension = [UnittestObjcRoot recursiveExtension]; 1883 1884 TestAllExtensions *message; 1885 @autoreleasepool { 1886 message = [[TestAllExtensions alloc] init]; 1887 [message getExtension:recursiveExtension]; 1888 } 1889 1890 // This statements checks that the extension value isn't accidentally 1891 // dealloced when removing it from the autocreated map. 1892 [message setExtension:recursiveExtension value:[message getExtension:recursiveExtension]]; 1893 XCTAssertTrue([message hasExtension:recursiveExtension]); 1894 [message release]; 1895} 1896 1897- (void)testRecursion { 1898 TestRecursiveMessage *message = [TestRecursiveMessage message]; 1899 XCTAssertNotNil(message.a); 1900 XCTAssertNotNil(message.a.a); 1901 XCTAssertEqual(message.a.a.i, 0); 1902} 1903 1904- (void)testGenerateAndParseUnknownMessage { 1905#pragma clang diagnostic push 1906#pragma clang diagnostic ignored "-Wdeprecated-declarations" 1907 GPBUnknownFieldSet *unknowns = [[[GPBUnknownFieldSet alloc] init] autorelease]; 1908 [unknowns mergeVarintField:123 value:456]; 1909 GPBMessage *message = [GPBMessage message]; 1910 [message setUnknownFields:unknowns]; 1911#pragma clang diagnostic pop 1912 GPBUnknownFields *ufs = [[[GPBUnknownFields alloc] init] autorelease]; 1913 [ufs addFieldNumber:1234 varint:5678]; 1914 XCTAssertTrue([message mergeUnknownFields:ufs extensionRegistry:nil error:NULL]); 1915 NSData *data = [message data]; 1916 GPBMessage *message2 = [GPBMessage parseFromData:data extensionRegistry:nil error:NULL]; 1917 XCTAssertEqualObjects(message, message2); 1918} 1919 1920- (void)testDelimitedWriteAndParseMultipleMessages { 1921#pragma clang diagnostic push 1922#pragma clang diagnostic ignored "-Wdeprecated-declarations" 1923 GPBUnknownFieldSet *unknowns1 = [[[GPBUnknownFieldSet alloc] init] autorelease]; 1924 [unknowns1 mergeVarintField:123 value:456]; 1925 GPBMessage *message1 = [GPBMessage message]; 1926 [message1 setUnknownFields:unknowns1]; 1927#pragma clang diagnostic pop 1928 GPBUnknownFields *ufs1 = [[[GPBUnknownFields alloc] init] autorelease]; 1929 [ufs1 addFieldNumber:1234 varint:5678]; 1930 XCTAssertTrue([message1 mergeUnknownFields:ufs1 extensionRegistry:nil error:NULL]); 1931 1932#pragma clang diagnostic push 1933#pragma clang diagnostic ignored "-Wdeprecated-declarations" 1934 GPBUnknownFieldSet *unknowns2 = [[[GPBUnknownFieldSet alloc] init] autorelease]; 1935 [unknowns2 mergeVarintField:789 value:987]; 1936 [unknowns2 mergeVarintField:654 value:321]; 1937 GPBMessage *message2 = [GPBMessage message]; 1938 [message2 setUnknownFields:unknowns2]; 1939#pragma clang diagnostic pop 1940 GPBUnknownFields *ufs2 = [[[GPBUnknownFields alloc] init] autorelease]; 1941 [ufs2 addFieldNumber:2345 fixed32:6789]; 1942 [ufs2 addFieldNumber:3456 fixed32:7890]; 1943 XCTAssertTrue([message2 mergeUnknownFields:ufs2 extensionRegistry:nil error:NULL]); 1944 1945 NSMutableData *delimitedData = [NSMutableData data]; 1946 [delimitedData appendData:[message1 delimitedData]]; 1947 [delimitedData appendData:[message2 delimitedData]]; 1948 GPBCodedInputStream *input = [GPBCodedInputStream streamWithData:delimitedData]; 1949 GPBMessage *message3 = [GPBMessage parseDelimitedFromCodedInputStream:input 1950 extensionRegistry:nil 1951 error:NULL]; 1952 GPBMessage *message4 = [GPBMessage parseDelimitedFromCodedInputStream:input 1953 extensionRegistry:nil 1954 error:NULL]; 1955 XCTAssertEqualObjects(message1, message3); 1956 XCTAssertEqualObjects(message2, message4); 1957} 1958 1959- (void)testDuplicateEnums { 1960 XCTAssertEqual(TestEnumWithDupValue_Foo1, TestEnumWithDupValue_Foo2); 1961} 1962 1963- (void)testWeirdDefaults { 1964 ObjcWeirdDefaults *message = [ObjcWeirdDefaults message]; 1965 GPBDescriptor *descriptor = [[message class] descriptor]; 1966 GPBFieldDescriptor *fieldDesc = [descriptor fieldWithName:@"foo"]; 1967 XCTAssertNotNil(fieldDesc); 1968 XCTAssertTrue(fieldDesc.hasDefaultValue); 1969 XCTAssertFalse(message.hasFoo); 1970 XCTAssertEqualObjects(message.foo, @""); 1971 1972 fieldDesc = [descriptor fieldWithName:@"bar"]; 1973 XCTAssertNotNil(fieldDesc); 1974 XCTAssertTrue(fieldDesc.hasDefaultValue); 1975 XCTAssertFalse(message.hasBar); 1976 XCTAssertEqualObjects(message.bar, GPBEmptyNSData()); 1977} 1978 1979- (void)testEnumDescriptorFromExtensionDescriptor { 1980 GPBExtensionDescriptor *extDescriptor = [UnittestRoot optionalForeignEnumExtension]; 1981 XCTAssertEqual(extDescriptor.dataType, GPBDataTypeEnum); 1982 GPBEnumDescriptor *enumDescriptor = extDescriptor.enumDescriptor; 1983 GPBEnumDescriptor *expectedDescriptor = ForeignEnum_EnumDescriptor(); 1984 XCTAssertEqualObjects(enumDescriptor, expectedDescriptor); 1985} 1986 1987- (void)testPropertyNaming { 1988 // names.cc has some special handing to get proper all caps for a few cases to 1989 // meet objc developer expectations. 1990 // 1991 // This "test" confirms that the expected names are generated, otherwise the 1992 // test itself will fail to compile. 1993 ObjCPropertyNaming *msg = [ObjCPropertyNaming message]; 1994 // On their own, at the end, in the middle. 1995 msg.URL = @"good"; 1996 msg.thumbnailURL = @"good"; 1997 msg.URLFoo = @"good"; 1998 msg.someURLBlah = @"good"; 1999 msg.HTTP = @"good"; 2000 msg.HTTPS = @"good"; 2001 // No caps since it was "urls". 2002 [msg.urlsArray addObject:@"good"]; 2003} 2004 2005- (void)testEnumNaming { 2006 // names.cc has some interesting cases to deal with in 2007 // EnumValueName/EnumValueShortName. Confirm that things generated as 2008 // expected. 2009 2010 // This block just has to compile to confirm we got the expected types/names. 2011 // The *_IsValidValue() calls are just there to keep the projects warnings 2012 // flags happy by providing use of the variables/values. 2013 2014 Foo aFoo = Foo_SerializedSize; 2015 Foo_IsValidValue(aFoo); 2016 aFoo = Foo_Size; 2017 Foo_IsValidValue(aFoo); 2018 2019 Category_Enum aCat = Category_Enum_Red; 2020 Category_Enum_IsValidValue(aCat); 2021 2022 Time aTime = Time_Base; 2023 Time_IsValidValue(aTime); 2024 aTime = Time_SomethingElse; 2025 Time_IsValidValue(aTime); 2026 2027 // This block confirms the names in the descriptors is what we wanted. 2028 2029 GPBEnumDescriptor *descriptor; 2030 NSString *valueName; 2031 2032 descriptor = Foo_EnumDescriptor(); 2033 XCTAssertNotNil(descriptor); 2034 XCTAssertEqualObjects(@"Foo", descriptor.name); 2035 valueName = [descriptor enumNameForValue:Foo_SerializedSize]; 2036 XCTAssertEqualObjects(@"Foo_SerializedSize", valueName); 2037 valueName = [descriptor enumNameForValue:Foo_Size]; 2038 XCTAssertEqualObjects(@"Foo_Size", valueName); 2039 2040 descriptor = Category_Enum_EnumDescriptor(); 2041 XCTAssertNotNil(descriptor); 2042 XCTAssertEqualObjects(@"Category_Enum", descriptor.name); 2043 valueName = [descriptor enumNameForValue:Category_Enum_Red]; 2044 XCTAssertEqualObjects(@"Category_Enum_Red", valueName); 2045 2046 descriptor = Time_EnumDescriptor(); 2047 XCTAssertNotNil(descriptor); 2048 XCTAssertEqualObjects(@"Time", descriptor.name); 2049 valueName = [descriptor enumNameForValue:Time_Base]; 2050 XCTAssertEqualObjects(@"Time_Base", valueName); 2051 valueName = [descriptor enumNameForValue:Time_SomethingElse]; 2052 XCTAssertEqualObjects(@"Time_SomethingElse", valueName); 2053} 2054 2055- (void)testNegativeEnums { 2056 EnumTestMsg *msg = [EnumTestMsg message]; 2057 2058 // Defaults 2059 XCTAssertEqual(msg.foo, EnumTestMsg_MyEnum_Zero); 2060 XCTAssertEqual(msg.bar, EnumTestMsg_MyEnum_One); 2061 XCTAssertEqual(msg.baz, EnumTestMsg_MyEnum_NegOne); 2062 // Bounce to wire and back. 2063 NSData *data = [msg data]; 2064 XCTAssertNotNil(data); 2065 EnumTestMsg *msgPrime = [EnumTestMsg parseFromData:data error:NULL]; 2066 XCTAssertEqualObjects(msgPrime, msg); 2067 XCTAssertEqual(msgPrime.foo, EnumTestMsg_MyEnum_Zero); 2068 XCTAssertEqual(msgPrime.bar, EnumTestMsg_MyEnum_One); 2069 XCTAssertEqual(msgPrime.baz, EnumTestMsg_MyEnum_NegOne); 2070 2071 // Other values 2072 msg.bar = EnumTestMsg_MyEnum_Two; 2073 msg.baz = EnumTestMsg_MyEnum_NegTwo; 2074 XCTAssertEqual(msg.bar, EnumTestMsg_MyEnum_Two); 2075 XCTAssertEqual(msg.baz, EnumTestMsg_MyEnum_NegTwo); 2076 // Bounce to wire and back. 2077 data = [msg data]; 2078 XCTAssertNotNil(data); 2079 msgPrime = [EnumTestMsg parseFromData:data error:NULL]; 2080 XCTAssertEqualObjects(msgPrime, msg); 2081 XCTAssertEqual(msgPrime.foo, EnumTestMsg_MyEnum_Zero); 2082 XCTAssertEqual(msgPrime.bar, EnumTestMsg_MyEnum_Two); 2083 XCTAssertEqual(msgPrime.baz, EnumTestMsg_MyEnum_NegTwo); 2084 2085 // Repeated field (shouldn't ever be an issue since developer has to use the 2086 // right GPBArray methods themselves). 2087 msg.mumbleArray = [GPBEnumArray arrayWithValidationFunction:EnumTestMsg_MyEnum_IsValidValue]; 2088 [msg.mumbleArray addValue:EnumTestMsg_MyEnum_Zero]; 2089 [msg.mumbleArray addValue:EnumTestMsg_MyEnum_One]; 2090 [msg.mumbleArray addValue:EnumTestMsg_MyEnum_Two]; 2091 [msg.mumbleArray addValue:EnumTestMsg_MyEnum_NegOne]; 2092 [msg.mumbleArray addValue:EnumTestMsg_MyEnum_NegTwo]; 2093 XCTAssertEqual([msg.mumbleArray valueAtIndex:0], EnumTestMsg_MyEnum_Zero); 2094 XCTAssertEqual([msg.mumbleArray valueAtIndex:1], EnumTestMsg_MyEnum_One); 2095 XCTAssertEqual([msg.mumbleArray valueAtIndex:2], EnumTestMsg_MyEnum_Two); 2096 XCTAssertEqual([msg.mumbleArray valueAtIndex:3], EnumTestMsg_MyEnum_NegOne); 2097 XCTAssertEqual([msg.mumbleArray valueAtIndex:4], EnumTestMsg_MyEnum_NegTwo); 2098 // Bounce to wire and back. 2099 data = [msg data]; 2100 XCTAssertNotNil(data); 2101 msgPrime = [EnumTestMsg parseFromData:data error:NULL]; 2102 XCTAssertEqualObjects(msgPrime, msg); 2103 XCTAssertEqual([msgPrime.mumbleArray valueAtIndex:0], EnumTestMsg_MyEnum_Zero); 2104 XCTAssertEqual([msgPrime.mumbleArray valueAtIndex:1], EnumTestMsg_MyEnum_One); 2105 XCTAssertEqual([msgPrime.mumbleArray valueAtIndex:2], EnumTestMsg_MyEnum_Two); 2106 XCTAssertEqual([msgPrime.mumbleArray valueAtIndex:3], EnumTestMsg_MyEnum_NegOne); 2107 XCTAssertEqual([msgPrime.mumbleArray valueAtIndex:4], EnumTestMsg_MyEnum_NegTwo); 2108} 2109 2110- (void)testCloseEnumsValuesOutOfRange { 2111 // The unknown values should all make it into the unknown fields. 2112 EnumTestMsg *msg1 = [EnumTestMsg message]; 2113 msg1.bar = EnumTestMsg_MyEnum_NegTwo; 2114 msg1.baz = EnumTestMsg_MyEnum_Two; 2115 [msg1.mumbleArray addValue:EnumTestMsg_MyEnum_Two]; 2116 [msg1.mumbleArray addValue:EnumTestMsg_MyEnum_NegTwo]; 2117 2118 NSData *data = [msg1 data]; 2119 XCTAssertNotNil(data); 2120 2121 EnumTestMsgPrime *msg2 = [EnumTestMsgPrime parseFromData:data error:NULL]; 2122 XCTAssertNotNil(msg2); 2123 XCTAssertEqualObjects(data, [msg2 data]); 2124 XCTAssertFalse(msg2.hasBar); 2125 XCTAssertFalse(msg2.hasBaz); 2126 XCTAssertEqual(msg2.mumbleArray_Count, 0U); 2127 2128 GPBUnknownFields *ufs = [[[GPBUnknownFields alloc] initFromMessage:msg2] autorelease]; 2129 XCTAssertEqual(ufs.count, 4U); 2130 uint64_t varint; 2131 XCTAssertTrue([ufs getFirst:EnumTestMsg_FieldNumber_Bar varint:&varint]); 2132 XCTAssertEqual(varint, (uint64_t)EnumTestMsg_MyEnum_NegTwo); 2133 XCTAssertTrue([ufs getFirst:EnumTestMsg_FieldNumber_Baz varint:&varint]); 2134 XCTAssertEqual(varint, (uint64_t)EnumTestMsg_MyEnum_Two); 2135 NSArray<GPBUnknownField *> *fields = [ufs fields:EnumTestMsg_FieldNumber_MumbleArray]; 2136 XCTAssertEqual(fields.count, 2U); 2137 XCTAssertEqual(fields[0].varint, (uint64_t)EnumTestMsg_MyEnum_Two); 2138 XCTAssertEqual(fields[1].varint, (uint64_t)EnumTestMsg_MyEnum_NegTwo); 2139 2140#pragma clang diagnostic push 2141#pragma clang diagnostic ignored "-Wdeprecated-declarations" 2142 GPBUnknownFieldSet *unknownFields = msg2.unknownFields; 2143 XCTAssertNotNil(unknownFields); 2144 XCTAssertEqual(unknownFields.countOfFields, 3U); 2145 XCTAssertTrue([unknownFields hasField:EnumTestMsg_FieldNumber_Bar]); 2146 XCTAssertTrue([unknownFields hasField:EnumTestMsg_FieldNumber_Baz]); 2147 XCTAssertTrue([unknownFields hasField:EnumTestMsg_FieldNumber_MumbleArray]); 2148 GPBUnknownField *field = [unknownFields getField:EnumTestMsg_FieldNumber_Bar]; 2149 XCTAssertEqual(field.varintList.count, 1U); 2150 XCTAssertEqual([field.varintList valueAtIndex:0], (uint64_t)EnumTestMsg_MyEnum_NegTwo); 2151 field = [unknownFields getField:EnumTestMsg_FieldNumber_Baz]; 2152 XCTAssertEqual(field.varintList.count, 1U); 2153 XCTAssertEqual([field.varintList valueAtIndex:0], (uint64_t)EnumTestMsg_MyEnum_Two); 2154 field = [unknownFields getField:EnumTestMsg_FieldNumber_MumbleArray]; 2155 XCTAssertEqual(field.varintList.count, 2U); 2156 XCTAssertEqual([field.varintList valueAtIndex:0], (uint64_t)EnumTestMsg_MyEnum_Two); 2157 XCTAssertEqual([field.varintList valueAtIndex:1], (uint64_t)EnumTestMsg_MyEnum_NegTwo); 2158#pragma clang diagnostic pop 2159} 2160 2161- (void)testReservedWordNaming { 2162 // names.cc has some special handing to make sure that some "reserved" objc 2163 // names get renamed in a way so they don't conflict. 2164 // 2165 // This "test" confirms that the expected names are generated, 2166 // otherwise the test itself will fail to compile. 2167 self_Class *msg = [self_Class message]; 2168 2169 // Some ObjC/C/C++ keywords. 2170 msg.className_p = msg.hasClassName_p; 2171 msg.cmd = msg.hasCmd; 2172 msg.nullable_p = msg.hasNullable_p; 2173 msg.typeof_p = msg.hasTypeof_p; 2174 msg.instancetype_p = msg.hasInstancetype_p; 2175 msg.nil_p = msg.hasNil_p; 2176 msg.instancetype_p = msg.hasInstancetype_p; 2177 msg.public_p = msg.hasPublic_p; 2178 2179 // Some that would override NSObject methods 2180 msg.camltype = msg.hasCamltype; 2181 msg.isNsdictionary = msg.hasIsNsdictionary; 2182 msg.dealloc_p = msg.hasDealloc_p; 2183 msg.zone_p = msg.hasZone_p; 2184 msg.accessibilityLabel_p = msg.hasAccessibilityLabel_p; 2185 2186 // Some that we shouldn't need to handle. 2187 msg.atomic = msg.hasAtomic; 2188 msg.nonatomic = msg.hasNonatomic; 2189 msg.strong = msg.hasStrong; 2190 msg.nullResettable = msg.hasNullResettable; 2191 2192 // Some that would override GPBMessage methods 2193 msg.clear_p = msg.hasClear_p; 2194 msg.data_p = msg.hasData_p; 2195 2196 // Some MacTypes 2197 msg.fixed = msg.hasFixed; 2198 msg.style = msg.hasStyle; 2199 2200 // Some C Identifiers 2201 msg.generic = msg.hasGeneric; 2202 msg.block = msg.hasBlock; 2203} 2204 2205- (void)testOneBasedEnumHolder { 2206 // Test case for https://github.com/protocolbuffers/protobuf/issues/1453 2207 // Message with no explicit defaults, but a non zero default for an enum. 2208 MessageWithOneBasedEnum *enumMsg = [MessageWithOneBasedEnum message]; 2209 XCTAssertEqual(enumMsg.enumField, MessageWithOneBasedEnum_OneBasedEnum_One); 2210} 2211 2212- (void)testBoolOffsetUsage { 2213 // Bools use storage within has_bits; this test ensures that this is honored 2214 // in all places where things should crash or fail based on reading out of 2215 // field storage instead. 2216 BoolOnlyMessage *msg1 = [BoolOnlyMessage message]; 2217 BoolOnlyMessage *msg2 = [BoolOnlyMessage message]; 2218 2219 msg1.boolField1 = YES; 2220 msg2.boolField1 = YES; 2221 msg1.boolField3 = YES; 2222 msg2.boolField3 = YES; 2223 msg1.boolField5 = YES; 2224 msg2.boolField5 = YES; 2225 msg1.boolField7 = YES; 2226 msg2.boolField7 = YES; 2227 msg1.boolField9 = YES; 2228 msg2.boolField9 = YES; 2229 msg1.boolField11 = YES; 2230 msg2.boolField11 = YES; 2231 msg1.boolField13 = YES; 2232 msg2.boolField13 = YES; 2233 msg1.boolField15 = YES; 2234 msg2.boolField15 = YES; 2235 msg1.boolField17 = YES; 2236 msg2.boolField17 = YES; 2237 msg1.boolField19 = YES; 2238 msg2.boolField19 = YES; 2239 msg1.boolField21 = YES; 2240 msg2.boolField21 = YES; 2241 msg1.boolField23 = YES; 2242 msg2.boolField23 = YES; 2243 msg1.boolField25 = YES; 2244 msg2.boolField25 = YES; 2245 msg1.boolField27 = YES; 2246 msg2.boolField27 = YES; 2247 msg1.boolField29 = YES; 2248 msg2.boolField29 = YES; 2249 msg1.boolField31 = YES; 2250 msg2.boolField31 = YES; 2251 2252 msg1.boolField32 = YES; 2253 msg2.boolField32 = YES; 2254 2255 XCTAssertTrue(msg1 != msg2); // Different pointers. 2256 XCTAssertEqual([msg1 hash], [msg2 hash]); 2257 XCTAssertEqualObjects(msg1, msg2); 2258 2259 BoolOnlyMessage *msg1Prime = [[msg1 copy] autorelease]; 2260 XCTAssertTrue(msg1Prime != msg1); // Different pointers. 2261 XCTAssertEqual([msg1 hash], [msg1Prime hash]); 2262 XCTAssertEqualObjects(msg1, msg1Prime); 2263 2264 // Field set in one, but not the other means they don't match (even if 2265 // set to default value). 2266 msg1Prime.boolField2 = NO; 2267 XCTAssertNotEqualObjects(msg1Prime, msg1); 2268 // And when set to different values. 2269 msg1.boolField2 = YES; 2270 XCTAssertNotEqualObjects(msg1Prime, msg1); 2271 // And then they match again. 2272 msg1.boolField2 = NO; 2273 XCTAssertEqualObjects(msg1Prime, msg1); 2274 XCTAssertEqual([msg1 hash], [msg1Prime hash]); 2275} 2276 2277- (void)testCopyingMapFields { 2278 TestMessageOfMaps *msg = [TestMessageOfMaps message]; 2279 2280 msg.strToStr[@"foo"] = @"bar"; 2281 2282 [msg.strToInt setInt32:1 forKey:@"mumble"]; 2283 [msg.intToStr setObject:@"wee" forKey:42]; 2284 [msg.intToInt setInt32:123 forKey:321]; 2285 2286 [msg.strToBool setBool:YES forKey:@"one"]; 2287 [msg.boolToStr setObject:@"something" forKey:YES]; 2288 [msg.boolToBool setBool:YES forKey:NO]; 2289 2290 [msg.intToBool setBool:YES forKey:13]; 2291 [msg.boolToInt setInt32:111 forKey:NO]; 2292 2293 TestAllTypes *subMsg1 = [TestAllTypes message]; 2294 subMsg1.optionalInt32 = 1; 2295 TestAllTypes *subMsg2 = [TestAllTypes message]; 2296 subMsg1.optionalInt32 = 2; 2297 TestAllTypes *subMsg3 = [TestAllTypes message]; 2298 subMsg1.optionalInt32 = 3; 2299 2300 msg.strToMsg[@"baz"] = subMsg1; 2301 [msg.intToMsg setObject:subMsg2 forKey:222]; 2302 [msg.boolToMsg setObject:subMsg3 forKey:YES]; 2303 2304 TestMessageOfMaps *msg2 = [[msg copy] autorelease]; 2305 XCTAssertNotNil(msg2); 2306 XCTAssertEqualObjects(msg2, msg); 2307 XCTAssertTrue(msg2 != msg); // ptr compare 2308 XCTAssertTrue(msg.strToStr != msg2.strToStr); // ptr compare 2309 XCTAssertTrue(msg.intToStr != msg2.intToStr); // ptr compare 2310 XCTAssertTrue(msg.intToInt != msg2.intToInt); // ptr compare 2311 XCTAssertTrue(msg.strToBool != msg2.strToBool); // ptr compare 2312 XCTAssertTrue(msg.boolToStr != msg2.boolToStr); // ptr compare 2313 XCTAssertTrue(msg.boolToBool != msg2.boolToBool); // ptr compare 2314 XCTAssertTrue(msg.intToBool != msg2.intToBool); // ptr compare 2315 XCTAssertTrue(msg.boolToInt != msg2.boolToInt); // ptr compare 2316 XCTAssertTrue(msg.strToMsg != msg2.strToMsg); // ptr compare 2317 XCTAssertTrue(msg.intToMsg != msg2.intToMsg); // ptr compare 2318 XCTAssertTrue(msg.boolToMsg != msg2.boolToMsg); // ptr compare 2319 2320 XCTAssertTrue(msg.strToMsg[@"baz"] != msg2.strToMsg[@"baz"]); // ptr compare 2321 XCTAssertEqualObjects(msg.strToMsg[@"baz"], msg2.strToMsg[@"baz"]); 2322 XCTAssertTrue([msg.intToMsg objectForKey:222] != 2323 [msg2.intToMsg objectForKey:222]); // ptr compare 2324 XCTAssertEqualObjects([msg.intToMsg objectForKey:222], [msg2.intToMsg objectForKey:222]); 2325 XCTAssertTrue([msg.boolToMsg objectForKey:YES] != 2326 [msg2.boolToMsg objectForKey:YES]); // ptr compare 2327 XCTAssertEqualObjects([msg.boolToMsg objectForKey:YES], [msg2.boolToMsg objectForKey:YES]); 2328} 2329 2330- (void)testPrefixedNames { 2331 // The fact that this compiles is sufficient as a test. 2332 // The assertions are just there to avoid "not-used" warnings. 2333 2334 // Verify that enum types and values get the prefix. 2335 GPBTESTTestObjcProtoPrefixEnum value = GPBTESTTestObjcProtoPrefixEnum_Value; 2336 XCTAssertNotEqual(value, 0); 2337 2338 // Verify that roots get the prefix. 2339 GPBTESTUnittestObjcOptionsRoot *root = nil; 2340 XCTAssertNil(root); 2341 2342 // Verify that messages that don't already have the prefix get a prefix. 2343 GPBTESTTestObjcProtoPrefixMessage *prefixedMessage = nil; 2344 XCTAssertNil(prefixedMessage); 2345 2346 // Verify that messages that already have a prefix aren't prefixed twice. 2347 GPBTESTTestHasAPrefixMessage *alreadyPrefixedMessage = nil; 2348 XCTAssertNil(alreadyPrefixedMessage); 2349 2350 // Verify that enums that already have a prefix aren't prefixed twice. 2351 GPBTESTTestHasAPrefixEnum prefixedValue = GPBTESTTestHasAPrefixEnum_ValueB; 2352 XCTAssertNotEqual(prefixedValue, 0); 2353 2354 // Verify that classes named the same as prefixes are prefixed. 2355 GPBTESTGPBTEST *prefixMessage = nil; 2356 XCTAssertNil(prefixMessage); 2357 2358 // Verify that classes that have the prefix followed by a lowercase 2359 // letter DO get the prefix. 2360 GPBTESTGPBTESTshouldGetAPrefixMessage *shouldGetAPrefixMessage = nil; 2361 XCTAssertNil(shouldGetAPrefixMessage); 2362} 2363 2364- (void)testWriteToFullOutputStreamShouldThrow { 2365 uint8_t buffer[1] = {0}; 2366 2367 // Output stream which can write precisely 1 byte of data before it's full. 2368 NSOutputStream *output = [[[NSOutputStream alloc] initToBuffer:buffer 2369 capacity:sizeof(buffer)] autorelease]; 2370 2371 TestAllTypes *message = [TestAllTypes message]; 2372 [message setOptionalInt32:1]; 2373 XCTAssertThrowsSpecificNamed([message writeToOutputStream:output], NSException, 2374 GPBCodedOutputStreamException_WriteFailed); 2375} 2376 2377@end 2378