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