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