blob: 5df1d51d59016476846b50958c8728996b5b477a [file] [log] [blame]
Jakob Buchgraber8cc62f72018-07-09 16:45:04 +02001// Protocol Buffers - Google's data interchange format
2// Copyright 2015 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 <Foundation/Foundation.h>
32#import <XCTest/XCTest.h>
33
34#import "GPBDictionary.h"
35
36#import "GPBTestUtilities.h"
37#import "google/protobuf/UnittestRuntimeProto2.pbobjc.h"
38
39// Pull in the macros (using an external file because expanding all tests
40// in a single file makes a file that is failing to work with within Xcode.
41//%PDDM-IMPORT-DEFINES GPBDictionaryTests.pddm
42
43//%PDDM-EXPAND TESTS_FOR_POD_VALUES(String, NSString, *, Objects, @"foo", @"bar", @"baz", @"mumble")
44// This block of code is generated, do not edit it directly.
45
46// To let the testing macros work, add some extra methods to simplify things.
47@interface GPBStringEnumDictionary (TestingTweak)
48+ (instancetype)dictionaryWithEnum:(int32_t)value forKey:(NSString *)key;
49- (instancetype)initWithEnums:(const int32_t [])values
50 forKeys:(const NSString * [])keys
51 count:(NSUInteger)count;
52@end
53
54static BOOL TestingEnum_IsValidValue(int32_t value) {
55 switch (value) {
56 case 700:
57 case 701:
58 case 702:
59 case 703:
60 return YES;
61 default:
62 return NO;
63 }
64}
65
66@implementation GPBStringEnumDictionary (TestingTweak)
67+ (instancetype)dictionaryWithEnum:(int32_t)value forKey:(NSString *)key {
68 // Cast is needed to compiler knows what class we are invoking initWithValues: on to get the
69 // type correct.
70 return [[(GPBStringEnumDictionary*)[self alloc] initWithValidationFunction:TestingEnum_IsValidValue
71 rawValues:&value
72 forKeys:&key
73 count:1] autorelease];
74}
75- (instancetype)initWithEnums:(const int32_t [])values
76 forKeys:(const NSString * [])keys
77 count:(NSUInteger)count {
78 return [self initWithValidationFunction:TestingEnum_IsValidValue
79 rawValues:values
80 forKeys:keys
81 count:count];
82}
83@end
84
85
86#pragma mark - String -> UInt32
87
88@interface GPBStringUInt32DictionaryTests : XCTestCase
89@end
90
91@implementation GPBStringUInt32DictionaryTests
92
93- (void)testEmpty {
94 GPBStringUInt32Dictionary *dict = [[GPBStringUInt32Dictionary alloc] init];
95 XCTAssertNotNil(dict);
96 XCTAssertEqual(dict.count, 0U);
97 XCTAssertFalse([dict getUInt32:NULL forKey:@"foo"]);
98 [dict enumerateKeysAndUInt32sUsingBlock:^(NSString *aKey, uint32_t aValue, BOOL *stop) {
99 #pragma unused(aKey, aValue, stop)
100 XCTFail(@"Shouldn't get here!");
101 }];
102 [dict release];
103}
104
105- (void)testOne {
106 GPBStringUInt32Dictionary *dict = [GPBStringUInt32Dictionary dictionaryWithUInt32:100U forKey:@"foo"];
107 XCTAssertNotNil(dict);
108 XCTAssertEqual(dict.count, 1U);
109 uint32_t value;
110 XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]);
111 XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]);
112 XCTAssertEqual(value, 100U);
113 XCTAssertFalse([dict getUInt32:NULL forKey:@"bar"]);
114 [dict enumerateKeysAndUInt32sUsingBlock:^(NSString *aKey, uint32_t aValue, BOOL *stop) {
115 XCTAssertEqualObjects(aKey, @"foo");
116 XCTAssertEqual(aValue, 100U);
117 XCTAssertNotEqual(stop, NULL);
118 }];
119}
120
121- (void)testBasics {
122 const NSString *kKeys[] = { @"foo", @"bar", @"baz" };
123 const uint32_t kValues[] = { 100U, 101U, 102U };
124 GPBStringUInt32Dictionary *dict =
125 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues
126 forKeys:kKeys
127 count:GPBARRAYSIZE(kValues)];
128 XCTAssertNotNil(dict);
129 XCTAssertEqual(dict.count, 3U);
130 uint32_t value;
131 XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]);
132 XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]);
133 XCTAssertEqual(value, 100U);
134 XCTAssertTrue([dict getUInt32:NULL forKey:@"bar"]);
135 XCTAssertTrue([dict getUInt32:&value forKey:@"bar"]);
136 XCTAssertEqual(value, 101U);
137 XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]);
138 XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]);
139 XCTAssertEqual(value, 102U);
140 XCTAssertFalse([dict getUInt32:NULL forKey:@"mumble"]);
141
142 __block NSUInteger idx = 0;
143 NSString **seenKeys = malloc(3 * sizeof(NSString*));
144 uint32_t *seenValues = malloc(3 * sizeof(uint32_t));
145 [dict enumerateKeysAndUInt32sUsingBlock:^(NSString *aKey, uint32_t aValue, BOOL *stop) {
146 XCTAssertLessThan(idx, 3U);
147 seenKeys[idx] = aKey;
148 seenValues[idx] = aValue;
149 XCTAssertNotEqual(stop, NULL);
150 ++idx;
151 }];
152 for (int i = 0; i < 3; ++i) {
153 BOOL foundKey = NO;
154 for (int j = 0; (j < 3) && !foundKey; ++j) {
155 if ([kKeys[i] isEqual:seenKeys[j]]) {
156 foundKey = YES;
157 XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
158 }
159 }
160 XCTAssertTrue(foundKey, @"i = %d", i);
161 }
162 free(seenKeys);
163 free(seenValues);
164
165 // Stopping the enumeration.
166 idx = 0;
167 [dict enumerateKeysAndUInt32sUsingBlock:^(NSString *aKey, uint32_t aValue, BOOL *stop) {
168 #pragma unused(aKey, aValue)
169 if (idx == 1) *stop = YES;
170 XCTAssertNotEqual(idx, 2U);
171 ++idx;
172 }];
173 [dict release];
174}
175
176- (void)testEquality {
177 const NSString *kKeys1[] = { @"foo", @"bar", @"baz", @"mumble" };
178 const NSString *kKeys2[] = { @"bar", @"foo", @"mumble" };
179 const uint32_t kValues1[] = { 100U, 101U, 102U };
180 const uint32_t kValues2[] = { 100U, 103U, 102U };
181 const uint32_t kValues3[] = { 100U, 101U, 102U, 103U };
182 GPBStringUInt32Dictionary *dict1 =
183 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues1
184 forKeys:kKeys1
185 count:GPBARRAYSIZE(kValues1)];
186 XCTAssertNotNil(dict1);
187 GPBStringUInt32Dictionary *dict1prime =
188 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues1
189 forKeys:kKeys1
190 count:GPBARRAYSIZE(kValues1)];
191 XCTAssertNotNil(dict1prime);
192 GPBStringUInt32Dictionary *dict2 =
193 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues2
194 forKeys:kKeys1
195 count:GPBARRAYSIZE(kValues2)];
196 XCTAssertNotNil(dict2);
197 GPBStringUInt32Dictionary *dict3 =
198 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues1
199 forKeys:kKeys2
200 count:GPBARRAYSIZE(kValues1)];
201 XCTAssertNotNil(dict3);
202 GPBStringUInt32Dictionary *dict4 =
203 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues3
204 forKeys:kKeys1
205 count:GPBARRAYSIZE(kValues3)];
206 XCTAssertNotNil(dict4);
207
208 // 1/1Prime should be different objects, but equal.
209 XCTAssertNotEqual(dict1, dict1prime);
210 XCTAssertEqualObjects(dict1, dict1prime);
211 // Equal, so they must have same hash.
212 XCTAssertEqual([dict1 hash], [dict1prime hash]);
213
214 // 2 is same keys, different values; not equal.
215 XCTAssertNotEqualObjects(dict1, dict2);
216
217 // 3 is different keys, same values; not equal.
218 XCTAssertNotEqualObjects(dict1, dict3);
219
220 // 4 extra pair; not equal
221 XCTAssertNotEqualObjects(dict1, dict4);
222
223 [dict1 release];
224 [dict1prime release];
225 [dict2 release];
226 [dict3 release];
227 [dict4 release];
228}
229
230- (void)testCopy {
231 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
232 const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
233 GPBStringUInt32Dictionary *dict =
234 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues
235 forKeys:kKeys
236 count:GPBARRAYSIZE(kValues)];
237 XCTAssertNotNil(dict);
238
239 GPBStringUInt32Dictionary *dict2 = [dict copy];
240 XCTAssertNotNil(dict2);
241
242 // Should be new object but equal.
243 XCTAssertNotEqual(dict, dict2);
244 XCTAssertEqualObjects(dict, dict2);
245 XCTAssertTrue([dict2 isKindOfClass:[GPBStringUInt32Dictionary class]]);
246
247 [dict2 release];
248 [dict release];
249}
250
251- (void)testDictionaryFromDictionary {
252 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
253 const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
254 GPBStringUInt32Dictionary *dict =
255 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues
256 forKeys:kKeys
257 count:GPBARRAYSIZE(kValues)];
258 XCTAssertNotNil(dict);
259
260 GPBStringUInt32Dictionary *dict2 =
261 [GPBStringUInt32Dictionary dictionaryWithDictionary:dict];
262 XCTAssertNotNil(dict2);
263
264 // Should be new pointer, but equal objects.
265 XCTAssertNotEqual(dict, dict2);
266 XCTAssertEqualObjects(dict, dict2);
267 [dict release];
268}
269
270- (void)testAdds {
271 GPBStringUInt32Dictionary *dict = [GPBStringUInt32Dictionary dictionary];
272 XCTAssertNotNil(dict);
273
274 XCTAssertEqual(dict.count, 0U);
275 [dict setUInt32:100U forKey:@"foo"];
276 XCTAssertEqual(dict.count, 1U);
277
278 const NSString *kKeys[] = { @"bar", @"baz", @"mumble" };
279 const uint32_t kValues[] = { 101U, 102U, 103U };
280 GPBStringUInt32Dictionary *dict2 =
281 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues
282 forKeys:kKeys
283 count:GPBARRAYSIZE(kValues)];
284 XCTAssertNotNil(dict2);
285 [dict addEntriesFromDictionary:dict2];
286 XCTAssertEqual(dict.count, 4U);
287
288 uint32_t value;
289 XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]);
290 XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]);
291 XCTAssertEqual(value, 100U);
292 XCTAssertTrue([dict getUInt32:NULL forKey:@"bar"]);
293 XCTAssertTrue([dict getUInt32:&value forKey:@"bar"]);
294 XCTAssertEqual(value, 101U);
295 XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]);
296 XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]);
297 XCTAssertEqual(value, 102U);
298 XCTAssertTrue([dict getUInt32:NULL forKey:@"mumble"]);
299 XCTAssertTrue([dict getUInt32:&value forKey:@"mumble"]);
300 XCTAssertEqual(value, 103U);
301 [dict2 release];
302}
303
304- (void)testRemove {
305 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
306 const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
307 GPBStringUInt32Dictionary *dict =
308 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues
309 forKeys:kKeys
310 count:GPBARRAYSIZE(kValues)];
311 XCTAssertNotNil(dict);
312 XCTAssertEqual(dict.count, 4U);
313
314 [dict removeUInt32ForKey:@"bar"];
315 XCTAssertEqual(dict.count, 3U);
316 uint32_t value;
317 XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]);
318 XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]);
319 XCTAssertEqual(value, 100U);
320 XCTAssertFalse([dict getUInt32:NULL forKey:@"bar"]);
321 XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]);
322 XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]);
323 XCTAssertEqual(value, 102U);
324 XCTAssertTrue([dict getUInt32:NULL forKey:@"mumble"]);
325 XCTAssertTrue([dict getUInt32:&value forKey:@"mumble"]);
326 XCTAssertEqual(value, 103U);
327
328 // Remove again does nothing.
329 [dict removeUInt32ForKey:@"bar"];
330 XCTAssertEqual(dict.count, 3U);
331 XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]);
332 XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]);
333 XCTAssertEqual(value, 100U);
334 XCTAssertFalse([dict getUInt32:NULL forKey:@"bar"]);
335 XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]);
336 XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]);
337 XCTAssertEqual(value, 102U);
338 XCTAssertTrue([dict getUInt32:NULL forKey:@"mumble"]);
339 XCTAssertTrue([dict getUInt32:&value forKey:@"mumble"]);
340 XCTAssertEqual(value, 103U);
341
342 [dict removeUInt32ForKey:@"mumble"];
343 XCTAssertEqual(dict.count, 2U);
344 XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]);
345 XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]);
346 XCTAssertEqual(value, 100U);
347 XCTAssertFalse([dict getUInt32:NULL forKey:@"bar"]);
348 XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]);
349 XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]);
350 XCTAssertEqual(value, 102U);
351 XCTAssertFalse([dict getUInt32:NULL forKey:@"mumble"]);
352
353 [dict removeAll];
354 XCTAssertEqual(dict.count, 0U);
355 XCTAssertFalse([dict getUInt32:NULL forKey:@"foo"]);
356 XCTAssertFalse([dict getUInt32:NULL forKey:@"bar"]);
357 XCTAssertFalse([dict getUInt32:NULL forKey:@"baz"]);
358 XCTAssertFalse([dict getUInt32:NULL forKey:@"mumble"]);
359 [dict release];
360}
361
362- (void)testInplaceMutation {
363 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
364 const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
365 GPBStringUInt32Dictionary *dict =
366 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues
367 forKeys:kKeys
368 count:GPBARRAYSIZE(kValues)];
369 XCTAssertNotNil(dict);
370 XCTAssertEqual(dict.count, 4U);
371 uint32_t value;
372 XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]);
373 XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]);
374 XCTAssertEqual(value, 100U);
375 XCTAssertTrue([dict getUInt32:NULL forKey:@"bar"]);
376 XCTAssertTrue([dict getUInt32:&value forKey:@"bar"]);
377 XCTAssertEqual(value, 101U);
378 XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]);
379 XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]);
380 XCTAssertEqual(value, 102U);
381 XCTAssertTrue([dict getUInt32:NULL forKey:@"mumble"]);
382 XCTAssertTrue([dict getUInt32:&value forKey:@"mumble"]);
383 XCTAssertEqual(value, 103U);
384
385 [dict setUInt32:103U forKey:@"foo"];
386 XCTAssertEqual(dict.count, 4U);
387 XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]);
388 XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]);
389 XCTAssertEqual(value, 103U);
390 XCTAssertTrue([dict getUInt32:NULL forKey:@"bar"]);
391 XCTAssertTrue([dict getUInt32:&value forKey:@"bar"]);
392 XCTAssertEqual(value, 101U);
393 XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]);
394 XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]);
395 XCTAssertEqual(value, 102U);
396 XCTAssertTrue([dict getUInt32:NULL forKey:@"mumble"]);
397 XCTAssertTrue([dict getUInt32:&value forKey:@"mumble"]);
398 XCTAssertEqual(value, 103U);
399
400 [dict setUInt32:101U forKey:@"mumble"];
401 XCTAssertEqual(dict.count, 4U);
402 XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]);
403 XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]);
404 XCTAssertEqual(value, 103U);
405 XCTAssertTrue([dict getUInt32:NULL forKey:@"bar"]);
406 XCTAssertTrue([dict getUInt32:&value forKey:@"bar"]);
407 XCTAssertEqual(value, 101U);
408 XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]);
409 XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]);
410 XCTAssertEqual(value, 102U);
411 XCTAssertTrue([dict getUInt32:NULL forKey:@"mumble"]);
412 XCTAssertTrue([dict getUInt32:&value forKey:@"mumble"]);
413 XCTAssertEqual(value, 101U);
414
415 const NSString *kKeys2[] = { @"bar", @"baz" };
416 const uint32_t kValues2[] = { 102U, 100U };
417 GPBStringUInt32Dictionary *dict2 =
418 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues2
419 forKeys:kKeys2
420 count:GPBARRAYSIZE(kValues2)];
421 XCTAssertNotNil(dict2);
422 [dict addEntriesFromDictionary:dict2];
423 XCTAssertEqual(dict.count, 4U);
424 XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]);
425 XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]);
426 XCTAssertEqual(value, 103U);
427 XCTAssertTrue([dict getUInt32:NULL forKey:@"bar"]);
428 XCTAssertTrue([dict getUInt32:&value forKey:@"bar"]);
429 XCTAssertEqual(value, 102U);
430 XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]);
431 XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]);
432 XCTAssertEqual(value, 100U);
433 XCTAssertTrue([dict getUInt32:NULL forKey:@"mumble"]);
434 XCTAssertTrue([dict getUInt32:&value forKey:@"mumble"]);
435 XCTAssertEqual(value, 101U);
436
437 [dict2 release];
438 [dict release];
439}
440
441@end
442
443#pragma mark - String -> Int32
444
445@interface GPBStringInt32DictionaryTests : XCTestCase
446@end
447
448@implementation GPBStringInt32DictionaryTests
449
450- (void)testEmpty {
451 GPBStringInt32Dictionary *dict = [[GPBStringInt32Dictionary alloc] init];
452 XCTAssertNotNil(dict);
453 XCTAssertEqual(dict.count, 0U);
454 XCTAssertFalse([dict getInt32:NULL forKey:@"foo"]);
455 [dict enumerateKeysAndInt32sUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
456 #pragma unused(aKey, aValue, stop)
457 XCTFail(@"Shouldn't get here!");
458 }];
459 [dict release];
460}
461
462- (void)testOne {
463 GPBStringInt32Dictionary *dict = [GPBStringInt32Dictionary dictionaryWithInt32:200 forKey:@"foo"];
464 XCTAssertNotNil(dict);
465 XCTAssertEqual(dict.count, 1U);
466 int32_t value;
467 XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]);
468 XCTAssertTrue([dict getInt32:&value forKey:@"foo"]);
469 XCTAssertEqual(value, 200);
470 XCTAssertFalse([dict getInt32:NULL forKey:@"bar"]);
471 [dict enumerateKeysAndInt32sUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
472 XCTAssertEqualObjects(aKey, @"foo");
473 XCTAssertEqual(aValue, 200);
474 XCTAssertNotEqual(stop, NULL);
475 }];
476}
477
478- (void)testBasics {
479 const NSString *kKeys[] = { @"foo", @"bar", @"baz" };
480 const int32_t kValues[] = { 200, 201, 202 };
481 GPBStringInt32Dictionary *dict =
482 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues
483 forKeys:kKeys
484 count:GPBARRAYSIZE(kValues)];
485 XCTAssertNotNil(dict);
486 XCTAssertEqual(dict.count, 3U);
487 int32_t value;
488 XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]);
489 XCTAssertTrue([dict getInt32:&value forKey:@"foo"]);
490 XCTAssertEqual(value, 200);
491 XCTAssertTrue([dict getInt32:NULL forKey:@"bar"]);
492 XCTAssertTrue([dict getInt32:&value forKey:@"bar"]);
493 XCTAssertEqual(value, 201);
494 XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]);
495 XCTAssertTrue([dict getInt32:&value forKey:@"baz"]);
496 XCTAssertEqual(value, 202);
497 XCTAssertFalse([dict getInt32:NULL forKey:@"mumble"]);
498
499 __block NSUInteger idx = 0;
500 NSString **seenKeys = malloc(3 * sizeof(NSString*));
501 int32_t *seenValues = malloc(3 * sizeof(int32_t));
502 [dict enumerateKeysAndInt32sUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
503 XCTAssertLessThan(idx, 3U);
504 seenKeys[idx] = aKey;
505 seenValues[idx] = aValue;
506 XCTAssertNotEqual(stop, NULL);
507 ++idx;
508 }];
509 for (int i = 0; i < 3; ++i) {
510 BOOL foundKey = NO;
511 for (int j = 0; (j < 3) && !foundKey; ++j) {
512 if ([kKeys[i] isEqual:seenKeys[j]]) {
513 foundKey = YES;
514 XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
515 }
516 }
517 XCTAssertTrue(foundKey, @"i = %d", i);
518 }
519 free(seenKeys);
520 free(seenValues);
521
522 // Stopping the enumeration.
523 idx = 0;
524 [dict enumerateKeysAndInt32sUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
525 #pragma unused(aKey, aValue)
526 if (idx == 1) *stop = YES;
527 XCTAssertNotEqual(idx, 2U);
528 ++idx;
529 }];
530 [dict release];
531}
532
533- (void)testEquality {
534 const NSString *kKeys1[] = { @"foo", @"bar", @"baz", @"mumble" };
535 const NSString *kKeys2[] = { @"bar", @"foo", @"mumble" };
536 const int32_t kValues1[] = { 200, 201, 202 };
537 const int32_t kValues2[] = { 200, 203, 202 };
538 const int32_t kValues3[] = { 200, 201, 202, 203 };
539 GPBStringInt32Dictionary *dict1 =
540 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues1
541 forKeys:kKeys1
542 count:GPBARRAYSIZE(kValues1)];
543 XCTAssertNotNil(dict1);
544 GPBStringInt32Dictionary *dict1prime =
545 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues1
546 forKeys:kKeys1
547 count:GPBARRAYSIZE(kValues1)];
548 XCTAssertNotNil(dict1prime);
549 GPBStringInt32Dictionary *dict2 =
550 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues2
551 forKeys:kKeys1
552 count:GPBARRAYSIZE(kValues2)];
553 XCTAssertNotNil(dict2);
554 GPBStringInt32Dictionary *dict3 =
555 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues1
556 forKeys:kKeys2
557 count:GPBARRAYSIZE(kValues1)];
558 XCTAssertNotNil(dict3);
559 GPBStringInt32Dictionary *dict4 =
560 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues3
561 forKeys:kKeys1
562 count:GPBARRAYSIZE(kValues3)];
563 XCTAssertNotNil(dict4);
564
565 // 1/1Prime should be different objects, but equal.
566 XCTAssertNotEqual(dict1, dict1prime);
567 XCTAssertEqualObjects(dict1, dict1prime);
568 // Equal, so they must have same hash.
569 XCTAssertEqual([dict1 hash], [dict1prime hash]);
570
571 // 2 is same keys, different values; not equal.
572 XCTAssertNotEqualObjects(dict1, dict2);
573
574 // 3 is different keys, same values; not equal.
575 XCTAssertNotEqualObjects(dict1, dict3);
576
577 // 4 extra pair; not equal
578 XCTAssertNotEqualObjects(dict1, dict4);
579
580 [dict1 release];
581 [dict1prime release];
582 [dict2 release];
583 [dict3 release];
584 [dict4 release];
585}
586
587- (void)testCopy {
588 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
589 const int32_t kValues[] = { 200, 201, 202, 203 };
590 GPBStringInt32Dictionary *dict =
591 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues
592 forKeys:kKeys
593 count:GPBARRAYSIZE(kValues)];
594 XCTAssertNotNil(dict);
595
596 GPBStringInt32Dictionary *dict2 = [dict copy];
597 XCTAssertNotNil(dict2);
598
599 // Should be new object but equal.
600 XCTAssertNotEqual(dict, dict2);
601 XCTAssertEqualObjects(dict, dict2);
602 XCTAssertTrue([dict2 isKindOfClass:[GPBStringInt32Dictionary class]]);
603
604 [dict2 release];
605 [dict release];
606}
607
608- (void)testDictionaryFromDictionary {
609 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
610 const int32_t kValues[] = { 200, 201, 202, 203 };
611 GPBStringInt32Dictionary *dict =
612 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues
613 forKeys:kKeys
614 count:GPBARRAYSIZE(kValues)];
615 XCTAssertNotNil(dict);
616
617 GPBStringInt32Dictionary *dict2 =
618 [GPBStringInt32Dictionary dictionaryWithDictionary:dict];
619 XCTAssertNotNil(dict2);
620
621 // Should be new pointer, but equal objects.
622 XCTAssertNotEqual(dict, dict2);
623 XCTAssertEqualObjects(dict, dict2);
624 [dict release];
625}
626
627- (void)testAdds {
628 GPBStringInt32Dictionary *dict = [GPBStringInt32Dictionary dictionary];
629 XCTAssertNotNil(dict);
630
631 XCTAssertEqual(dict.count, 0U);
632 [dict setInt32:200 forKey:@"foo"];
633 XCTAssertEqual(dict.count, 1U);
634
635 const NSString *kKeys[] = { @"bar", @"baz", @"mumble" };
636 const int32_t kValues[] = { 201, 202, 203 };
637 GPBStringInt32Dictionary *dict2 =
638 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues
639 forKeys:kKeys
640 count:GPBARRAYSIZE(kValues)];
641 XCTAssertNotNil(dict2);
642 [dict addEntriesFromDictionary:dict2];
643 XCTAssertEqual(dict.count, 4U);
644
645 int32_t value;
646 XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]);
647 XCTAssertTrue([dict getInt32:&value forKey:@"foo"]);
648 XCTAssertEqual(value, 200);
649 XCTAssertTrue([dict getInt32:NULL forKey:@"bar"]);
650 XCTAssertTrue([dict getInt32:&value forKey:@"bar"]);
651 XCTAssertEqual(value, 201);
652 XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]);
653 XCTAssertTrue([dict getInt32:&value forKey:@"baz"]);
654 XCTAssertEqual(value, 202);
655 XCTAssertTrue([dict getInt32:NULL forKey:@"mumble"]);
656 XCTAssertTrue([dict getInt32:&value forKey:@"mumble"]);
657 XCTAssertEqual(value, 203);
658 [dict2 release];
659}
660
661- (void)testRemove {
662 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
663 const int32_t kValues[] = { 200, 201, 202, 203 };
664 GPBStringInt32Dictionary *dict =
665 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues
666 forKeys:kKeys
667 count:GPBARRAYSIZE(kValues)];
668 XCTAssertNotNil(dict);
669 XCTAssertEqual(dict.count, 4U);
670
671 [dict removeInt32ForKey:@"bar"];
672 XCTAssertEqual(dict.count, 3U);
673 int32_t value;
674 XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]);
675 XCTAssertTrue([dict getInt32:&value forKey:@"foo"]);
676 XCTAssertEqual(value, 200);
677 XCTAssertFalse([dict getInt32:NULL forKey:@"bar"]);
678 XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]);
679 XCTAssertTrue([dict getInt32:&value forKey:@"baz"]);
680 XCTAssertEqual(value, 202);
681 XCTAssertTrue([dict getInt32:NULL forKey:@"mumble"]);
682 XCTAssertTrue([dict getInt32:&value forKey:@"mumble"]);
683 XCTAssertEqual(value, 203);
684
685 // Remove again does nothing.
686 [dict removeInt32ForKey:@"bar"];
687 XCTAssertEqual(dict.count, 3U);
688 XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]);
689 XCTAssertTrue([dict getInt32:&value forKey:@"foo"]);
690 XCTAssertEqual(value, 200);
691 XCTAssertFalse([dict getInt32:NULL forKey:@"bar"]);
692 XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]);
693 XCTAssertTrue([dict getInt32:&value forKey:@"baz"]);
694 XCTAssertEqual(value, 202);
695 XCTAssertTrue([dict getInt32:NULL forKey:@"mumble"]);
696 XCTAssertTrue([dict getInt32:&value forKey:@"mumble"]);
697 XCTAssertEqual(value, 203);
698
699 [dict removeInt32ForKey:@"mumble"];
700 XCTAssertEqual(dict.count, 2U);
701 XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]);
702 XCTAssertTrue([dict getInt32:&value forKey:@"foo"]);
703 XCTAssertEqual(value, 200);
704 XCTAssertFalse([dict getInt32:NULL forKey:@"bar"]);
705 XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]);
706 XCTAssertTrue([dict getInt32:&value forKey:@"baz"]);
707 XCTAssertEqual(value, 202);
708 XCTAssertFalse([dict getInt32:NULL forKey:@"mumble"]);
709
710 [dict removeAll];
711 XCTAssertEqual(dict.count, 0U);
712 XCTAssertFalse([dict getInt32:NULL forKey:@"foo"]);
713 XCTAssertFalse([dict getInt32:NULL forKey:@"bar"]);
714 XCTAssertFalse([dict getInt32:NULL forKey:@"baz"]);
715 XCTAssertFalse([dict getInt32:NULL forKey:@"mumble"]);
716 [dict release];
717}
718
719- (void)testInplaceMutation {
720 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
721 const int32_t kValues[] = { 200, 201, 202, 203 };
722 GPBStringInt32Dictionary *dict =
723 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues
724 forKeys:kKeys
725 count:GPBARRAYSIZE(kValues)];
726 XCTAssertNotNil(dict);
727 XCTAssertEqual(dict.count, 4U);
728 int32_t value;
729 XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]);
730 XCTAssertTrue([dict getInt32:&value forKey:@"foo"]);
731 XCTAssertEqual(value, 200);
732 XCTAssertTrue([dict getInt32:NULL forKey:@"bar"]);
733 XCTAssertTrue([dict getInt32:&value forKey:@"bar"]);
734 XCTAssertEqual(value, 201);
735 XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]);
736 XCTAssertTrue([dict getInt32:&value forKey:@"baz"]);
737 XCTAssertEqual(value, 202);
738 XCTAssertTrue([dict getInt32:NULL forKey:@"mumble"]);
739 XCTAssertTrue([dict getInt32:&value forKey:@"mumble"]);
740 XCTAssertEqual(value, 203);
741
742 [dict setInt32:203 forKey:@"foo"];
743 XCTAssertEqual(dict.count, 4U);
744 XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]);
745 XCTAssertTrue([dict getInt32:&value forKey:@"foo"]);
746 XCTAssertEqual(value, 203);
747 XCTAssertTrue([dict getInt32:NULL forKey:@"bar"]);
748 XCTAssertTrue([dict getInt32:&value forKey:@"bar"]);
749 XCTAssertEqual(value, 201);
750 XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]);
751 XCTAssertTrue([dict getInt32:&value forKey:@"baz"]);
752 XCTAssertEqual(value, 202);
753 XCTAssertTrue([dict getInt32:NULL forKey:@"mumble"]);
754 XCTAssertTrue([dict getInt32:&value forKey:@"mumble"]);
755 XCTAssertEqual(value, 203);
756
757 [dict setInt32:201 forKey:@"mumble"];
758 XCTAssertEqual(dict.count, 4U);
759 XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]);
760 XCTAssertTrue([dict getInt32:&value forKey:@"foo"]);
761 XCTAssertEqual(value, 203);
762 XCTAssertTrue([dict getInt32:NULL forKey:@"bar"]);
763 XCTAssertTrue([dict getInt32:&value forKey:@"bar"]);
764 XCTAssertEqual(value, 201);
765 XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]);
766 XCTAssertTrue([dict getInt32:&value forKey:@"baz"]);
767 XCTAssertEqual(value, 202);
768 XCTAssertTrue([dict getInt32:NULL forKey:@"mumble"]);
769 XCTAssertTrue([dict getInt32:&value forKey:@"mumble"]);
770 XCTAssertEqual(value, 201);
771
772 const NSString *kKeys2[] = { @"bar", @"baz" };
773 const int32_t kValues2[] = { 202, 200 };
774 GPBStringInt32Dictionary *dict2 =
775 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues2
776 forKeys:kKeys2
777 count:GPBARRAYSIZE(kValues2)];
778 XCTAssertNotNil(dict2);
779 [dict addEntriesFromDictionary:dict2];
780 XCTAssertEqual(dict.count, 4U);
781 XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]);
782 XCTAssertTrue([dict getInt32:&value forKey:@"foo"]);
783 XCTAssertEqual(value, 203);
784 XCTAssertTrue([dict getInt32:NULL forKey:@"bar"]);
785 XCTAssertTrue([dict getInt32:&value forKey:@"bar"]);
786 XCTAssertEqual(value, 202);
787 XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]);
788 XCTAssertTrue([dict getInt32:&value forKey:@"baz"]);
789 XCTAssertEqual(value, 200);
790 XCTAssertTrue([dict getInt32:NULL forKey:@"mumble"]);
791 XCTAssertTrue([dict getInt32:&value forKey:@"mumble"]);
792 XCTAssertEqual(value, 201);
793
794 [dict2 release];
795 [dict release];
796}
797
798@end
799
800#pragma mark - String -> UInt64
801
802@interface GPBStringUInt64DictionaryTests : XCTestCase
803@end
804
805@implementation GPBStringUInt64DictionaryTests
806
807- (void)testEmpty {
808 GPBStringUInt64Dictionary *dict = [[GPBStringUInt64Dictionary alloc] init];
809 XCTAssertNotNil(dict);
810 XCTAssertEqual(dict.count, 0U);
811 XCTAssertFalse([dict getUInt64:NULL forKey:@"foo"]);
812 [dict enumerateKeysAndUInt64sUsingBlock:^(NSString *aKey, uint64_t aValue, BOOL *stop) {
813 #pragma unused(aKey, aValue, stop)
814 XCTFail(@"Shouldn't get here!");
815 }];
816 [dict release];
817}
818
819- (void)testOne {
820 GPBStringUInt64Dictionary *dict = [GPBStringUInt64Dictionary dictionaryWithUInt64:300U forKey:@"foo"];
821 XCTAssertNotNil(dict);
822 XCTAssertEqual(dict.count, 1U);
823 uint64_t value;
824 XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]);
825 XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]);
826 XCTAssertEqual(value, 300U);
827 XCTAssertFalse([dict getUInt64:NULL forKey:@"bar"]);
828 [dict enumerateKeysAndUInt64sUsingBlock:^(NSString *aKey, uint64_t aValue, BOOL *stop) {
829 XCTAssertEqualObjects(aKey, @"foo");
830 XCTAssertEqual(aValue, 300U);
831 XCTAssertNotEqual(stop, NULL);
832 }];
833}
834
835- (void)testBasics {
836 const NSString *kKeys[] = { @"foo", @"bar", @"baz" };
837 const uint64_t kValues[] = { 300U, 301U, 302U };
838 GPBStringUInt64Dictionary *dict =
839 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues
840 forKeys:kKeys
841 count:GPBARRAYSIZE(kValues)];
842 XCTAssertNotNil(dict);
843 XCTAssertEqual(dict.count, 3U);
844 uint64_t value;
845 XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]);
846 XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]);
847 XCTAssertEqual(value, 300U);
848 XCTAssertTrue([dict getUInt64:NULL forKey:@"bar"]);
849 XCTAssertTrue([dict getUInt64:&value forKey:@"bar"]);
850 XCTAssertEqual(value, 301U);
851 XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]);
852 XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]);
853 XCTAssertEqual(value, 302U);
854 XCTAssertFalse([dict getUInt64:NULL forKey:@"mumble"]);
855
856 __block NSUInteger idx = 0;
857 NSString **seenKeys = malloc(3 * sizeof(NSString*));
858 uint64_t *seenValues = malloc(3 * sizeof(uint64_t));
859 [dict enumerateKeysAndUInt64sUsingBlock:^(NSString *aKey, uint64_t aValue, BOOL *stop) {
860 XCTAssertLessThan(idx, 3U);
861 seenKeys[idx] = aKey;
862 seenValues[idx] = aValue;
863 XCTAssertNotEqual(stop, NULL);
864 ++idx;
865 }];
866 for (int i = 0; i < 3; ++i) {
867 BOOL foundKey = NO;
868 for (int j = 0; (j < 3) && !foundKey; ++j) {
869 if ([kKeys[i] isEqual:seenKeys[j]]) {
870 foundKey = YES;
871 XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
872 }
873 }
874 XCTAssertTrue(foundKey, @"i = %d", i);
875 }
876 free(seenKeys);
877 free(seenValues);
878
879 // Stopping the enumeration.
880 idx = 0;
881 [dict enumerateKeysAndUInt64sUsingBlock:^(NSString *aKey, uint64_t aValue, BOOL *stop) {
882 #pragma unused(aKey, aValue)
883 if (idx == 1) *stop = YES;
884 XCTAssertNotEqual(idx, 2U);
885 ++idx;
886 }];
887 [dict release];
888}
889
890- (void)testEquality {
891 const NSString *kKeys1[] = { @"foo", @"bar", @"baz", @"mumble" };
892 const NSString *kKeys2[] = { @"bar", @"foo", @"mumble" };
893 const uint64_t kValues1[] = { 300U, 301U, 302U };
894 const uint64_t kValues2[] = { 300U, 303U, 302U };
895 const uint64_t kValues3[] = { 300U, 301U, 302U, 303U };
896 GPBStringUInt64Dictionary *dict1 =
897 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues1
898 forKeys:kKeys1
899 count:GPBARRAYSIZE(kValues1)];
900 XCTAssertNotNil(dict1);
901 GPBStringUInt64Dictionary *dict1prime =
902 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues1
903 forKeys:kKeys1
904 count:GPBARRAYSIZE(kValues1)];
905 XCTAssertNotNil(dict1prime);
906 GPBStringUInt64Dictionary *dict2 =
907 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues2
908 forKeys:kKeys1
909 count:GPBARRAYSIZE(kValues2)];
910 XCTAssertNotNil(dict2);
911 GPBStringUInt64Dictionary *dict3 =
912 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues1
913 forKeys:kKeys2
914 count:GPBARRAYSIZE(kValues1)];
915 XCTAssertNotNil(dict3);
916 GPBStringUInt64Dictionary *dict4 =
917 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues3
918 forKeys:kKeys1
919 count:GPBARRAYSIZE(kValues3)];
920 XCTAssertNotNil(dict4);
921
922 // 1/1Prime should be different objects, but equal.
923 XCTAssertNotEqual(dict1, dict1prime);
924 XCTAssertEqualObjects(dict1, dict1prime);
925 // Equal, so they must have same hash.
926 XCTAssertEqual([dict1 hash], [dict1prime hash]);
927
928 // 2 is same keys, different values; not equal.
929 XCTAssertNotEqualObjects(dict1, dict2);
930
931 // 3 is different keys, same values; not equal.
932 XCTAssertNotEqualObjects(dict1, dict3);
933
934 // 4 extra pair; not equal
935 XCTAssertNotEqualObjects(dict1, dict4);
936
937 [dict1 release];
938 [dict1prime release];
939 [dict2 release];
940 [dict3 release];
941 [dict4 release];
942}
943
944- (void)testCopy {
945 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
946 const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
947 GPBStringUInt64Dictionary *dict =
948 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues
949 forKeys:kKeys
950 count:GPBARRAYSIZE(kValues)];
951 XCTAssertNotNil(dict);
952
953 GPBStringUInt64Dictionary *dict2 = [dict copy];
954 XCTAssertNotNil(dict2);
955
956 // Should be new object but equal.
957 XCTAssertNotEqual(dict, dict2);
958 XCTAssertEqualObjects(dict, dict2);
959 XCTAssertTrue([dict2 isKindOfClass:[GPBStringUInt64Dictionary class]]);
960
961 [dict2 release];
962 [dict release];
963}
964
965- (void)testDictionaryFromDictionary {
966 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
967 const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
968 GPBStringUInt64Dictionary *dict =
969 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues
970 forKeys:kKeys
971 count:GPBARRAYSIZE(kValues)];
972 XCTAssertNotNil(dict);
973
974 GPBStringUInt64Dictionary *dict2 =
975 [GPBStringUInt64Dictionary dictionaryWithDictionary:dict];
976 XCTAssertNotNil(dict2);
977
978 // Should be new pointer, but equal objects.
979 XCTAssertNotEqual(dict, dict2);
980 XCTAssertEqualObjects(dict, dict2);
981 [dict release];
982}
983
984- (void)testAdds {
985 GPBStringUInt64Dictionary *dict = [GPBStringUInt64Dictionary dictionary];
986 XCTAssertNotNil(dict);
987
988 XCTAssertEqual(dict.count, 0U);
989 [dict setUInt64:300U forKey:@"foo"];
990 XCTAssertEqual(dict.count, 1U);
991
992 const NSString *kKeys[] = { @"bar", @"baz", @"mumble" };
993 const uint64_t kValues[] = { 301U, 302U, 303U };
994 GPBStringUInt64Dictionary *dict2 =
995 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues
996 forKeys:kKeys
997 count:GPBARRAYSIZE(kValues)];
998 XCTAssertNotNil(dict2);
999 [dict addEntriesFromDictionary:dict2];
1000 XCTAssertEqual(dict.count, 4U);
1001
1002 uint64_t value;
1003 XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]);
1004 XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]);
1005 XCTAssertEqual(value, 300U);
1006 XCTAssertTrue([dict getUInt64:NULL forKey:@"bar"]);
1007 XCTAssertTrue([dict getUInt64:&value forKey:@"bar"]);
1008 XCTAssertEqual(value, 301U);
1009 XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]);
1010 XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]);
1011 XCTAssertEqual(value, 302U);
1012 XCTAssertTrue([dict getUInt64:NULL forKey:@"mumble"]);
1013 XCTAssertTrue([dict getUInt64:&value forKey:@"mumble"]);
1014 XCTAssertEqual(value, 303U);
1015 [dict2 release];
1016}
1017
1018- (void)testRemove {
1019 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
1020 const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
1021 GPBStringUInt64Dictionary *dict =
1022 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues
1023 forKeys:kKeys
1024 count:GPBARRAYSIZE(kValues)];
1025 XCTAssertNotNil(dict);
1026 XCTAssertEqual(dict.count, 4U);
1027
1028 [dict removeUInt64ForKey:@"bar"];
1029 XCTAssertEqual(dict.count, 3U);
1030 uint64_t value;
1031 XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]);
1032 XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]);
1033 XCTAssertEqual(value, 300U);
1034 XCTAssertFalse([dict getUInt64:NULL forKey:@"bar"]);
1035 XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]);
1036 XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]);
1037 XCTAssertEqual(value, 302U);
1038 XCTAssertTrue([dict getUInt64:NULL forKey:@"mumble"]);
1039 XCTAssertTrue([dict getUInt64:&value forKey:@"mumble"]);
1040 XCTAssertEqual(value, 303U);
1041
1042 // Remove again does nothing.
1043 [dict removeUInt64ForKey:@"bar"];
1044 XCTAssertEqual(dict.count, 3U);
1045 XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]);
1046 XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]);
1047 XCTAssertEqual(value, 300U);
1048 XCTAssertFalse([dict getUInt64:NULL forKey:@"bar"]);
1049 XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]);
1050 XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]);
1051 XCTAssertEqual(value, 302U);
1052 XCTAssertTrue([dict getUInt64:NULL forKey:@"mumble"]);
1053 XCTAssertTrue([dict getUInt64:&value forKey:@"mumble"]);
1054 XCTAssertEqual(value, 303U);
1055
1056 [dict removeUInt64ForKey:@"mumble"];
1057 XCTAssertEqual(dict.count, 2U);
1058 XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]);
1059 XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]);
1060 XCTAssertEqual(value, 300U);
1061 XCTAssertFalse([dict getUInt64:NULL forKey:@"bar"]);
1062 XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]);
1063 XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]);
1064 XCTAssertEqual(value, 302U);
1065 XCTAssertFalse([dict getUInt64:NULL forKey:@"mumble"]);
1066
1067 [dict removeAll];
1068 XCTAssertEqual(dict.count, 0U);
1069 XCTAssertFalse([dict getUInt64:NULL forKey:@"foo"]);
1070 XCTAssertFalse([dict getUInt64:NULL forKey:@"bar"]);
1071 XCTAssertFalse([dict getUInt64:NULL forKey:@"baz"]);
1072 XCTAssertFalse([dict getUInt64:NULL forKey:@"mumble"]);
1073 [dict release];
1074}
1075
1076- (void)testInplaceMutation {
1077 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
1078 const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
1079 GPBStringUInt64Dictionary *dict =
1080 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues
1081 forKeys:kKeys
1082 count:GPBARRAYSIZE(kValues)];
1083 XCTAssertNotNil(dict);
1084 XCTAssertEqual(dict.count, 4U);
1085 uint64_t value;
1086 XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]);
1087 XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]);
1088 XCTAssertEqual(value, 300U);
1089 XCTAssertTrue([dict getUInt64:NULL forKey:@"bar"]);
1090 XCTAssertTrue([dict getUInt64:&value forKey:@"bar"]);
1091 XCTAssertEqual(value, 301U);
1092 XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]);
1093 XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]);
1094 XCTAssertEqual(value, 302U);
1095 XCTAssertTrue([dict getUInt64:NULL forKey:@"mumble"]);
1096 XCTAssertTrue([dict getUInt64:&value forKey:@"mumble"]);
1097 XCTAssertEqual(value, 303U);
1098
1099 [dict setUInt64:303U forKey:@"foo"];
1100 XCTAssertEqual(dict.count, 4U);
1101 XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]);
1102 XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]);
1103 XCTAssertEqual(value, 303U);
1104 XCTAssertTrue([dict getUInt64:NULL forKey:@"bar"]);
1105 XCTAssertTrue([dict getUInt64:&value forKey:@"bar"]);
1106 XCTAssertEqual(value, 301U);
1107 XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]);
1108 XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]);
1109 XCTAssertEqual(value, 302U);
1110 XCTAssertTrue([dict getUInt64:NULL forKey:@"mumble"]);
1111 XCTAssertTrue([dict getUInt64:&value forKey:@"mumble"]);
1112 XCTAssertEqual(value, 303U);
1113
1114 [dict setUInt64:301U forKey:@"mumble"];
1115 XCTAssertEqual(dict.count, 4U);
1116 XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]);
1117 XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]);
1118 XCTAssertEqual(value, 303U);
1119 XCTAssertTrue([dict getUInt64:NULL forKey:@"bar"]);
1120 XCTAssertTrue([dict getUInt64:&value forKey:@"bar"]);
1121 XCTAssertEqual(value, 301U);
1122 XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]);
1123 XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]);
1124 XCTAssertEqual(value, 302U);
1125 XCTAssertTrue([dict getUInt64:NULL forKey:@"mumble"]);
1126 XCTAssertTrue([dict getUInt64:&value forKey:@"mumble"]);
1127 XCTAssertEqual(value, 301U);
1128
1129 const NSString *kKeys2[] = { @"bar", @"baz" };
1130 const uint64_t kValues2[] = { 302U, 300U };
1131 GPBStringUInt64Dictionary *dict2 =
1132 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues2
1133 forKeys:kKeys2
1134 count:GPBARRAYSIZE(kValues2)];
1135 XCTAssertNotNil(dict2);
1136 [dict addEntriesFromDictionary:dict2];
1137 XCTAssertEqual(dict.count, 4U);
1138 XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]);
1139 XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]);
1140 XCTAssertEqual(value, 303U);
1141 XCTAssertTrue([dict getUInt64:NULL forKey:@"bar"]);
1142 XCTAssertTrue([dict getUInt64:&value forKey:@"bar"]);
1143 XCTAssertEqual(value, 302U);
1144 XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]);
1145 XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]);
1146 XCTAssertEqual(value, 300U);
1147 XCTAssertTrue([dict getUInt64:NULL forKey:@"mumble"]);
1148 XCTAssertTrue([dict getUInt64:&value forKey:@"mumble"]);
1149 XCTAssertEqual(value, 301U);
1150
1151 [dict2 release];
1152 [dict release];
1153}
1154
1155@end
1156
1157#pragma mark - String -> Int64
1158
1159@interface GPBStringInt64DictionaryTests : XCTestCase
1160@end
1161
1162@implementation GPBStringInt64DictionaryTests
1163
1164- (void)testEmpty {
1165 GPBStringInt64Dictionary *dict = [[GPBStringInt64Dictionary alloc] init];
1166 XCTAssertNotNil(dict);
1167 XCTAssertEqual(dict.count, 0U);
1168 XCTAssertFalse([dict getInt64:NULL forKey:@"foo"]);
1169 [dict enumerateKeysAndInt64sUsingBlock:^(NSString *aKey, int64_t aValue, BOOL *stop) {
1170 #pragma unused(aKey, aValue, stop)
1171 XCTFail(@"Shouldn't get here!");
1172 }];
1173 [dict release];
1174}
1175
1176- (void)testOne {
1177 GPBStringInt64Dictionary *dict = [GPBStringInt64Dictionary dictionaryWithInt64:400 forKey:@"foo"];
1178 XCTAssertNotNil(dict);
1179 XCTAssertEqual(dict.count, 1U);
1180 int64_t value;
1181 XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]);
1182 XCTAssertTrue([dict getInt64:&value forKey:@"foo"]);
1183 XCTAssertEqual(value, 400);
1184 XCTAssertFalse([dict getInt64:NULL forKey:@"bar"]);
1185 [dict enumerateKeysAndInt64sUsingBlock:^(NSString *aKey, int64_t aValue, BOOL *stop) {
1186 XCTAssertEqualObjects(aKey, @"foo");
1187 XCTAssertEqual(aValue, 400);
1188 XCTAssertNotEqual(stop, NULL);
1189 }];
1190}
1191
1192- (void)testBasics {
1193 const NSString *kKeys[] = { @"foo", @"bar", @"baz" };
1194 const int64_t kValues[] = { 400, 401, 402 };
1195 GPBStringInt64Dictionary *dict =
1196 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues
1197 forKeys:kKeys
1198 count:GPBARRAYSIZE(kValues)];
1199 XCTAssertNotNil(dict);
1200 XCTAssertEqual(dict.count, 3U);
1201 int64_t value;
1202 XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]);
1203 XCTAssertTrue([dict getInt64:&value forKey:@"foo"]);
1204 XCTAssertEqual(value, 400);
1205 XCTAssertTrue([dict getInt64:NULL forKey:@"bar"]);
1206 XCTAssertTrue([dict getInt64:&value forKey:@"bar"]);
1207 XCTAssertEqual(value, 401);
1208 XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]);
1209 XCTAssertTrue([dict getInt64:&value forKey:@"baz"]);
1210 XCTAssertEqual(value, 402);
1211 XCTAssertFalse([dict getInt64:NULL forKey:@"mumble"]);
1212
1213 __block NSUInteger idx = 0;
1214 NSString **seenKeys = malloc(3 * sizeof(NSString*));
1215 int64_t *seenValues = malloc(3 * sizeof(int64_t));
1216 [dict enumerateKeysAndInt64sUsingBlock:^(NSString *aKey, int64_t aValue, BOOL *stop) {
1217 XCTAssertLessThan(idx, 3U);
1218 seenKeys[idx] = aKey;
1219 seenValues[idx] = aValue;
1220 XCTAssertNotEqual(stop, NULL);
1221 ++idx;
1222 }];
1223 for (int i = 0; i < 3; ++i) {
1224 BOOL foundKey = NO;
1225 for (int j = 0; (j < 3) && !foundKey; ++j) {
1226 if ([kKeys[i] isEqual:seenKeys[j]]) {
1227 foundKey = YES;
1228 XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
1229 }
1230 }
1231 XCTAssertTrue(foundKey, @"i = %d", i);
1232 }
1233 free(seenKeys);
1234 free(seenValues);
1235
1236 // Stopping the enumeration.
1237 idx = 0;
1238 [dict enumerateKeysAndInt64sUsingBlock:^(NSString *aKey, int64_t aValue, BOOL *stop) {
1239 #pragma unused(aKey, aValue)
1240 if (idx == 1) *stop = YES;
1241 XCTAssertNotEqual(idx, 2U);
1242 ++idx;
1243 }];
1244 [dict release];
1245}
1246
1247- (void)testEquality {
1248 const NSString *kKeys1[] = { @"foo", @"bar", @"baz", @"mumble" };
1249 const NSString *kKeys2[] = { @"bar", @"foo", @"mumble" };
1250 const int64_t kValues1[] = { 400, 401, 402 };
1251 const int64_t kValues2[] = { 400, 403, 402 };
1252 const int64_t kValues3[] = { 400, 401, 402, 403 };
1253 GPBStringInt64Dictionary *dict1 =
1254 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues1
1255 forKeys:kKeys1
1256 count:GPBARRAYSIZE(kValues1)];
1257 XCTAssertNotNil(dict1);
1258 GPBStringInt64Dictionary *dict1prime =
1259 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues1
1260 forKeys:kKeys1
1261 count:GPBARRAYSIZE(kValues1)];
1262 XCTAssertNotNil(dict1prime);
1263 GPBStringInt64Dictionary *dict2 =
1264 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues2
1265 forKeys:kKeys1
1266 count:GPBARRAYSIZE(kValues2)];
1267 XCTAssertNotNil(dict2);
1268 GPBStringInt64Dictionary *dict3 =
1269 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues1
1270 forKeys:kKeys2
1271 count:GPBARRAYSIZE(kValues1)];
1272 XCTAssertNotNil(dict3);
1273 GPBStringInt64Dictionary *dict4 =
1274 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues3
1275 forKeys:kKeys1
1276 count:GPBARRAYSIZE(kValues3)];
1277 XCTAssertNotNil(dict4);
1278
1279 // 1/1Prime should be different objects, but equal.
1280 XCTAssertNotEqual(dict1, dict1prime);
1281 XCTAssertEqualObjects(dict1, dict1prime);
1282 // Equal, so they must have same hash.
1283 XCTAssertEqual([dict1 hash], [dict1prime hash]);
1284
1285 // 2 is same keys, different values; not equal.
1286 XCTAssertNotEqualObjects(dict1, dict2);
1287
1288 // 3 is different keys, same values; not equal.
1289 XCTAssertNotEqualObjects(dict1, dict3);
1290
1291 // 4 extra pair; not equal
1292 XCTAssertNotEqualObjects(dict1, dict4);
1293
1294 [dict1 release];
1295 [dict1prime release];
1296 [dict2 release];
1297 [dict3 release];
1298 [dict4 release];
1299}
1300
1301- (void)testCopy {
1302 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
1303 const int64_t kValues[] = { 400, 401, 402, 403 };
1304 GPBStringInt64Dictionary *dict =
1305 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues
1306 forKeys:kKeys
1307 count:GPBARRAYSIZE(kValues)];
1308 XCTAssertNotNil(dict);
1309
1310 GPBStringInt64Dictionary *dict2 = [dict copy];
1311 XCTAssertNotNil(dict2);
1312
1313 // Should be new object but equal.
1314 XCTAssertNotEqual(dict, dict2);
1315 XCTAssertEqualObjects(dict, dict2);
1316 XCTAssertTrue([dict2 isKindOfClass:[GPBStringInt64Dictionary class]]);
1317
1318 [dict2 release];
1319 [dict release];
1320}
1321
1322- (void)testDictionaryFromDictionary {
1323 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
1324 const int64_t kValues[] = { 400, 401, 402, 403 };
1325 GPBStringInt64Dictionary *dict =
1326 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues
1327 forKeys:kKeys
1328 count:GPBARRAYSIZE(kValues)];
1329 XCTAssertNotNil(dict);
1330
1331 GPBStringInt64Dictionary *dict2 =
1332 [GPBStringInt64Dictionary dictionaryWithDictionary:dict];
1333 XCTAssertNotNil(dict2);
1334
1335 // Should be new pointer, but equal objects.
1336 XCTAssertNotEqual(dict, dict2);
1337 XCTAssertEqualObjects(dict, dict2);
1338 [dict release];
1339}
1340
1341- (void)testAdds {
1342 GPBStringInt64Dictionary *dict = [GPBStringInt64Dictionary dictionary];
1343 XCTAssertNotNil(dict);
1344
1345 XCTAssertEqual(dict.count, 0U);
1346 [dict setInt64:400 forKey:@"foo"];
1347 XCTAssertEqual(dict.count, 1U);
1348
1349 const NSString *kKeys[] = { @"bar", @"baz", @"mumble" };
1350 const int64_t kValues[] = { 401, 402, 403 };
1351 GPBStringInt64Dictionary *dict2 =
1352 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues
1353 forKeys:kKeys
1354 count:GPBARRAYSIZE(kValues)];
1355 XCTAssertNotNil(dict2);
1356 [dict addEntriesFromDictionary:dict2];
1357 XCTAssertEqual(dict.count, 4U);
1358
1359 int64_t value;
1360 XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]);
1361 XCTAssertTrue([dict getInt64:&value forKey:@"foo"]);
1362 XCTAssertEqual(value, 400);
1363 XCTAssertTrue([dict getInt64:NULL forKey:@"bar"]);
1364 XCTAssertTrue([dict getInt64:&value forKey:@"bar"]);
1365 XCTAssertEqual(value, 401);
1366 XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]);
1367 XCTAssertTrue([dict getInt64:&value forKey:@"baz"]);
1368 XCTAssertEqual(value, 402);
1369 XCTAssertTrue([dict getInt64:NULL forKey:@"mumble"]);
1370 XCTAssertTrue([dict getInt64:&value forKey:@"mumble"]);
1371 XCTAssertEqual(value, 403);
1372 [dict2 release];
1373}
1374
1375- (void)testRemove {
1376 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
1377 const int64_t kValues[] = { 400, 401, 402, 403 };
1378 GPBStringInt64Dictionary *dict =
1379 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues
1380 forKeys:kKeys
1381 count:GPBARRAYSIZE(kValues)];
1382 XCTAssertNotNil(dict);
1383 XCTAssertEqual(dict.count, 4U);
1384
1385 [dict removeInt64ForKey:@"bar"];
1386 XCTAssertEqual(dict.count, 3U);
1387 int64_t value;
1388 XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]);
1389 XCTAssertTrue([dict getInt64:&value forKey:@"foo"]);
1390 XCTAssertEqual(value, 400);
1391 XCTAssertFalse([dict getInt64:NULL forKey:@"bar"]);
1392 XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]);
1393 XCTAssertTrue([dict getInt64:&value forKey:@"baz"]);
1394 XCTAssertEqual(value, 402);
1395 XCTAssertTrue([dict getInt64:NULL forKey:@"mumble"]);
1396 XCTAssertTrue([dict getInt64:&value forKey:@"mumble"]);
1397 XCTAssertEqual(value, 403);
1398
1399 // Remove again does nothing.
1400 [dict removeInt64ForKey:@"bar"];
1401 XCTAssertEqual(dict.count, 3U);
1402 XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]);
1403 XCTAssertTrue([dict getInt64:&value forKey:@"foo"]);
1404 XCTAssertEqual(value, 400);
1405 XCTAssertFalse([dict getInt64:NULL forKey:@"bar"]);
1406 XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]);
1407 XCTAssertTrue([dict getInt64:&value forKey:@"baz"]);
1408 XCTAssertEqual(value, 402);
1409 XCTAssertTrue([dict getInt64:NULL forKey:@"mumble"]);
1410 XCTAssertTrue([dict getInt64:&value forKey:@"mumble"]);
1411 XCTAssertEqual(value, 403);
1412
1413 [dict removeInt64ForKey:@"mumble"];
1414 XCTAssertEqual(dict.count, 2U);
1415 XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]);
1416 XCTAssertTrue([dict getInt64:&value forKey:@"foo"]);
1417 XCTAssertEqual(value, 400);
1418 XCTAssertFalse([dict getInt64:NULL forKey:@"bar"]);
1419 XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]);
1420 XCTAssertTrue([dict getInt64:&value forKey:@"baz"]);
1421 XCTAssertEqual(value, 402);
1422 XCTAssertFalse([dict getInt64:NULL forKey:@"mumble"]);
1423
1424 [dict removeAll];
1425 XCTAssertEqual(dict.count, 0U);
1426 XCTAssertFalse([dict getInt64:NULL forKey:@"foo"]);
1427 XCTAssertFalse([dict getInt64:NULL forKey:@"bar"]);
1428 XCTAssertFalse([dict getInt64:NULL forKey:@"baz"]);
1429 XCTAssertFalse([dict getInt64:NULL forKey:@"mumble"]);
1430 [dict release];
1431}
1432
1433- (void)testInplaceMutation {
1434 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
1435 const int64_t kValues[] = { 400, 401, 402, 403 };
1436 GPBStringInt64Dictionary *dict =
1437 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues
1438 forKeys:kKeys
1439 count:GPBARRAYSIZE(kValues)];
1440 XCTAssertNotNil(dict);
1441 XCTAssertEqual(dict.count, 4U);
1442 int64_t value;
1443 XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]);
1444 XCTAssertTrue([dict getInt64:&value forKey:@"foo"]);
1445 XCTAssertEqual(value, 400);
1446 XCTAssertTrue([dict getInt64:NULL forKey:@"bar"]);
1447 XCTAssertTrue([dict getInt64:&value forKey:@"bar"]);
1448 XCTAssertEqual(value, 401);
1449 XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]);
1450 XCTAssertTrue([dict getInt64:&value forKey:@"baz"]);
1451 XCTAssertEqual(value, 402);
1452 XCTAssertTrue([dict getInt64:NULL forKey:@"mumble"]);
1453 XCTAssertTrue([dict getInt64:&value forKey:@"mumble"]);
1454 XCTAssertEqual(value, 403);
1455
1456 [dict setInt64:403 forKey:@"foo"];
1457 XCTAssertEqual(dict.count, 4U);
1458 XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]);
1459 XCTAssertTrue([dict getInt64:&value forKey:@"foo"]);
1460 XCTAssertEqual(value, 403);
1461 XCTAssertTrue([dict getInt64:NULL forKey:@"bar"]);
1462 XCTAssertTrue([dict getInt64:&value forKey:@"bar"]);
1463 XCTAssertEqual(value, 401);
1464 XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]);
1465 XCTAssertTrue([dict getInt64:&value forKey:@"baz"]);
1466 XCTAssertEqual(value, 402);
1467 XCTAssertTrue([dict getInt64:NULL forKey:@"mumble"]);
1468 XCTAssertTrue([dict getInt64:&value forKey:@"mumble"]);
1469 XCTAssertEqual(value, 403);
1470
1471 [dict setInt64:401 forKey:@"mumble"];
1472 XCTAssertEqual(dict.count, 4U);
1473 XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]);
1474 XCTAssertTrue([dict getInt64:&value forKey:@"foo"]);
1475 XCTAssertEqual(value, 403);
1476 XCTAssertTrue([dict getInt64:NULL forKey:@"bar"]);
1477 XCTAssertTrue([dict getInt64:&value forKey:@"bar"]);
1478 XCTAssertEqual(value, 401);
1479 XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]);
1480 XCTAssertTrue([dict getInt64:&value forKey:@"baz"]);
1481 XCTAssertEqual(value, 402);
1482 XCTAssertTrue([dict getInt64:NULL forKey:@"mumble"]);
1483 XCTAssertTrue([dict getInt64:&value forKey:@"mumble"]);
1484 XCTAssertEqual(value, 401);
1485
1486 const NSString *kKeys2[] = { @"bar", @"baz" };
1487 const int64_t kValues2[] = { 402, 400 };
1488 GPBStringInt64Dictionary *dict2 =
1489 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues2
1490 forKeys:kKeys2
1491 count:GPBARRAYSIZE(kValues2)];
1492 XCTAssertNotNil(dict2);
1493 [dict addEntriesFromDictionary:dict2];
1494 XCTAssertEqual(dict.count, 4U);
1495 XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]);
1496 XCTAssertTrue([dict getInt64:&value forKey:@"foo"]);
1497 XCTAssertEqual(value, 403);
1498 XCTAssertTrue([dict getInt64:NULL forKey:@"bar"]);
1499 XCTAssertTrue([dict getInt64:&value forKey:@"bar"]);
1500 XCTAssertEqual(value, 402);
1501 XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]);
1502 XCTAssertTrue([dict getInt64:&value forKey:@"baz"]);
1503 XCTAssertEqual(value, 400);
1504 XCTAssertTrue([dict getInt64:NULL forKey:@"mumble"]);
1505 XCTAssertTrue([dict getInt64:&value forKey:@"mumble"]);
1506 XCTAssertEqual(value, 401);
1507
1508 [dict2 release];
1509 [dict release];
1510}
1511
1512@end
1513
1514#pragma mark - String -> Bool
1515
1516@interface GPBStringBoolDictionaryTests : XCTestCase
1517@end
1518
1519@implementation GPBStringBoolDictionaryTests
1520
1521- (void)testEmpty {
1522 GPBStringBoolDictionary *dict = [[GPBStringBoolDictionary alloc] init];
1523 XCTAssertNotNil(dict);
1524 XCTAssertEqual(dict.count, 0U);
1525 XCTAssertFalse([dict getBool:NULL forKey:@"foo"]);
1526 [dict enumerateKeysAndBoolsUsingBlock:^(NSString *aKey, BOOL aValue, BOOL *stop) {
1527 #pragma unused(aKey, aValue, stop)
1528 XCTFail(@"Shouldn't get here!");
1529 }];
1530 [dict release];
1531}
1532
1533- (void)testOne {
1534 GPBStringBoolDictionary *dict = [GPBStringBoolDictionary dictionaryWithBool:YES forKey:@"foo"];
1535 XCTAssertNotNil(dict);
1536 XCTAssertEqual(dict.count, 1U);
1537 BOOL value;
1538 XCTAssertTrue([dict getBool:NULL forKey:@"foo"]);
1539 XCTAssertTrue([dict getBool:&value forKey:@"foo"]);
1540 XCTAssertEqual(value, YES);
1541 XCTAssertFalse([dict getBool:NULL forKey:@"bar"]);
1542 [dict enumerateKeysAndBoolsUsingBlock:^(NSString *aKey, BOOL aValue, BOOL *stop) {
1543 XCTAssertEqualObjects(aKey, @"foo");
1544 XCTAssertEqual(aValue, YES);
1545 XCTAssertNotEqual(stop, NULL);
1546 }];
1547}
1548
1549- (void)testBasics {
1550 const NSString *kKeys[] = { @"foo", @"bar", @"baz" };
1551 const BOOL kValues[] = { YES, YES, NO };
1552 GPBStringBoolDictionary *dict =
1553 [[GPBStringBoolDictionary alloc] initWithBools:kValues
1554 forKeys:kKeys
1555 count:GPBARRAYSIZE(kValues)];
1556 XCTAssertNotNil(dict);
1557 XCTAssertEqual(dict.count, 3U);
1558 BOOL value;
1559 XCTAssertTrue([dict getBool:NULL forKey:@"foo"]);
1560 XCTAssertTrue([dict getBool:&value forKey:@"foo"]);
1561 XCTAssertEqual(value, YES);
1562 XCTAssertTrue([dict getBool:NULL forKey:@"bar"]);
1563 XCTAssertTrue([dict getBool:&value forKey:@"bar"]);
1564 XCTAssertEqual(value, YES);
1565 XCTAssertTrue([dict getBool:NULL forKey:@"baz"]);
1566 XCTAssertTrue([dict getBool:&value forKey:@"baz"]);
1567 XCTAssertEqual(value, NO);
1568 XCTAssertFalse([dict getBool:NULL forKey:@"mumble"]);
1569
1570 __block NSUInteger idx = 0;
1571 NSString **seenKeys = malloc(3 * sizeof(NSString*));
1572 BOOL *seenValues = malloc(3 * sizeof(BOOL));
1573 [dict enumerateKeysAndBoolsUsingBlock:^(NSString *aKey, BOOL aValue, BOOL *stop) {
1574 XCTAssertLessThan(idx, 3U);
1575 seenKeys[idx] = aKey;
1576 seenValues[idx] = aValue;
1577 XCTAssertNotEqual(stop, NULL);
1578 ++idx;
1579 }];
1580 for (int i = 0; i < 3; ++i) {
1581 BOOL foundKey = NO;
1582 for (int j = 0; (j < 3) && !foundKey; ++j) {
1583 if ([kKeys[i] isEqual:seenKeys[j]]) {
1584 foundKey = YES;
1585 XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
1586 }
1587 }
1588 XCTAssertTrue(foundKey, @"i = %d", i);
1589 }
1590 free(seenKeys);
1591 free(seenValues);
1592
1593 // Stopping the enumeration.
1594 idx = 0;
1595 [dict enumerateKeysAndBoolsUsingBlock:^(NSString *aKey, BOOL aValue, BOOL *stop) {
1596 #pragma unused(aKey, aValue)
1597 if (idx == 1) *stop = YES;
1598 XCTAssertNotEqual(idx, 2U);
1599 ++idx;
1600 }];
1601 [dict release];
1602}
1603
1604- (void)testEquality {
1605 const NSString *kKeys1[] = { @"foo", @"bar", @"baz", @"mumble" };
1606 const NSString *kKeys2[] = { @"bar", @"foo", @"mumble" };
1607 const BOOL kValues1[] = { YES, YES, NO };
1608 const BOOL kValues2[] = { YES, NO, NO };
1609 const BOOL kValues3[] = { YES, YES, NO, NO };
1610 GPBStringBoolDictionary *dict1 =
1611 [[GPBStringBoolDictionary alloc] initWithBools:kValues1
1612 forKeys:kKeys1
1613 count:GPBARRAYSIZE(kValues1)];
1614 XCTAssertNotNil(dict1);
1615 GPBStringBoolDictionary *dict1prime =
1616 [[GPBStringBoolDictionary alloc] initWithBools:kValues1
1617 forKeys:kKeys1
1618 count:GPBARRAYSIZE(kValues1)];
1619 XCTAssertNotNil(dict1prime);
1620 GPBStringBoolDictionary *dict2 =
1621 [[GPBStringBoolDictionary alloc] initWithBools:kValues2
1622 forKeys:kKeys1
1623 count:GPBARRAYSIZE(kValues2)];
1624 XCTAssertNotNil(dict2);
1625 GPBStringBoolDictionary *dict3 =
1626 [[GPBStringBoolDictionary alloc] initWithBools:kValues1
1627 forKeys:kKeys2
1628 count:GPBARRAYSIZE(kValues1)];
1629 XCTAssertNotNil(dict3);
1630 GPBStringBoolDictionary *dict4 =
1631 [[GPBStringBoolDictionary alloc] initWithBools:kValues3
1632 forKeys:kKeys1
1633 count:GPBARRAYSIZE(kValues3)];
1634 XCTAssertNotNil(dict4);
1635
1636 // 1/1Prime should be different objects, but equal.
1637 XCTAssertNotEqual(dict1, dict1prime);
1638 XCTAssertEqualObjects(dict1, dict1prime);
1639 // Equal, so they must have same hash.
1640 XCTAssertEqual([dict1 hash], [dict1prime hash]);
1641
1642 // 2 is same keys, different values; not equal.
1643 XCTAssertNotEqualObjects(dict1, dict2);
1644
1645 // 3 is different keys, same values; not equal.
1646 XCTAssertNotEqualObjects(dict1, dict3);
1647
1648 // 4 extra pair; not equal
1649 XCTAssertNotEqualObjects(dict1, dict4);
1650
1651 [dict1 release];
1652 [dict1prime release];
1653 [dict2 release];
1654 [dict3 release];
1655 [dict4 release];
1656}
1657
1658- (void)testCopy {
1659 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
1660 const BOOL kValues[] = { YES, YES, NO, NO };
1661 GPBStringBoolDictionary *dict =
1662 [[GPBStringBoolDictionary alloc] initWithBools:kValues
1663 forKeys:kKeys
1664 count:GPBARRAYSIZE(kValues)];
1665 XCTAssertNotNil(dict);
1666
1667 GPBStringBoolDictionary *dict2 = [dict copy];
1668 XCTAssertNotNil(dict2);
1669
1670 // Should be new object but equal.
1671 XCTAssertNotEqual(dict, dict2);
1672 XCTAssertEqualObjects(dict, dict2);
1673 XCTAssertTrue([dict2 isKindOfClass:[GPBStringBoolDictionary class]]);
1674
1675 [dict2 release];
1676 [dict release];
1677}
1678
1679- (void)testDictionaryFromDictionary {
1680 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
1681 const BOOL kValues[] = { YES, YES, NO, NO };
1682 GPBStringBoolDictionary *dict =
1683 [[GPBStringBoolDictionary alloc] initWithBools:kValues
1684 forKeys:kKeys
1685 count:GPBARRAYSIZE(kValues)];
1686 XCTAssertNotNil(dict);
1687
1688 GPBStringBoolDictionary *dict2 =
1689 [GPBStringBoolDictionary dictionaryWithDictionary:dict];
1690 XCTAssertNotNil(dict2);
1691
1692 // Should be new pointer, but equal objects.
1693 XCTAssertNotEqual(dict, dict2);
1694 XCTAssertEqualObjects(dict, dict2);
1695 [dict release];
1696}
1697
1698- (void)testAdds {
1699 GPBStringBoolDictionary *dict = [GPBStringBoolDictionary dictionary];
1700 XCTAssertNotNil(dict);
1701
1702 XCTAssertEqual(dict.count, 0U);
1703 [dict setBool:YES forKey:@"foo"];
1704 XCTAssertEqual(dict.count, 1U);
1705
1706 const NSString *kKeys[] = { @"bar", @"baz", @"mumble" };
1707 const BOOL kValues[] = { YES, NO, NO };
1708 GPBStringBoolDictionary *dict2 =
1709 [[GPBStringBoolDictionary alloc] initWithBools:kValues
1710 forKeys:kKeys
1711 count:GPBARRAYSIZE(kValues)];
1712 XCTAssertNotNil(dict2);
1713 [dict addEntriesFromDictionary:dict2];
1714 XCTAssertEqual(dict.count, 4U);
1715
1716 BOOL value;
1717 XCTAssertTrue([dict getBool:NULL forKey:@"foo"]);
1718 XCTAssertTrue([dict getBool:&value forKey:@"foo"]);
1719 XCTAssertEqual(value, YES);
1720 XCTAssertTrue([dict getBool:NULL forKey:@"bar"]);
1721 XCTAssertTrue([dict getBool:&value forKey:@"bar"]);
1722 XCTAssertEqual(value, YES);
1723 XCTAssertTrue([dict getBool:NULL forKey:@"baz"]);
1724 XCTAssertTrue([dict getBool:&value forKey:@"baz"]);
1725 XCTAssertEqual(value, NO);
1726 XCTAssertTrue([dict getBool:NULL forKey:@"mumble"]);
1727 XCTAssertTrue([dict getBool:&value forKey:@"mumble"]);
1728 XCTAssertEqual(value, NO);
1729 [dict2 release];
1730}
1731
1732- (void)testRemove {
1733 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
1734 const BOOL kValues[] = { YES, YES, NO, NO };
1735 GPBStringBoolDictionary *dict =
1736 [[GPBStringBoolDictionary alloc] initWithBools:kValues
1737 forKeys:kKeys
1738 count:GPBARRAYSIZE(kValues)];
1739 XCTAssertNotNil(dict);
1740 XCTAssertEqual(dict.count, 4U);
1741
1742 [dict removeBoolForKey:@"bar"];
1743 XCTAssertEqual(dict.count, 3U);
1744 BOOL value;
1745 XCTAssertTrue([dict getBool:NULL forKey:@"foo"]);
1746 XCTAssertTrue([dict getBool:&value forKey:@"foo"]);
1747 XCTAssertEqual(value, YES);
1748 XCTAssertFalse([dict getBool:NULL forKey:@"bar"]);
1749 XCTAssertTrue([dict getBool:NULL forKey:@"baz"]);
1750 XCTAssertTrue([dict getBool:&value forKey:@"baz"]);
1751 XCTAssertEqual(value, NO);
1752 XCTAssertTrue([dict getBool:NULL forKey:@"mumble"]);
1753 XCTAssertTrue([dict getBool:&value forKey:@"mumble"]);
1754 XCTAssertEqual(value, NO);
1755
1756 // Remove again does nothing.
1757 [dict removeBoolForKey:@"bar"];
1758 XCTAssertEqual(dict.count, 3U);
1759 XCTAssertTrue([dict getBool:NULL forKey:@"foo"]);
1760 XCTAssertTrue([dict getBool:&value forKey:@"foo"]);
1761 XCTAssertEqual(value, YES);
1762 XCTAssertFalse([dict getBool:NULL forKey:@"bar"]);
1763 XCTAssertTrue([dict getBool:NULL forKey:@"baz"]);
1764 XCTAssertTrue([dict getBool:&value forKey:@"baz"]);
1765 XCTAssertEqual(value, NO);
1766 XCTAssertTrue([dict getBool:NULL forKey:@"mumble"]);
1767 XCTAssertTrue([dict getBool:&value forKey:@"mumble"]);
1768 XCTAssertEqual(value, NO);
1769
1770 [dict removeBoolForKey:@"mumble"];
1771 XCTAssertEqual(dict.count, 2U);
1772 XCTAssertTrue([dict getBool:NULL forKey:@"foo"]);
1773 XCTAssertTrue([dict getBool:&value forKey:@"foo"]);
1774 XCTAssertEqual(value, YES);
1775 XCTAssertFalse([dict getBool:NULL forKey:@"bar"]);
1776 XCTAssertTrue([dict getBool:NULL forKey:@"baz"]);
1777 XCTAssertTrue([dict getBool:&value forKey:@"baz"]);
1778 XCTAssertEqual(value, NO);
1779 XCTAssertFalse([dict getBool:NULL forKey:@"mumble"]);
1780
1781 [dict removeAll];
1782 XCTAssertEqual(dict.count, 0U);
1783 XCTAssertFalse([dict getBool:NULL forKey:@"foo"]);
1784 XCTAssertFalse([dict getBool:NULL forKey:@"bar"]);
1785 XCTAssertFalse([dict getBool:NULL forKey:@"baz"]);
1786 XCTAssertFalse([dict getBool:NULL forKey:@"mumble"]);
1787 [dict release];
1788}
1789
1790- (void)testInplaceMutation {
1791 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
1792 const BOOL kValues[] = { YES, YES, NO, NO };
1793 GPBStringBoolDictionary *dict =
1794 [[GPBStringBoolDictionary alloc] initWithBools:kValues
1795 forKeys:kKeys
1796 count:GPBARRAYSIZE(kValues)];
1797 XCTAssertNotNil(dict);
1798 XCTAssertEqual(dict.count, 4U);
1799 BOOL value;
1800 XCTAssertTrue([dict getBool:NULL forKey:@"foo"]);
1801 XCTAssertTrue([dict getBool:&value forKey:@"foo"]);
1802 XCTAssertEqual(value, YES);
1803 XCTAssertTrue([dict getBool:NULL forKey:@"bar"]);
1804 XCTAssertTrue([dict getBool:&value forKey:@"bar"]);
1805 XCTAssertEqual(value, YES);
1806 XCTAssertTrue([dict getBool:NULL forKey:@"baz"]);
1807 XCTAssertTrue([dict getBool:&value forKey:@"baz"]);
1808 XCTAssertEqual(value, NO);
1809 XCTAssertTrue([dict getBool:NULL forKey:@"mumble"]);
1810 XCTAssertTrue([dict getBool:&value forKey:@"mumble"]);
1811 XCTAssertEqual(value, NO);
1812
1813 [dict setBool:NO forKey:@"foo"];
1814 XCTAssertEqual(dict.count, 4U);
1815 XCTAssertTrue([dict getBool:NULL forKey:@"foo"]);
1816 XCTAssertTrue([dict getBool:&value forKey:@"foo"]);
1817 XCTAssertEqual(value, NO);
1818 XCTAssertTrue([dict getBool:NULL forKey:@"bar"]);
1819 XCTAssertTrue([dict getBool:&value forKey:@"bar"]);
1820 XCTAssertEqual(value, YES);
1821 XCTAssertTrue([dict getBool:NULL forKey:@"baz"]);
1822 XCTAssertTrue([dict getBool:&value forKey:@"baz"]);
1823 XCTAssertEqual(value, NO);
1824 XCTAssertTrue([dict getBool:NULL forKey:@"mumble"]);
1825 XCTAssertTrue([dict getBool:&value forKey:@"mumble"]);
1826 XCTAssertEqual(value, NO);
1827
1828 [dict setBool:YES forKey:@"mumble"];
1829 XCTAssertEqual(dict.count, 4U);
1830 XCTAssertTrue([dict getBool:NULL forKey:@"foo"]);
1831 XCTAssertTrue([dict getBool:&value forKey:@"foo"]);
1832 XCTAssertEqual(value, NO);
1833 XCTAssertTrue([dict getBool:NULL forKey:@"bar"]);
1834 XCTAssertTrue([dict getBool:&value forKey:@"bar"]);
1835 XCTAssertEqual(value, YES);
1836 XCTAssertTrue([dict getBool:NULL forKey:@"baz"]);
1837 XCTAssertTrue([dict getBool:&value forKey:@"baz"]);
1838 XCTAssertEqual(value, NO);
1839 XCTAssertTrue([dict getBool:NULL forKey:@"mumble"]);
1840 XCTAssertTrue([dict getBool:&value forKey:@"mumble"]);
1841 XCTAssertEqual(value, YES);
1842
1843 const NSString *kKeys2[] = { @"bar", @"baz" };
1844 const BOOL kValues2[] = { NO, YES };
1845 GPBStringBoolDictionary *dict2 =
1846 [[GPBStringBoolDictionary alloc] initWithBools:kValues2
1847 forKeys:kKeys2
1848 count:GPBARRAYSIZE(kValues2)];
1849 XCTAssertNotNil(dict2);
1850 [dict addEntriesFromDictionary:dict2];
1851 XCTAssertEqual(dict.count, 4U);
1852 XCTAssertTrue([dict getBool:NULL forKey:@"foo"]);
1853 XCTAssertTrue([dict getBool:&value forKey:@"foo"]);
1854 XCTAssertEqual(value, NO);
1855 XCTAssertTrue([dict getBool:NULL forKey:@"bar"]);
1856 XCTAssertTrue([dict getBool:&value forKey:@"bar"]);
1857 XCTAssertEqual(value, NO);
1858 XCTAssertTrue([dict getBool:NULL forKey:@"baz"]);
1859 XCTAssertTrue([dict getBool:&value forKey:@"baz"]);
1860 XCTAssertEqual(value, YES);
1861 XCTAssertTrue([dict getBool:NULL forKey:@"mumble"]);
1862 XCTAssertTrue([dict getBool:&value forKey:@"mumble"]);
1863 XCTAssertEqual(value, YES);
1864
1865 [dict2 release];
1866 [dict release];
1867}
1868
1869@end
1870
1871#pragma mark - String -> Float
1872
1873@interface GPBStringFloatDictionaryTests : XCTestCase
1874@end
1875
1876@implementation GPBStringFloatDictionaryTests
1877
1878- (void)testEmpty {
1879 GPBStringFloatDictionary *dict = [[GPBStringFloatDictionary alloc] init];
1880 XCTAssertNotNil(dict);
1881 XCTAssertEqual(dict.count, 0U);
1882 XCTAssertFalse([dict getFloat:NULL forKey:@"foo"]);
1883 [dict enumerateKeysAndFloatsUsingBlock:^(NSString *aKey, float aValue, BOOL *stop) {
1884 #pragma unused(aKey, aValue, stop)
1885 XCTFail(@"Shouldn't get here!");
1886 }];
1887 [dict release];
1888}
1889
1890- (void)testOne {
1891 GPBStringFloatDictionary *dict = [GPBStringFloatDictionary dictionaryWithFloat:500.f forKey:@"foo"];
1892 XCTAssertNotNil(dict);
1893 XCTAssertEqual(dict.count, 1U);
1894 float value;
1895 XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]);
1896 XCTAssertTrue([dict getFloat:&value forKey:@"foo"]);
1897 XCTAssertEqual(value, 500.f);
1898 XCTAssertFalse([dict getFloat:NULL forKey:@"bar"]);
1899 [dict enumerateKeysAndFloatsUsingBlock:^(NSString *aKey, float aValue, BOOL *stop) {
1900 XCTAssertEqualObjects(aKey, @"foo");
1901 XCTAssertEqual(aValue, 500.f);
1902 XCTAssertNotEqual(stop, NULL);
1903 }];
1904}
1905
1906- (void)testBasics {
1907 const NSString *kKeys[] = { @"foo", @"bar", @"baz" };
1908 const float kValues[] = { 500.f, 501.f, 502.f };
1909 GPBStringFloatDictionary *dict =
1910 [[GPBStringFloatDictionary alloc] initWithFloats:kValues
1911 forKeys:kKeys
1912 count:GPBARRAYSIZE(kValues)];
1913 XCTAssertNotNil(dict);
1914 XCTAssertEqual(dict.count, 3U);
1915 float value;
1916 XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]);
1917 XCTAssertTrue([dict getFloat:&value forKey:@"foo"]);
1918 XCTAssertEqual(value, 500.f);
1919 XCTAssertTrue([dict getFloat:NULL forKey:@"bar"]);
1920 XCTAssertTrue([dict getFloat:&value forKey:@"bar"]);
1921 XCTAssertEqual(value, 501.f);
1922 XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]);
1923 XCTAssertTrue([dict getFloat:&value forKey:@"baz"]);
1924 XCTAssertEqual(value, 502.f);
1925 XCTAssertFalse([dict getFloat:NULL forKey:@"mumble"]);
1926
1927 __block NSUInteger idx = 0;
1928 NSString **seenKeys = malloc(3 * sizeof(NSString*));
1929 float *seenValues = malloc(3 * sizeof(float));
1930 [dict enumerateKeysAndFloatsUsingBlock:^(NSString *aKey, float aValue, BOOL *stop) {
1931 XCTAssertLessThan(idx, 3U);
1932 seenKeys[idx] = aKey;
1933 seenValues[idx] = aValue;
1934 XCTAssertNotEqual(stop, NULL);
1935 ++idx;
1936 }];
1937 for (int i = 0; i < 3; ++i) {
1938 BOOL foundKey = NO;
1939 for (int j = 0; (j < 3) && !foundKey; ++j) {
1940 if ([kKeys[i] isEqual:seenKeys[j]]) {
1941 foundKey = YES;
1942 XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
1943 }
1944 }
1945 XCTAssertTrue(foundKey, @"i = %d", i);
1946 }
1947 free(seenKeys);
1948 free(seenValues);
1949
1950 // Stopping the enumeration.
1951 idx = 0;
1952 [dict enumerateKeysAndFloatsUsingBlock:^(NSString *aKey, float aValue, BOOL *stop) {
1953 #pragma unused(aKey, aValue)
1954 if (idx == 1) *stop = YES;
1955 XCTAssertNotEqual(idx, 2U);
1956 ++idx;
1957 }];
1958 [dict release];
1959}
1960
1961- (void)testEquality {
1962 const NSString *kKeys1[] = { @"foo", @"bar", @"baz", @"mumble" };
1963 const NSString *kKeys2[] = { @"bar", @"foo", @"mumble" };
1964 const float kValues1[] = { 500.f, 501.f, 502.f };
1965 const float kValues2[] = { 500.f, 503.f, 502.f };
1966 const float kValues3[] = { 500.f, 501.f, 502.f, 503.f };
1967 GPBStringFloatDictionary *dict1 =
1968 [[GPBStringFloatDictionary alloc] initWithFloats:kValues1
1969 forKeys:kKeys1
1970 count:GPBARRAYSIZE(kValues1)];
1971 XCTAssertNotNil(dict1);
1972 GPBStringFloatDictionary *dict1prime =
1973 [[GPBStringFloatDictionary alloc] initWithFloats:kValues1
1974 forKeys:kKeys1
1975 count:GPBARRAYSIZE(kValues1)];
1976 XCTAssertNotNil(dict1prime);
1977 GPBStringFloatDictionary *dict2 =
1978 [[GPBStringFloatDictionary alloc] initWithFloats:kValues2
1979 forKeys:kKeys1
1980 count:GPBARRAYSIZE(kValues2)];
1981 XCTAssertNotNil(dict2);
1982 GPBStringFloatDictionary *dict3 =
1983 [[GPBStringFloatDictionary alloc] initWithFloats:kValues1
1984 forKeys:kKeys2
1985 count:GPBARRAYSIZE(kValues1)];
1986 XCTAssertNotNil(dict3);
1987 GPBStringFloatDictionary *dict4 =
1988 [[GPBStringFloatDictionary alloc] initWithFloats:kValues3
1989 forKeys:kKeys1
1990 count:GPBARRAYSIZE(kValues3)];
1991 XCTAssertNotNil(dict4);
1992
1993 // 1/1Prime should be different objects, but equal.
1994 XCTAssertNotEqual(dict1, dict1prime);
1995 XCTAssertEqualObjects(dict1, dict1prime);
1996 // Equal, so they must have same hash.
1997 XCTAssertEqual([dict1 hash], [dict1prime hash]);
1998
1999 // 2 is same keys, different values; not equal.
2000 XCTAssertNotEqualObjects(dict1, dict2);
2001
2002 // 3 is different keys, same values; not equal.
2003 XCTAssertNotEqualObjects(dict1, dict3);
2004
2005 // 4 extra pair; not equal
2006 XCTAssertNotEqualObjects(dict1, dict4);
2007
2008 [dict1 release];
2009 [dict1prime release];
2010 [dict2 release];
2011 [dict3 release];
2012 [dict4 release];
2013}
2014
2015- (void)testCopy {
2016 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
2017 const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
2018 GPBStringFloatDictionary *dict =
2019 [[GPBStringFloatDictionary alloc] initWithFloats:kValues
2020 forKeys:kKeys
2021 count:GPBARRAYSIZE(kValues)];
2022 XCTAssertNotNil(dict);
2023
2024 GPBStringFloatDictionary *dict2 = [dict copy];
2025 XCTAssertNotNil(dict2);
2026
2027 // Should be new object but equal.
2028 XCTAssertNotEqual(dict, dict2);
2029 XCTAssertEqualObjects(dict, dict2);
2030 XCTAssertTrue([dict2 isKindOfClass:[GPBStringFloatDictionary class]]);
2031
2032 [dict2 release];
2033 [dict release];
2034}
2035
2036- (void)testDictionaryFromDictionary {
2037 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
2038 const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
2039 GPBStringFloatDictionary *dict =
2040 [[GPBStringFloatDictionary alloc] initWithFloats:kValues
2041 forKeys:kKeys
2042 count:GPBARRAYSIZE(kValues)];
2043 XCTAssertNotNil(dict);
2044
2045 GPBStringFloatDictionary *dict2 =
2046 [GPBStringFloatDictionary dictionaryWithDictionary:dict];
2047 XCTAssertNotNil(dict2);
2048
2049 // Should be new pointer, but equal objects.
2050 XCTAssertNotEqual(dict, dict2);
2051 XCTAssertEqualObjects(dict, dict2);
2052 [dict release];
2053}
2054
2055- (void)testAdds {
2056 GPBStringFloatDictionary *dict = [GPBStringFloatDictionary dictionary];
2057 XCTAssertNotNil(dict);
2058
2059 XCTAssertEqual(dict.count, 0U);
2060 [dict setFloat:500.f forKey:@"foo"];
2061 XCTAssertEqual(dict.count, 1U);
2062
2063 const NSString *kKeys[] = { @"bar", @"baz", @"mumble" };
2064 const float kValues[] = { 501.f, 502.f, 503.f };
2065 GPBStringFloatDictionary *dict2 =
2066 [[GPBStringFloatDictionary alloc] initWithFloats:kValues
2067 forKeys:kKeys
2068 count:GPBARRAYSIZE(kValues)];
2069 XCTAssertNotNil(dict2);
2070 [dict addEntriesFromDictionary:dict2];
2071 XCTAssertEqual(dict.count, 4U);
2072
2073 float value;
2074 XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]);
2075 XCTAssertTrue([dict getFloat:&value forKey:@"foo"]);
2076 XCTAssertEqual(value, 500.f);
2077 XCTAssertTrue([dict getFloat:NULL forKey:@"bar"]);
2078 XCTAssertTrue([dict getFloat:&value forKey:@"bar"]);
2079 XCTAssertEqual(value, 501.f);
2080 XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]);
2081 XCTAssertTrue([dict getFloat:&value forKey:@"baz"]);
2082 XCTAssertEqual(value, 502.f);
2083 XCTAssertTrue([dict getFloat:NULL forKey:@"mumble"]);
2084 XCTAssertTrue([dict getFloat:&value forKey:@"mumble"]);
2085 XCTAssertEqual(value, 503.f);
2086 [dict2 release];
2087}
2088
2089- (void)testRemove {
2090 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
2091 const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
2092 GPBStringFloatDictionary *dict =
2093 [[GPBStringFloatDictionary alloc] initWithFloats:kValues
2094 forKeys:kKeys
2095 count:GPBARRAYSIZE(kValues)];
2096 XCTAssertNotNil(dict);
2097 XCTAssertEqual(dict.count, 4U);
2098
2099 [dict removeFloatForKey:@"bar"];
2100 XCTAssertEqual(dict.count, 3U);
2101 float value;
2102 XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]);
2103 XCTAssertTrue([dict getFloat:&value forKey:@"foo"]);
2104 XCTAssertEqual(value, 500.f);
2105 XCTAssertFalse([dict getFloat:NULL forKey:@"bar"]);
2106 XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]);
2107 XCTAssertTrue([dict getFloat:&value forKey:@"baz"]);
2108 XCTAssertEqual(value, 502.f);
2109 XCTAssertTrue([dict getFloat:NULL forKey:@"mumble"]);
2110 XCTAssertTrue([dict getFloat:&value forKey:@"mumble"]);
2111 XCTAssertEqual(value, 503.f);
2112
2113 // Remove again does nothing.
2114 [dict removeFloatForKey:@"bar"];
2115 XCTAssertEqual(dict.count, 3U);
2116 XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]);
2117 XCTAssertTrue([dict getFloat:&value forKey:@"foo"]);
2118 XCTAssertEqual(value, 500.f);
2119 XCTAssertFalse([dict getFloat:NULL forKey:@"bar"]);
2120 XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]);
2121 XCTAssertTrue([dict getFloat:&value forKey:@"baz"]);
2122 XCTAssertEqual(value, 502.f);
2123 XCTAssertTrue([dict getFloat:NULL forKey:@"mumble"]);
2124 XCTAssertTrue([dict getFloat:&value forKey:@"mumble"]);
2125 XCTAssertEqual(value, 503.f);
2126
2127 [dict removeFloatForKey:@"mumble"];
2128 XCTAssertEqual(dict.count, 2U);
2129 XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]);
2130 XCTAssertTrue([dict getFloat:&value forKey:@"foo"]);
2131 XCTAssertEqual(value, 500.f);
2132 XCTAssertFalse([dict getFloat:NULL forKey:@"bar"]);
2133 XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]);
2134 XCTAssertTrue([dict getFloat:&value forKey:@"baz"]);
2135 XCTAssertEqual(value, 502.f);
2136 XCTAssertFalse([dict getFloat:NULL forKey:@"mumble"]);
2137
2138 [dict removeAll];
2139 XCTAssertEqual(dict.count, 0U);
2140 XCTAssertFalse([dict getFloat:NULL forKey:@"foo"]);
2141 XCTAssertFalse([dict getFloat:NULL forKey:@"bar"]);
2142 XCTAssertFalse([dict getFloat:NULL forKey:@"baz"]);
2143 XCTAssertFalse([dict getFloat:NULL forKey:@"mumble"]);
2144 [dict release];
2145}
2146
2147- (void)testInplaceMutation {
2148 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
2149 const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
2150 GPBStringFloatDictionary *dict =
2151 [[GPBStringFloatDictionary alloc] initWithFloats:kValues
2152 forKeys:kKeys
2153 count:GPBARRAYSIZE(kValues)];
2154 XCTAssertNotNil(dict);
2155 XCTAssertEqual(dict.count, 4U);
2156 float value;
2157 XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]);
2158 XCTAssertTrue([dict getFloat:&value forKey:@"foo"]);
2159 XCTAssertEqual(value, 500.f);
2160 XCTAssertTrue([dict getFloat:NULL forKey:@"bar"]);
2161 XCTAssertTrue([dict getFloat:&value forKey:@"bar"]);
2162 XCTAssertEqual(value, 501.f);
2163 XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]);
2164 XCTAssertTrue([dict getFloat:&value forKey:@"baz"]);
2165 XCTAssertEqual(value, 502.f);
2166 XCTAssertTrue([dict getFloat:NULL forKey:@"mumble"]);
2167 XCTAssertTrue([dict getFloat:&value forKey:@"mumble"]);
2168 XCTAssertEqual(value, 503.f);
2169
2170 [dict setFloat:503.f forKey:@"foo"];
2171 XCTAssertEqual(dict.count, 4U);
2172 XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]);
2173 XCTAssertTrue([dict getFloat:&value forKey:@"foo"]);
2174 XCTAssertEqual(value, 503.f);
2175 XCTAssertTrue([dict getFloat:NULL forKey:@"bar"]);
2176 XCTAssertTrue([dict getFloat:&value forKey:@"bar"]);
2177 XCTAssertEqual(value, 501.f);
2178 XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]);
2179 XCTAssertTrue([dict getFloat:&value forKey:@"baz"]);
2180 XCTAssertEqual(value, 502.f);
2181 XCTAssertTrue([dict getFloat:NULL forKey:@"mumble"]);
2182 XCTAssertTrue([dict getFloat:&value forKey:@"mumble"]);
2183 XCTAssertEqual(value, 503.f);
2184
2185 [dict setFloat:501.f forKey:@"mumble"];
2186 XCTAssertEqual(dict.count, 4U);
2187 XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]);
2188 XCTAssertTrue([dict getFloat:&value forKey:@"foo"]);
2189 XCTAssertEqual(value, 503.f);
2190 XCTAssertTrue([dict getFloat:NULL forKey:@"bar"]);
2191 XCTAssertTrue([dict getFloat:&value forKey:@"bar"]);
2192 XCTAssertEqual(value, 501.f);
2193 XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]);
2194 XCTAssertTrue([dict getFloat:&value forKey:@"baz"]);
2195 XCTAssertEqual(value, 502.f);
2196 XCTAssertTrue([dict getFloat:NULL forKey:@"mumble"]);
2197 XCTAssertTrue([dict getFloat:&value forKey:@"mumble"]);
2198 XCTAssertEqual(value, 501.f);
2199
2200 const NSString *kKeys2[] = { @"bar", @"baz" };
2201 const float kValues2[] = { 502.f, 500.f };
2202 GPBStringFloatDictionary *dict2 =
2203 [[GPBStringFloatDictionary alloc] initWithFloats:kValues2
2204 forKeys:kKeys2
2205 count:GPBARRAYSIZE(kValues2)];
2206 XCTAssertNotNil(dict2);
2207 [dict addEntriesFromDictionary:dict2];
2208 XCTAssertEqual(dict.count, 4U);
2209 XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]);
2210 XCTAssertTrue([dict getFloat:&value forKey:@"foo"]);
2211 XCTAssertEqual(value, 503.f);
2212 XCTAssertTrue([dict getFloat:NULL forKey:@"bar"]);
2213 XCTAssertTrue([dict getFloat:&value forKey:@"bar"]);
2214 XCTAssertEqual(value, 502.f);
2215 XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]);
2216 XCTAssertTrue([dict getFloat:&value forKey:@"baz"]);
2217 XCTAssertEqual(value, 500.f);
2218 XCTAssertTrue([dict getFloat:NULL forKey:@"mumble"]);
2219 XCTAssertTrue([dict getFloat:&value forKey:@"mumble"]);
2220 XCTAssertEqual(value, 501.f);
2221
2222 [dict2 release];
2223 [dict release];
2224}
2225
2226@end
2227
2228#pragma mark - String -> Double
2229
2230@interface GPBStringDoubleDictionaryTests : XCTestCase
2231@end
2232
2233@implementation GPBStringDoubleDictionaryTests
2234
2235- (void)testEmpty {
2236 GPBStringDoubleDictionary *dict = [[GPBStringDoubleDictionary alloc] init];
2237 XCTAssertNotNil(dict);
2238 XCTAssertEqual(dict.count, 0U);
2239 XCTAssertFalse([dict getDouble:NULL forKey:@"foo"]);
2240 [dict enumerateKeysAndDoublesUsingBlock:^(NSString *aKey, double aValue, BOOL *stop) {
2241 #pragma unused(aKey, aValue, stop)
2242 XCTFail(@"Shouldn't get here!");
2243 }];
2244 [dict release];
2245}
2246
2247- (void)testOne {
2248 GPBStringDoubleDictionary *dict = [GPBStringDoubleDictionary dictionaryWithDouble:600. forKey:@"foo"];
2249 XCTAssertNotNil(dict);
2250 XCTAssertEqual(dict.count, 1U);
2251 double value;
2252 XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]);
2253 XCTAssertTrue([dict getDouble:&value forKey:@"foo"]);
2254 XCTAssertEqual(value, 600.);
2255 XCTAssertFalse([dict getDouble:NULL forKey:@"bar"]);
2256 [dict enumerateKeysAndDoublesUsingBlock:^(NSString *aKey, double aValue, BOOL *stop) {
2257 XCTAssertEqualObjects(aKey, @"foo");
2258 XCTAssertEqual(aValue, 600.);
2259 XCTAssertNotEqual(stop, NULL);
2260 }];
2261}
2262
2263- (void)testBasics {
2264 const NSString *kKeys[] = { @"foo", @"bar", @"baz" };
2265 const double kValues[] = { 600., 601., 602. };
2266 GPBStringDoubleDictionary *dict =
2267 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues
2268 forKeys:kKeys
2269 count:GPBARRAYSIZE(kValues)];
2270 XCTAssertNotNil(dict);
2271 XCTAssertEqual(dict.count, 3U);
2272 double value;
2273 XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]);
2274 XCTAssertTrue([dict getDouble:&value forKey:@"foo"]);
2275 XCTAssertEqual(value, 600.);
2276 XCTAssertTrue([dict getDouble:NULL forKey:@"bar"]);
2277 XCTAssertTrue([dict getDouble:&value forKey:@"bar"]);
2278 XCTAssertEqual(value, 601.);
2279 XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]);
2280 XCTAssertTrue([dict getDouble:&value forKey:@"baz"]);
2281 XCTAssertEqual(value, 602.);
2282 XCTAssertFalse([dict getDouble:NULL forKey:@"mumble"]);
2283
2284 __block NSUInteger idx = 0;
2285 NSString **seenKeys = malloc(3 * sizeof(NSString*));
2286 double *seenValues = malloc(3 * sizeof(double));
2287 [dict enumerateKeysAndDoublesUsingBlock:^(NSString *aKey, double aValue, BOOL *stop) {
2288 XCTAssertLessThan(idx, 3U);
2289 seenKeys[idx] = aKey;
2290 seenValues[idx] = aValue;
2291 XCTAssertNotEqual(stop, NULL);
2292 ++idx;
2293 }];
2294 for (int i = 0; i < 3; ++i) {
2295 BOOL foundKey = NO;
2296 for (int j = 0; (j < 3) && !foundKey; ++j) {
2297 if ([kKeys[i] isEqual:seenKeys[j]]) {
2298 foundKey = YES;
2299 XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
2300 }
2301 }
2302 XCTAssertTrue(foundKey, @"i = %d", i);
2303 }
2304 free(seenKeys);
2305 free(seenValues);
2306
2307 // Stopping the enumeration.
2308 idx = 0;
2309 [dict enumerateKeysAndDoublesUsingBlock:^(NSString *aKey, double aValue, BOOL *stop) {
2310 #pragma unused(aKey, aValue)
2311 if (idx == 1) *stop = YES;
2312 XCTAssertNotEqual(idx, 2U);
2313 ++idx;
2314 }];
2315 [dict release];
2316}
2317
2318- (void)testEquality {
2319 const NSString *kKeys1[] = { @"foo", @"bar", @"baz", @"mumble" };
2320 const NSString *kKeys2[] = { @"bar", @"foo", @"mumble" };
2321 const double kValues1[] = { 600., 601., 602. };
2322 const double kValues2[] = { 600., 603., 602. };
2323 const double kValues3[] = { 600., 601., 602., 603. };
2324 GPBStringDoubleDictionary *dict1 =
2325 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues1
2326 forKeys:kKeys1
2327 count:GPBARRAYSIZE(kValues1)];
2328 XCTAssertNotNil(dict1);
2329 GPBStringDoubleDictionary *dict1prime =
2330 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues1
2331 forKeys:kKeys1
2332 count:GPBARRAYSIZE(kValues1)];
2333 XCTAssertNotNil(dict1prime);
2334 GPBStringDoubleDictionary *dict2 =
2335 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues2
2336 forKeys:kKeys1
2337 count:GPBARRAYSIZE(kValues2)];
2338 XCTAssertNotNil(dict2);
2339 GPBStringDoubleDictionary *dict3 =
2340 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues1
2341 forKeys:kKeys2
2342 count:GPBARRAYSIZE(kValues1)];
2343 XCTAssertNotNil(dict3);
2344 GPBStringDoubleDictionary *dict4 =
2345 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues3
2346 forKeys:kKeys1
2347 count:GPBARRAYSIZE(kValues3)];
2348 XCTAssertNotNil(dict4);
2349
2350 // 1/1Prime should be different objects, but equal.
2351 XCTAssertNotEqual(dict1, dict1prime);
2352 XCTAssertEqualObjects(dict1, dict1prime);
2353 // Equal, so they must have same hash.
2354 XCTAssertEqual([dict1 hash], [dict1prime hash]);
2355
2356 // 2 is same keys, different values; not equal.
2357 XCTAssertNotEqualObjects(dict1, dict2);
2358
2359 // 3 is different keys, same values; not equal.
2360 XCTAssertNotEqualObjects(dict1, dict3);
2361
2362 // 4 extra pair; not equal
2363 XCTAssertNotEqualObjects(dict1, dict4);
2364
2365 [dict1 release];
2366 [dict1prime release];
2367 [dict2 release];
2368 [dict3 release];
2369 [dict4 release];
2370}
2371
2372- (void)testCopy {
2373 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
2374 const double kValues[] = { 600., 601., 602., 603. };
2375 GPBStringDoubleDictionary *dict =
2376 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues
2377 forKeys:kKeys
2378 count:GPBARRAYSIZE(kValues)];
2379 XCTAssertNotNil(dict);
2380
2381 GPBStringDoubleDictionary *dict2 = [dict copy];
2382 XCTAssertNotNil(dict2);
2383
2384 // Should be new object but equal.
2385 XCTAssertNotEqual(dict, dict2);
2386 XCTAssertEqualObjects(dict, dict2);
2387 XCTAssertTrue([dict2 isKindOfClass:[GPBStringDoubleDictionary class]]);
2388
2389 [dict2 release];
2390 [dict release];
2391}
2392
2393- (void)testDictionaryFromDictionary {
2394 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
2395 const double kValues[] = { 600., 601., 602., 603. };
2396 GPBStringDoubleDictionary *dict =
2397 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues
2398 forKeys:kKeys
2399 count:GPBARRAYSIZE(kValues)];
2400 XCTAssertNotNil(dict);
2401
2402 GPBStringDoubleDictionary *dict2 =
2403 [GPBStringDoubleDictionary dictionaryWithDictionary:dict];
2404 XCTAssertNotNil(dict2);
2405
2406 // Should be new pointer, but equal objects.
2407 XCTAssertNotEqual(dict, dict2);
2408 XCTAssertEqualObjects(dict, dict2);
2409 [dict release];
2410}
2411
2412- (void)testAdds {
2413 GPBStringDoubleDictionary *dict = [GPBStringDoubleDictionary dictionary];
2414 XCTAssertNotNil(dict);
2415
2416 XCTAssertEqual(dict.count, 0U);
2417 [dict setDouble:600. forKey:@"foo"];
2418 XCTAssertEqual(dict.count, 1U);
2419
2420 const NSString *kKeys[] = { @"bar", @"baz", @"mumble" };
2421 const double kValues[] = { 601., 602., 603. };
2422 GPBStringDoubleDictionary *dict2 =
2423 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues
2424 forKeys:kKeys
2425 count:GPBARRAYSIZE(kValues)];
2426 XCTAssertNotNil(dict2);
2427 [dict addEntriesFromDictionary:dict2];
2428 XCTAssertEqual(dict.count, 4U);
2429
2430 double value;
2431 XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]);
2432 XCTAssertTrue([dict getDouble:&value forKey:@"foo"]);
2433 XCTAssertEqual(value, 600.);
2434 XCTAssertTrue([dict getDouble:NULL forKey:@"bar"]);
2435 XCTAssertTrue([dict getDouble:&value forKey:@"bar"]);
2436 XCTAssertEqual(value, 601.);
2437 XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]);
2438 XCTAssertTrue([dict getDouble:&value forKey:@"baz"]);
2439 XCTAssertEqual(value, 602.);
2440 XCTAssertTrue([dict getDouble:NULL forKey:@"mumble"]);
2441 XCTAssertTrue([dict getDouble:&value forKey:@"mumble"]);
2442 XCTAssertEqual(value, 603.);
2443 [dict2 release];
2444}
2445
2446- (void)testRemove {
2447 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
2448 const double kValues[] = { 600., 601., 602., 603. };
2449 GPBStringDoubleDictionary *dict =
2450 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues
2451 forKeys:kKeys
2452 count:GPBARRAYSIZE(kValues)];
2453 XCTAssertNotNil(dict);
2454 XCTAssertEqual(dict.count, 4U);
2455
2456 [dict removeDoubleForKey:@"bar"];
2457 XCTAssertEqual(dict.count, 3U);
2458 double value;
2459 XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]);
2460 XCTAssertTrue([dict getDouble:&value forKey:@"foo"]);
2461 XCTAssertEqual(value, 600.);
2462 XCTAssertFalse([dict getDouble:NULL forKey:@"bar"]);
2463 XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]);
2464 XCTAssertTrue([dict getDouble:&value forKey:@"baz"]);
2465 XCTAssertEqual(value, 602.);
2466 XCTAssertTrue([dict getDouble:NULL forKey:@"mumble"]);
2467 XCTAssertTrue([dict getDouble:&value forKey:@"mumble"]);
2468 XCTAssertEqual(value, 603.);
2469
2470 // Remove again does nothing.
2471 [dict removeDoubleForKey:@"bar"];
2472 XCTAssertEqual(dict.count, 3U);
2473 XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]);
2474 XCTAssertTrue([dict getDouble:&value forKey:@"foo"]);
2475 XCTAssertEqual(value, 600.);
2476 XCTAssertFalse([dict getDouble:NULL forKey:@"bar"]);
2477 XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]);
2478 XCTAssertTrue([dict getDouble:&value forKey:@"baz"]);
2479 XCTAssertEqual(value, 602.);
2480 XCTAssertTrue([dict getDouble:NULL forKey:@"mumble"]);
2481 XCTAssertTrue([dict getDouble:&value forKey:@"mumble"]);
2482 XCTAssertEqual(value, 603.);
2483
2484 [dict removeDoubleForKey:@"mumble"];
2485 XCTAssertEqual(dict.count, 2U);
2486 XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]);
2487 XCTAssertTrue([dict getDouble:&value forKey:@"foo"]);
2488 XCTAssertEqual(value, 600.);
2489 XCTAssertFalse([dict getDouble:NULL forKey:@"bar"]);
2490 XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]);
2491 XCTAssertTrue([dict getDouble:&value forKey:@"baz"]);
2492 XCTAssertEqual(value, 602.);
2493 XCTAssertFalse([dict getDouble:NULL forKey:@"mumble"]);
2494
2495 [dict removeAll];
2496 XCTAssertEqual(dict.count, 0U);
2497 XCTAssertFalse([dict getDouble:NULL forKey:@"foo"]);
2498 XCTAssertFalse([dict getDouble:NULL forKey:@"bar"]);
2499 XCTAssertFalse([dict getDouble:NULL forKey:@"baz"]);
2500 XCTAssertFalse([dict getDouble:NULL forKey:@"mumble"]);
2501 [dict release];
2502}
2503
2504- (void)testInplaceMutation {
2505 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
2506 const double kValues[] = { 600., 601., 602., 603. };
2507 GPBStringDoubleDictionary *dict =
2508 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues
2509 forKeys:kKeys
2510 count:GPBARRAYSIZE(kValues)];
2511 XCTAssertNotNil(dict);
2512 XCTAssertEqual(dict.count, 4U);
2513 double value;
2514 XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]);
2515 XCTAssertTrue([dict getDouble:&value forKey:@"foo"]);
2516 XCTAssertEqual(value, 600.);
2517 XCTAssertTrue([dict getDouble:NULL forKey:@"bar"]);
2518 XCTAssertTrue([dict getDouble:&value forKey:@"bar"]);
2519 XCTAssertEqual(value, 601.);
2520 XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]);
2521 XCTAssertTrue([dict getDouble:&value forKey:@"baz"]);
2522 XCTAssertEqual(value, 602.);
2523 XCTAssertTrue([dict getDouble:NULL forKey:@"mumble"]);
2524 XCTAssertTrue([dict getDouble:&value forKey:@"mumble"]);
2525 XCTAssertEqual(value, 603.);
2526
2527 [dict setDouble:603. forKey:@"foo"];
2528 XCTAssertEqual(dict.count, 4U);
2529 XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]);
2530 XCTAssertTrue([dict getDouble:&value forKey:@"foo"]);
2531 XCTAssertEqual(value, 603.);
2532 XCTAssertTrue([dict getDouble:NULL forKey:@"bar"]);
2533 XCTAssertTrue([dict getDouble:&value forKey:@"bar"]);
2534 XCTAssertEqual(value, 601.);
2535 XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]);
2536 XCTAssertTrue([dict getDouble:&value forKey:@"baz"]);
2537 XCTAssertEqual(value, 602.);
2538 XCTAssertTrue([dict getDouble:NULL forKey:@"mumble"]);
2539 XCTAssertTrue([dict getDouble:&value forKey:@"mumble"]);
2540 XCTAssertEqual(value, 603.);
2541
2542 [dict setDouble:601. forKey:@"mumble"];
2543 XCTAssertEqual(dict.count, 4U);
2544 XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]);
2545 XCTAssertTrue([dict getDouble:&value forKey:@"foo"]);
2546 XCTAssertEqual(value, 603.);
2547 XCTAssertTrue([dict getDouble:NULL forKey:@"bar"]);
2548 XCTAssertTrue([dict getDouble:&value forKey:@"bar"]);
2549 XCTAssertEqual(value, 601.);
2550 XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]);
2551 XCTAssertTrue([dict getDouble:&value forKey:@"baz"]);
2552 XCTAssertEqual(value, 602.);
2553 XCTAssertTrue([dict getDouble:NULL forKey:@"mumble"]);
2554 XCTAssertTrue([dict getDouble:&value forKey:@"mumble"]);
2555 XCTAssertEqual(value, 601.);
2556
2557 const NSString *kKeys2[] = { @"bar", @"baz" };
2558 const double kValues2[] = { 602., 600. };
2559 GPBStringDoubleDictionary *dict2 =
2560 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues2
2561 forKeys:kKeys2
2562 count:GPBARRAYSIZE(kValues2)];
2563 XCTAssertNotNil(dict2);
2564 [dict addEntriesFromDictionary:dict2];
2565 XCTAssertEqual(dict.count, 4U);
2566 XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]);
2567 XCTAssertTrue([dict getDouble:&value forKey:@"foo"]);
2568 XCTAssertEqual(value, 603.);
2569 XCTAssertTrue([dict getDouble:NULL forKey:@"bar"]);
2570 XCTAssertTrue([dict getDouble:&value forKey:@"bar"]);
2571 XCTAssertEqual(value, 602.);
2572 XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]);
2573 XCTAssertTrue([dict getDouble:&value forKey:@"baz"]);
2574 XCTAssertEqual(value, 600.);
2575 XCTAssertTrue([dict getDouble:NULL forKey:@"mumble"]);
2576 XCTAssertTrue([dict getDouble:&value forKey:@"mumble"]);
2577 XCTAssertEqual(value, 601.);
2578
2579 [dict2 release];
2580 [dict release];
2581}
2582
2583@end
2584
2585#pragma mark - String -> Enum
2586
2587@interface GPBStringEnumDictionaryTests : XCTestCase
2588@end
2589
2590@implementation GPBStringEnumDictionaryTests
2591
2592- (void)testEmpty {
2593 GPBStringEnumDictionary *dict = [[GPBStringEnumDictionary alloc] init];
2594 XCTAssertNotNil(dict);
2595 XCTAssertEqual(dict.count, 0U);
2596 XCTAssertFalse([dict getEnum:NULL forKey:@"foo"]);
2597 [dict enumerateKeysAndEnumsUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
2598 #pragma unused(aKey, aValue, stop)
2599 XCTFail(@"Shouldn't get here!");
2600 }];
2601 [dict release];
2602}
2603
2604- (void)testOne {
2605 GPBStringEnumDictionary *dict = [GPBStringEnumDictionary dictionaryWithEnum:700 forKey:@"foo"];
2606 XCTAssertNotNil(dict);
2607 XCTAssertEqual(dict.count, 1U);
2608 int32_t value;
2609 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
2610 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
2611 XCTAssertEqual(value, 700);
2612 XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]);
2613 [dict enumerateKeysAndEnumsUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
2614 XCTAssertEqualObjects(aKey, @"foo");
2615 XCTAssertEqual(aValue, 700);
2616 XCTAssertNotEqual(stop, NULL);
2617 }];
2618}
2619
2620- (void)testBasics {
2621 const NSString *kKeys[] = { @"foo", @"bar", @"baz" };
2622 const int32_t kValues[] = { 700, 701, 702 };
2623 GPBStringEnumDictionary *dict =
2624 [[GPBStringEnumDictionary alloc] initWithEnums:kValues
2625 forKeys:kKeys
2626 count:GPBARRAYSIZE(kValues)];
2627 XCTAssertNotNil(dict);
2628 XCTAssertEqual(dict.count, 3U);
2629 int32_t value;
2630 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
2631 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
2632 XCTAssertEqual(value, 700);
2633 XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]);
2634 XCTAssertTrue([dict getEnum:&value forKey:@"bar"]);
2635 XCTAssertEqual(value, 701);
2636 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
2637 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
2638 XCTAssertEqual(value, 702);
2639 XCTAssertFalse([dict getEnum:NULL forKey:@"mumble"]);
2640
2641 __block NSUInteger idx = 0;
2642 NSString **seenKeys = malloc(3 * sizeof(NSString*));
2643 int32_t *seenValues = malloc(3 * sizeof(int32_t));
2644 [dict enumerateKeysAndEnumsUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
2645 XCTAssertLessThan(idx, 3U);
2646 seenKeys[idx] = aKey;
2647 seenValues[idx] = aValue;
2648 XCTAssertNotEqual(stop, NULL);
2649 ++idx;
2650 }];
2651 for (int i = 0; i < 3; ++i) {
2652 BOOL foundKey = NO;
2653 for (int j = 0; (j < 3) && !foundKey; ++j) {
2654 if ([kKeys[i] isEqual:seenKeys[j]]) {
2655 foundKey = YES;
2656 XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
2657 }
2658 }
2659 XCTAssertTrue(foundKey, @"i = %d", i);
2660 }
2661 free(seenKeys);
2662 free(seenValues);
2663
2664 // Stopping the enumeration.
2665 idx = 0;
2666 [dict enumerateKeysAndEnumsUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
2667 #pragma unused(aKey, aValue)
2668 if (idx == 1) *stop = YES;
2669 XCTAssertNotEqual(idx, 2U);
2670 ++idx;
2671 }];
2672 [dict release];
2673}
2674
2675- (void)testEquality {
2676 const NSString *kKeys1[] = { @"foo", @"bar", @"baz", @"mumble" };
2677 const NSString *kKeys2[] = { @"bar", @"foo", @"mumble" };
2678 const int32_t kValues1[] = { 700, 701, 702 };
2679 const int32_t kValues2[] = { 700, 703, 702 };
2680 const int32_t kValues3[] = { 700, 701, 702, 703 };
2681 GPBStringEnumDictionary *dict1 =
2682 [[GPBStringEnumDictionary alloc] initWithEnums:kValues1
2683 forKeys:kKeys1
2684 count:GPBARRAYSIZE(kValues1)];
2685 XCTAssertNotNil(dict1);
2686 GPBStringEnumDictionary *dict1prime =
2687 [[GPBStringEnumDictionary alloc] initWithEnums:kValues1
2688 forKeys:kKeys1
2689 count:GPBARRAYSIZE(kValues1)];
2690 XCTAssertNotNil(dict1prime);
2691 GPBStringEnumDictionary *dict2 =
2692 [[GPBStringEnumDictionary alloc] initWithEnums:kValues2
2693 forKeys:kKeys1
2694 count:GPBARRAYSIZE(kValues2)];
2695 XCTAssertNotNil(dict2);
2696 GPBStringEnumDictionary *dict3 =
2697 [[GPBStringEnumDictionary alloc] initWithEnums:kValues1
2698 forKeys:kKeys2
2699 count:GPBARRAYSIZE(kValues1)];
2700 XCTAssertNotNil(dict3);
2701 GPBStringEnumDictionary *dict4 =
2702 [[GPBStringEnumDictionary alloc] initWithEnums:kValues3
2703 forKeys:kKeys1
2704 count:GPBARRAYSIZE(kValues3)];
2705 XCTAssertNotNil(dict4);
2706
2707 // 1/1Prime should be different objects, but equal.
2708 XCTAssertNotEqual(dict1, dict1prime);
2709 XCTAssertEqualObjects(dict1, dict1prime);
2710 // Equal, so they must have same hash.
2711 XCTAssertEqual([dict1 hash], [dict1prime hash]);
2712
2713 // 2 is same keys, different values; not equal.
2714 XCTAssertNotEqualObjects(dict1, dict2);
2715
2716 // 3 is different keys, same values; not equal.
2717 XCTAssertNotEqualObjects(dict1, dict3);
2718
2719 // 4 extra pair; not equal
2720 XCTAssertNotEqualObjects(dict1, dict4);
2721
2722 [dict1 release];
2723 [dict1prime release];
2724 [dict2 release];
2725 [dict3 release];
2726 [dict4 release];
2727}
2728
2729- (void)testCopy {
2730 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
2731 const int32_t kValues[] = { 700, 701, 702, 703 };
2732 GPBStringEnumDictionary *dict =
2733 [[GPBStringEnumDictionary alloc] initWithEnums:kValues
2734 forKeys:kKeys
2735 count:GPBARRAYSIZE(kValues)];
2736 XCTAssertNotNil(dict);
2737
2738 GPBStringEnumDictionary *dict2 = [dict copy];
2739 XCTAssertNotNil(dict2);
2740
2741 // Should be new object but equal.
2742 XCTAssertNotEqual(dict, dict2);
2743 XCTAssertEqualObjects(dict, dict2);
2744 XCTAssertTrue([dict2 isKindOfClass:[GPBStringEnumDictionary class]]);
2745
2746 [dict2 release];
2747 [dict release];
2748}
2749
2750- (void)testDictionaryFromDictionary {
2751 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
2752 const int32_t kValues[] = { 700, 701, 702, 703 };
2753 GPBStringEnumDictionary *dict =
2754 [[GPBStringEnumDictionary alloc] initWithEnums:kValues
2755 forKeys:kKeys
2756 count:GPBARRAYSIZE(kValues)];
2757 XCTAssertNotNil(dict);
2758
2759 GPBStringEnumDictionary *dict2 =
2760 [GPBStringEnumDictionary dictionaryWithDictionary:dict];
2761 XCTAssertNotNil(dict2);
2762
2763 // Should be new pointer, but equal objects.
2764 XCTAssertNotEqual(dict, dict2);
2765 XCTAssertEqualObjects(dict, dict2);
2766 [dict release];
2767}
2768
2769- (void)testAdds {
2770 GPBStringEnumDictionary *dict = [GPBStringEnumDictionary dictionary];
2771 XCTAssertNotNil(dict);
2772
2773 XCTAssertEqual(dict.count, 0U);
2774 [dict setEnum:700 forKey:@"foo"];
2775 XCTAssertEqual(dict.count, 1U);
2776
2777 const NSString *kKeys[] = { @"bar", @"baz", @"mumble" };
2778 const int32_t kValues[] = { 701, 702, 703 };
2779 GPBStringEnumDictionary *dict2 =
2780 [[GPBStringEnumDictionary alloc] initWithEnums:kValues
2781 forKeys:kKeys
2782 count:GPBARRAYSIZE(kValues)];
2783 XCTAssertNotNil(dict2);
2784 [dict addRawEntriesFromDictionary:dict2];
2785 XCTAssertEqual(dict.count, 4U);
2786
2787 int32_t value;
2788 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
2789 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
2790 XCTAssertEqual(value, 700);
2791 XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]);
2792 XCTAssertTrue([dict getEnum:&value forKey:@"bar"]);
2793 XCTAssertEqual(value, 701);
2794 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
2795 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
2796 XCTAssertEqual(value, 702);
2797 XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]);
2798 XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]);
2799 XCTAssertEqual(value, 703);
2800 [dict2 release];
2801}
2802
2803- (void)testRemove {
2804 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
2805 const int32_t kValues[] = { 700, 701, 702, 703 };
2806 GPBStringEnumDictionary *dict =
2807 [[GPBStringEnumDictionary alloc] initWithEnums:kValues
2808 forKeys:kKeys
2809 count:GPBARRAYSIZE(kValues)];
2810 XCTAssertNotNil(dict);
2811 XCTAssertEqual(dict.count, 4U);
2812
2813 [dict removeEnumForKey:@"bar"];
2814 XCTAssertEqual(dict.count, 3U);
2815 int32_t value;
2816 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
2817 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
2818 XCTAssertEqual(value, 700);
2819 XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]);
2820 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
2821 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
2822 XCTAssertEqual(value, 702);
2823 XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]);
2824 XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]);
2825 XCTAssertEqual(value, 703);
2826
2827 // Remove again does nothing.
2828 [dict removeEnumForKey:@"bar"];
2829 XCTAssertEqual(dict.count, 3U);
2830 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
2831 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
2832 XCTAssertEqual(value, 700);
2833 XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]);
2834 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
2835 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
2836 XCTAssertEqual(value, 702);
2837 XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]);
2838 XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]);
2839 XCTAssertEqual(value, 703);
2840
2841 [dict removeEnumForKey:@"mumble"];
2842 XCTAssertEqual(dict.count, 2U);
2843 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
2844 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
2845 XCTAssertEqual(value, 700);
2846 XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]);
2847 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
2848 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
2849 XCTAssertEqual(value, 702);
2850 XCTAssertFalse([dict getEnum:NULL forKey:@"mumble"]);
2851
2852 [dict removeAll];
2853 XCTAssertEqual(dict.count, 0U);
2854 XCTAssertFalse([dict getEnum:NULL forKey:@"foo"]);
2855 XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]);
2856 XCTAssertFalse([dict getEnum:NULL forKey:@"baz"]);
2857 XCTAssertFalse([dict getEnum:NULL forKey:@"mumble"]);
2858 [dict release];
2859}
2860
2861- (void)testInplaceMutation {
2862 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
2863 const int32_t kValues[] = { 700, 701, 702, 703 };
2864 GPBStringEnumDictionary *dict =
2865 [[GPBStringEnumDictionary alloc] initWithEnums:kValues
2866 forKeys:kKeys
2867 count:GPBARRAYSIZE(kValues)];
2868 XCTAssertNotNil(dict);
2869 XCTAssertEqual(dict.count, 4U);
2870 int32_t value;
2871 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
2872 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
2873 XCTAssertEqual(value, 700);
2874 XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]);
2875 XCTAssertTrue([dict getEnum:&value forKey:@"bar"]);
2876 XCTAssertEqual(value, 701);
2877 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
2878 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
2879 XCTAssertEqual(value, 702);
2880 XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]);
2881 XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]);
2882 XCTAssertEqual(value, 703);
2883
2884 [dict setEnum:703 forKey:@"foo"];
2885 XCTAssertEqual(dict.count, 4U);
2886 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
2887 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
2888 XCTAssertEqual(value, 703);
2889 XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]);
2890 XCTAssertTrue([dict getEnum:&value forKey:@"bar"]);
2891 XCTAssertEqual(value, 701);
2892 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
2893 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
2894 XCTAssertEqual(value, 702);
2895 XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]);
2896 XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]);
2897 XCTAssertEqual(value, 703);
2898
2899 [dict setEnum:701 forKey:@"mumble"];
2900 XCTAssertEqual(dict.count, 4U);
2901 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
2902 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
2903 XCTAssertEqual(value, 703);
2904 XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]);
2905 XCTAssertTrue([dict getEnum:&value forKey:@"bar"]);
2906 XCTAssertEqual(value, 701);
2907 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
2908 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
2909 XCTAssertEqual(value, 702);
2910 XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]);
2911 XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]);
2912 XCTAssertEqual(value, 701);
2913
2914 const NSString *kKeys2[] = { @"bar", @"baz" };
2915 const int32_t kValues2[] = { 702, 700 };
2916 GPBStringEnumDictionary *dict2 =
2917 [[GPBStringEnumDictionary alloc] initWithEnums:kValues2
2918 forKeys:kKeys2
2919 count:GPBARRAYSIZE(kValues2)];
2920 XCTAssertNotNil(dict2);
2921 [dict addRawEntriesFromDictionary:dict2];
2922 XCTAssertEqual(dict.count, 4U);
2923 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
2924 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
2925 XCTAssertEqual(value, 703);
2926 XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]);
2927 XCTAssertTrue([dict getEnum:&value forKey:@"bar"]);
2928 XCTAssertEqual(value, 702);
2929 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
2930 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
2931 XCTAssertEqual(value, 700);
2932 XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]);
2933 XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]);
2934 XCTAssertEqual(value, 701);
2935
2936 [dict2 release];
2937 [dict release];
2938}
2939
2940@end
2941
2942#pragma mark - String -> Enum (Unknown Enums)
2943
2944@interface GPBStringEnumDictionaryUnknownEnumTests : XCTestCase
2945@end
2946
2947@implementation GPBStringEnumDictionaryUnknownEnumTests
2948
2949- (void)testRawBasics {
2950 const NSString *kKeys[] = { @"foo", @"bar", @"baz" };
2951 const int32_t kValues[] = { 700, 801, 702 };
2952 GPBStringEnumDictionary *dict =
2953 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
2954 rawValues:kValues
2955 forKeys:kKeys
2956 count:GPBARRAYSIZE(kValues)];
2957 XCTAssertNotNil(dict);
2958 XCTAssertEqual(dict.count, 3U);
2959 XCTAssertTrue(dict.validationFunc == TestingEnum_IsValidValue); // Pointer comparison
2960 int32_t value;
2961 XCTAssertTrue([dict getRawValue:NULL forKey:@"foo"]);
2962 XCTAssertTrue([dict getRawValue:&value forKey:@"foo"]);
2963 XCTAssertEqual(value, 700);
2964 XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]);
2965 XCTAssertTrue([dict getEnum:&value forKey:@"bar"]);
2966 XCTAssertEqual(value, kGPBUnrecognizedEnumeratorValue);
2967 XCTAssertTrue([dict getRawValue:NULL forKey:@"bar"]);
2968 XCTAssertTrue([dict getRawValue:&value forKey:@"bar"]);
2969 XCTAssertEqual(value, 801);
2970 XCTAssertTrue([dict getRawValue:NULL forKey:@"baz"]);
2971 XCTAssertTrue([dict getRawValue:&value forKey:@"baz"]);
2972 XCTAssertEqual(value, 702);
2973 XCTAssertFalse([dict getRawValue:NULL forKey:@"mumble"]);
2974
2975 __block NSUInteger idx = 0;
2976 NSString **seenKeys = malloc(3 * sizeof(NSString*));
2977 int32_t *seenValues = malloc(3 * sizeof(int32_t));
2978 [dict enumerateKeysAndEnumsUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
2979 XCTAssertLessThan(idx, 3U);
2980 seenKeys[idx] = aKey;
2981 seenValues[idx] = aValue;
2982 XCTAssertNotEqual(stop, NULL);
2983 ++idx;
2984 }];
2985 for (int i = 0; i < 3; ++i) {
2986 BOOL foundKey = NO;
2987 for (int j = 0; (j < 3) && !foundKey; ++j) {
2988 if ([kKeys[i] isEqual:seenKeys[j]]) {
2989 foundKey = YES;
2990 if (i == 1) {
2991 XCTAssertEqual(kGPBUnrecognizedEnumeratorValue, seenValues[j], @"i = %d, j = %d", i, j);
2992 } else {
2993 XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
2994 }
2995 }
2996 }
2997 XCTAssertTrue(foundKey, @"i = %d", i);
2998 }
2999 idx = 0;
3000 [dict enumerateKeysAndRawValuesUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
3001 XCTAssertLessThan(idx, 3U);
3002 seenKeys[idx] = aKey;
3003 seenValues[idx] = aValue;
3004 XCTAssertNotEqual(stop, NULL);
3005 ++idx;
3006 }];
3007 for (int i = 0; i < 3; ++i) {
3008 BOOL foundKey = NO;
3009 for (int j = 0; (j < 3) && !foundKey; ++j) {
3010 if ([kKeys[i] isEqual:seenKeys[j]]) {
3011 foundKey = YES;
3012 XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
3013 }
3014 }
3015 XCTAssertTrue(foundKey, @"i = %d", i);
3016 }
3017 free(seenKeys);
3018 free(seenValues);
3019
3020 // Stopping the enumeration.
3021 idx = 0;
3022 [dict enumerateKeysAndRawValuesUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
3023 #pragma unused(aKey, aValue)
3024 if (idx == 1) *stop = YES;
3025 XCTAssertNotEqual(idx, 2U);
3026 ++idx;
3027 }];
3028 [dict release];
3029}
3030
3031- (void)testEqualityWithUnknowns {
3032 const NSString *kKeys1[] = { @"foo", @"bar", @"baz", @"mumble" };
3033 const NSString *kKeys2[] = { @"bar", @"foo", @"mumble" };
3034 const int32_t kValues1[] = { 700, 801, 702 }; // Unknown
3035 const int32_t kValues2[] = { 700, 803, 702 }; // Unknown
3036 const int32_t kValues3[] = { 700, 801, 702, 803 }; // Unknowns
3037 GPBStringEnumDictionary *dict1 =
3038 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3039 rawValues:kValues1
3040 forKeys:kKeys1
3041 count:GPBARRAYSIZE(kValues1)];
3042 XCTAssertNotNil(dict1);
3043 GPBStringEnumDictionary *dict1prime =
3044 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3045 rawValues:kValues1
3046 forKeys:kKeys1
3047 count:GPBARRAYSIZE(kValues1)];
3048 XCTAssertNotNil(dict1prime);
3049 GPBStringEnumDictionary *dict2 =
3050 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3051 rawValues:kValues2
3052 forKeys:kKeys1
3053 count:GPBARRAYSIZE(kValues2)];
3054 XCTAssertNotNil(dict2);
3055 GPBStringEnumDictionary *dict3 =
3056 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3057 rawValues:kValues1
3058 forKeys:kKeys2
3059 count:GPBARRAYSIZE(kValues1)];
3060 XCTAssertNotNil(dict3);
3061 GPBStringEnumDictionary *dict4 =
3062 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3063 rawValues:kValues3
3064 forKeys:kKeys1
3065 count:GPBARRAYSIZE(kValues3)];
3066 XCTAssertNotNil(dict4);
3067
3068 // 1/1Prime should be different objects, but equal.
3069 XCTAssertNotEqual(dict1, dict1prime);
3070 XCTAssertEqualObjects(dict1, dict1prime);
3071 // Equal, so they must have same hash.
3072 XCTAssertEqual([dict1 hash], [dict1prime hash]);
3073
3074 // 2 is same keys, different values; not equal.
3075 XCTAssertNotEqualObjects(dict1, dict2);
3076
3077 // 3 is different keys, same values; not equal.
3078 XCTAssertNotEqualObjects(dict1, dict3);
3079
3080 // 4 extra pair; not equal
3081 XCTAssertNotEqualObjects(dict1, dict4);
3082
3083 [dict1 release];
3084 [dict1prime release];
3085 [dict2 release];
3086 [dict3 release];
3087 [dict4 release];
3088}
3089
3090- (void)testCopyWithUnknowns {
3091 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
3092 const int32_t kValues[] = { 700, 801, 702, 803 }; // Unknown
3093 GPBStringEnumDictionary *dict =
3094 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3095 rawValues:kValues
3096 forKeys:kKeys
3097 count:GPBARRAYSIZE(kValues)];
3098 XCTAssertNotNil(dict);
3099
3100 GPBStringEnumDictionary *dict2 = [dict copy];
3101 XCTAssertNotNil(dict2);
3102
3103 // Should be new pointer, but equal objects.
3104 XCTAssertNotEqual(dict, dict2);
3105 XCTAssertEqual(dict.validationFunc, dict2.validationFunc); // Pointer comparison
3106 XCTAssertEqualObjects(dict, dict2);
3107
3108 [dict2 release];
3109 [dict release];
3110}
3111
3112- (void)testDictionaryFromDictionary {
3113 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
3114 const int32_t kValues[] = { 700, 801, 702, 803 }; // Unknowns
3115 GPBStringEnumDictionary *dict =
3116 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3117 rawValues:kValues
3118 forKeys:kKeys
3119 count:GPBARRAYSIZE(kValues)];
3120 XCTAssertNotNil(dict);
3121
3122 GPBStringEnumDictionary *dict2 =
3123 [GPBStringEnumDictionary dictionaryWithDictionary:dict];
3124 XCTAssertNotNil(dict2);
3125
3126 // Should be new pointer, but equal objects.
3127 XCTAssertNotEqual(dict, dict2);
3128 XCTAssertEqualObjects(dict, dict2);
3129 XCTAssertEqual(dict.validationFunc, dict2.validationFunc); // Pointer comparison
3130 [dict release];
3131}
3132
3133- (void)testUnknownAdds {
3134 GPBStringEnumDictionary *dict =
3135 [GPBStringEnumDictionary dictionaryWithValidationFunction:TestingEnum_IsValidValue];
3136 XCTAssertNotNil(dict);
3137
3138 XCTAssertEqual(dict.count, 0U);
3139 XCTAssertThrowsSpecificNamed([dict setEnum:801 forKey:@"bar"], // Unknown
3140 NSException, NSInvalidArgumentException);
3141 XCTAssertEqual(dict.count, 0U);
3142 [dict setRawValue:801 forKey:@"bar"]; // Unknown
3143 XCTAssertEqual(dict.count, 1U);
3144
3145 const NSString *kKeys[] = { @"foo", @"baz", @"mumble" };
3146 const int32_t kValues[] = { 700, 702, 803 }; // Unknown
3147 GPBStringEnumDictionary *dict2 =
3148 [[GPBStringEnumDictionary alloc] initWithEnums:kValues
3149 forKeys:kKeys
3150 count:GPBARRAYSIZE(kValues)];
3151 XCTAssertNotNil(dict2);
3152 [dict addRawEntriesFromDictionary:dict2];
3153 XCTAssertEqual(dict.count, 4U);
3154
3155 int32_t value;
3156 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
3157 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
3158 XCTAssertEqual(value, 700);
3159 XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]);
3160 XCTAssertTrue([dict getEnum:&value forKey:@"bar"]);
3161 XCTAssertEqual(value, kGPBUnrecognizedEnumeratorValue);
3162 XCTAssertTrue([dict getRawValue:NULL forKey:@"bar"]);
3163 XCTAssertTrue([dict getRawValue:&value forKey:@"bar"]);
3164 XCTAssertEqual(value, 801);
3165 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
3166 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
3167 XCTAssertEqual(value, 702);
3168 XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]);
3169 XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]);
3170 XCTAssertEqual(value, kGPBUnrecognizedEnumeratorValue);
3171 XCTAssertTrue([dict getRawValue:NULL forKey:@"mumble"]);
3172 XCTAssertTrue([dict getRawValue:&value forKey:@"mumble"]);
3173 XCTAssertEqual(value, 803);
3174 [dict2 release];
3175}
3176
3177- (void)testUnknownRemove {
3178 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
3179 const int32_t kValues[] = { 700, 801, 702, 803 }; // Unknowns
3180 GPBStringEnumDictionary *dict =
3181 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3182 rawValues:kValues
3183 forKeys:kKeys
3184 count:GPBARRAYSIZE(kValues)];
3185 XCTAssertNotNil(dict);
3186 XCTAssertEqual(dict.count, 4U);
3187
3188 [dict removeEnumForKey:@"bar"];
3189 XCTAssertEqual(dict.count, 3U);
3190 int32_t value;
3191 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
3192 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
3193 XCTAssertEqual(value, 700);
3194 XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]);
3195 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
3196 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
3197 XCTAssertEqual(value, 702);
3198 XCTAssertTrue([dict getRawValue:NULL forKey:@"mumble"]);
3199 XCTAssertTrue([dict getRawValue:&value forKey:@"mumble"]);
3200 XCTAssertEqual(value, 803);
3201
3202 // Remove again does nothing.
3203 [dict removeEnumForKey:@"bar"];
3204 XCTAssertEqual(dict.count, 3U);
3205 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
3206 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
3207 XCTAssertEqual(value, 700);
3208 XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]);
3209 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
3210 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
3211 XCTAssertEqual(value, 702);
3212 XCTAssertTrue([dict getRawValue:NULL forKey:@"mumble"]);
3213 XCTAssertTrue([dict getRawValue:&value forKey:@"mumble"]);
3214 XCTAssertEqual(value, 803);
3215
3216 [dict removeEnumForKey:@"mumble"];
3217 XCTAssertEqual(dict.count, 2U);
3218 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
3219 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
3220 XCTAssertEqual(value, 700);
3221 XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]);
3222 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
3223 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
3224 XCTAssertEqual(value, 702);
3225 XCTAssertFalse([dict getEnum:NULL forKey:@"mumble"]);
3226
3227 [dict removeAll];
3228 XCTAssertEqual(dict.count, 0U);
3229 XCTAssertFalse([dict getEnum:NULL forKey:@"foo"]);
3230 XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]);
3231 XCTAssertFalse([dict getEnum:NULL forKey:@"baz"]);
3232 XCTAssertFalse([dict getEnum:NULL forKey:@"mumble"]);
3233 [dict release];
3234}
3235
3236- (void)testInplaceMutationUnknowns {
3237 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
3238 const int32_t kValues[] = { 700, 801, 702, 803 }; // Unknowns
3239 GPBStringEnumDictionary *dict =
3240 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3241 rawValues:kValues
3242 forKeys:kKeys
3243 count:GPBARRAYSIZE(kValues)];
3244 XCTAssertNotNil(dict);
3245 XCTAssertEqual(dict.count, 4U);
3246 int32_t value;
3247 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
3248 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
3249 XCTAssertEqual(value, 700);
3250 XCTAssertTrue([dict getRawValue:NULL forKey:@"bar"]);
3251 XCTAssertTrue([dict getRawValue:&value forKey:@"bar"]);
3252 XCTAssertEqual(value, 801);
3253 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
3254 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
3255 XCTAssertEqual(value, 702);
3256 XCTAssertTrue([dict getRawValue:NULL forKey:@"mumble"]);
3257 XCTAssertTrue([dict getRawValue:&value forKey:@"mumble"]);
3258 XCTAssertEqual(value, 803);
3259
3260 XCTAssertThrowsSpecificNamed([dict setEnum:803 forKey:@"foo"], // Unknown
3261 NSException, NSInvalidArgumentException);
3262 XCTAssertEqual(dict.count, 4U);
3263 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
3264 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
3265 XCTAssertEqual(value, 700);
3266 XCTAssertTrue([dict getRawValue:NULL forKey:@"bar"]);
3267 XCTAssertTrue([dict getRawValue:&value forKey:@"bar"]);
3268 XCTAssertEqual(value, 801);
3269 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
3270 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
3271 XCTAssertEqual(value, 702);
3272 XCTAssertTrue([dict getRawValue:NULL forKey:@"mumble"]);
3273 XCTAssertTrue([dict getRawValue:&value forKey:@"mumble"]);
3274 XCTAssertEqual(value, 803);
3275
3276 [dict setRawValue:803 forKey:@"foo"]; // Unknown
3277 XCTAssertEqual(dict.count, 4U);
3278 XCTAssertTrue([dict getRawValue:NULL forKey:@"foo"]);
3279 XCTAssertTrue([dict getRawValue:&value forKey:@"foo"]);
3280 XCTAssertEqual(value, 803);
3281 XCTAssertTrue([dict getRawValue:NULL forKey:@"bar"]);
3282 XCTAssertTrue([dict getRawValue:&value forKey:@"bar"]);
3283 XCTAssertEqual(value, 801);
3284 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
3285 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
3286 XCTAssertEqual(value, 702);
3287 XCTAssertTrue([dict getRawValue:NULL forKey:@"mumble"]);
3288 XCTAssertTrue([dict getRawValue:&value forKey:@"mumble"]);
3289 XCTAssertEqual(value, 803);
3290
3291 [dict setRawValue:700 forKey:@"mumble"];
3292 XCTAssertEqual(dict.count, 4U);
3293 XCTAssertTrue([dict getRawValue:NULL forKey:@"foo"]);
3294 XCTAssertTrue([dict getRawValue:&value forKey:@"foo"]);
3295 XCTAssertEqual(value, 803);
3296 XCTAssertTrue([dict getRawValue:NULL forKey:@"bar"]);
3297 XCTAssertTrue([dict getRawValue:&value forKey:@"bar"]);
3298 XCTAssertEqual(value, 801);
3299 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
3300 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
3301 XCTAssertEqual(value, 702);
3302 XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]);
3303 XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]);
3304 XCTAssertEqual(value, 700);
3305
3306 const NSString *kKeys2[] = { @"bar", @"baz" };
3307 const int32_t kValues2[] = { 702, 801 }; // Unknown
3308 GPBStringEnumDictionary *dict2 =
3309 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3310 rawValues:kValues2
3311 forKeys:kKeys2
3312 count:GPBARRAYSIZE(kValues2)];
3313 XCTAssertNotNil(dict2);
3314 [dict addRawEntriesFromDictionary:dict2];
3315 XCTAssertEqual(dict.count, 4U);
3316 XCTAssertTrue([dict getRawValue:NULL forKey:@"foo"]);
3317 XCTAssertTrue([dict getRawValue:&value forKey:@"foo"]);
3318 XCTAssertEqual(value, 803);
3319 XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]);
3320 XCTAssertTrue([dict getEnum:&value forKey:@"bar"]);
3321 XCTAssertEqual(value, 702);
3322 XCTAssertTrue([dict getRawValue:NULL forKey:@"baz"]);
3323 XCTAssertTrue([dict getRawValue:&value forKey:@"baz"]);
3324 XCTAssertEqual(value, 801);
3325 XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]);
3326 XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]);
3327 XCTAssertEqual(value, 700);
3328
3329 [dict2 release];
3330 [dict release];
3331}
3332
3333- (void)testCopyUnknowns {
3334 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
3335 const int32_t kValues[] = { 700, 801, 702, 803 };
3336 GPBStringEnumDictionary *dict =
3337 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3338 rawValues:kValues
3339 forKeys:kKeys
3340 count:GPBARRAYSIZE(kValues)];
3341 XCTAssertNotNil(dict);
3342
3343 GPBStringEnumDictionary *dict2 = [dict copy];
3344 XCTAssertNotNil(dict2);
3345
3346 // Should be new pointer, but equal objects.
3347 XCTAssertNotEqual(dict, dict2);
3348 XCTAssertEqualObjects(dict, dict2);
3349 XCTAssertEqual(dict.validationFunc, dict2.validationFunc); // Pointer comparison
3350 XCTAssertTrue([dict2 isKindOfClass:[GPBStringEnumDictionary class]]);
3351
3352 [dict2 release];
3353 [dict release];
3354}
3355
3356@end
3357
3358//%PDDM-EXPAND-END TESTS_FOR_POD_VALUES(String, NSString, *, Objects, @"foo", @"bar", @"baz", @"mumble")
3359