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