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