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