OLD | NEW |
| (Empty) |
1 // Protocol Buffers - Google's data interchange format | |
2 // Copyright 2008 Google Inc. All rights reserved. | |
3 // https://developers.google.com/protocol-buffers/ | |
4 // | |
5 // Redistribution and use in source and binary forms, with or without | |
6 // modification, are permitted provided that the following conditions are | |
7 // met: | |
8 // | |
9 // * Redistributions of source code must retain the above copyright | |
10 // notice, this list of conditions and the following disclaimer. | |
11 // * Redistributions in binary form must reproduce the above | |
12 // copyright notice, this list of conditions and the following disclaimer | |
13 // in the documentation and/or other materials provided with the | |
14 // distribution. | |
15 // * Neither the name of Google Inc. nor the names of its | |
16 // contributors may be used to endorse or promote products derived from | |
17 // this software without specific prior written permission. | |
18 // | |
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
30 | |
31 #import "GPBTestUtilities.h" | |
32 | |
33 #import <objc/runtime.h> | |
34 | |
35 #import "GPBArray_PackagePrivate.h" | |
36 #import "GPBDescriptor.h" | |
37 #import "GPBDictionary_PackagePrivate.h" | |
38 #import "GPBMessage_PackagePrivate.h" | |
39 #import "GPBUnknownField_PackagePrivate.h" | |
40 #import "GPBUnknownFieldSet_PackagePrivate.h" | |
41 #import "google/protobuf/Unittest.pbobjc.h" | |
42 #import "google/protobuf/UnittestObjc.pbobjc.h" | |
43 | |
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 = [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 | |
279 - (void)testDataFromUninitialized { | |
280 TestRequired *message = [TestRequired message]; | |
281 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); | |
289 #endif // DEBUG | |
290 } | |
291 | |
292 - (void)testInitialized { | |
293 // We're mostly testing that no exception is thrown. | |
294 TestRequired *message = [TestRequired message]; | |
295 XCTAssertFalse(message.initialized); | |
296 } | |
297 | |
298 - (void)testDataFromNestedUninitialized { | |
299 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]]; | |
304 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); | |
312 #endif // DEBUG | |
313 } | |
314 | |
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 | |
327 - (void)testParseUninitialized { | |
328 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); | |
342 #endif // DEBUG | |
343 } | |
344 | |
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]; | |
422 GPBUnknownField *field = | |
423 [[[GPBUnknownField alloc] initWithNumber:2] autorelease]; | |
424 [field addVarint:2]; | |
425 [unknownFields addField:field]; | |
426 field = [[[GPBUnknownField alloc] initWithNumber:3] autorelease]; | |
427 [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); | |
454 GPBGenericValue defaultValue = [fieldDescriptor defaultValue]; | |
455 [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 orphan
ed. | |
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 assign
ed. | |
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); | |
1041 TestAllTypes *message4 = [[message3 copy] autorelease]; | |
1042 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 | |
1164 - (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 cl
ass]]); | |
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 | |
1363 - (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 optionalNestedMessageExtens
ion]]); | |
1454 XCTAssertFalse([message hasExtension:[UnittestRoot optionalForeignMessageExten
sion]]); | |
1455 XCTAssertFalse([message hasExtension:[UnittestRoot optionalImportMessageExtens
ion]]); | |
1456 XCTAssertFalse([message hasExtension:[UnittestRoot optionalPublicImportMessage
Extension]]); | |
1457 XCTAssertFalse([message hasExtension:[UnittestRoot optionalLazyMessageExtensio
n]]); | |
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]; | |
1557 GPBExtensionDescriptor *extension = [UnittestRoot optionalGroupExtension]; | |
1558 [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]; | |
1574 GPBExtensionDescriptor *optionalGroupExtension = | |
1575 [UnittestRoot optionalGroupExtension]; | |
1576 GPBExtensionDescriptor *optionalNestedMessageExtesion = | |
1577 [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]; | |
1606 GPBExtensionDescriptor *optionalGroupExtension = | |
1607 [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]; | |
1623 GPBExtensionDescriptor *optionalGroupExtension = | |
1624 [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]; | |
1641 GPBExtensionDescriptor *optionalGroupExtension = | |
1642 [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 | |
1654 GPBExtensionDescriptor *recursiveExtension = | |
1655 [UnittestObjcRoot recursiveExtension]; | |
1656 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]; | |
1667 GPBExtensionDescriptor *recursiveExtension = | |
1668 [UnittestObjcRoot recursiveExtension]; | |
1669 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]; | |
1691 GPBExtensionDescriptor *optionalGroupExtension = | |
1692 [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 { | |
1701 GPBExtensionDescriptor *recursiveExtension = | |
1702 [UnittestObjcRoot recursiveExtension]; | |
1703 | |
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 { | |
1735 GPBExtensionDescriptor *recursiveExtension = | |
1736 [UnittestObjcRoot recursiveExtension]; | |
1737 | |
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]; | |
1766 GPBMessage *message2 = | |
1767 [GPBMessage parseFromData:data extensionRegistry:nil error:NULL]; | |
1768 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 | |
1791 extensionRegistry:nil | |
1792 error:NULL]; | |
1793 GPBMessage *message4 = [GPBMessage parseDelimitedFromCodedInputStream:input | |
1794 extensionRegistry:nil | |
1795 error:NULL]; | |
1796 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 { | |
1821 GPBExtensionDescriptor *extDescriptor = | |
1822 [UnittestRoot optionalForeignEnumExtension]; | |
1823 XCTAssertEqual(extDescriptor.dataType, GPBDataTypeEnum); | |
1824 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. | |
1887 EnumTestMsg *msgPrime = [EnumTestMsg parseFromData:[msg data] error:NULL]; | |
1888 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. | |
1899 msgPrime = [EnumTestMsg parseFromData:[msg data] error:NULL]; | |
1900 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. | |
1920 msgPrime = [EnumTestMsg parseFromData:[msg 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 | |
OLD | NEW |