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