Fixed depth limit check by comparing effective depth limits.
[google-protobuf.git] / objectivec / Tests / GPBDictionaryTests+UInt64.m
blob877bead67bac110e9f6c0f9093a8cd1c48314f03
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2015 Google Inc.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
8 #import <Foundation/Foundation.h>
9 #import <XCTest/XCTest.h>
11 #import "GPBDictionary.h"
12 #import "GPBTestUtilities.h"
13 #import "objectivec/Tests/UnittestRuntimeProto2.pbobjc.h"
15 // Disable clang-format for the macros.
16 // clang-format off
18 // Pull in the macros (using an external file because expanding all tests
19 // in a single file makes a file that is failing to work with within Xcode.
20 //%PDDM-IMPORT-DEFINES GPBDictionaryTests.pddm
22 //%PDDM-EXPAND TEST_FOR_POD_KEY(UInt64, uint64_t, 31ULL, 32ULL, 33ULL, 34ULL)
23 // This block of code is generated, do not edit it directly.
25 // To let the testing macros work, add some extra methods to simplify things.
26 @interface GPBUInt64EnumDictionary (TestingTweak)
27 - (instancetype)initWithEnums:(const int32_t [])values
28                       forKeys:(const uint64_t [])keys
29                         count:(NSUInteger)count;
30 @end
32 static BOOL TestingEnum_IsValidValue(int32_t value) {
33   switch (value) {
34     case 700:
35     case 701:
36     case 702:
37     case 703:
38       return YES;
39     default:
40       return NO;
41   }
44 @implementation GPBUInt64EnumDictionary (TestingTweak)
45 - (instancetype)initWithEnums:(const int32_t [])values
46                       forKeys:(const uint64_t [])keys
47                         count:(NSUInteger)count {
48   return [self initWithValidationFunction:TestingEnum_IsValidValue
49                                 rawValues:values
50                                   forKeys:keys
51                                     count:count];
53 @end
56 #pragma mark - UInt64 -> UInt32
58 @interface GPBUInt64UInt32DictionaryTests : XCTestCase
59 @end
61 @implementation GPBUInt64UInt32DictionaryTests
63 - (void)testEmpty {
64   GPBUInt64UInt32Dictionary *dict = [[GPBUInt64UInt32Dictionary alloc] init];
65   XCTAssertNotNil(dict);
66   XCTAssertEqual(dict.count, 0U);
67   XCTAssertFalse([dict getUInt32:NULL forKey:31ULL]);
68   [dict enumerateKeysAndUInt32sUsingBlock:^(__unused uint64_t aKey, __unused uint32_t aValue, __unused BOOL *stop) {
69     XCTFail(@"Shouldn't get here!");
70   }];
71   [dict release];
74 - (void)testOne {
75   GPBUInt64UInt32Dictionary *dict = [[GPBUInt64UInt32Dictionary alloc] init];
76   [dict setUInt32:100U forKey:31ULL];
77   XCTAssertNotNil(dict);
78   XCTAssertEqual(dict.count, 1U);
79   uint32_t value;
80   XCTAssertTrue([dict getUInt32:NULL forKey:31ULL]);
81   XCTAssertTrue([dict getUInt32:&value forKey:31ULL]);
82   XCTAssertEqual(value, 100U);
83   XCTAssertFalse([dict getUInt32:NULL forKey:32ULL]);
84   [dict enumerateKeysAndUInt32sUsingBlock:^(uint64_t aKey, uint32_t aValue, BOOL *stop) {
85     XCTAssertEqual(aKey, 31ULL);
86     XCTAssertEqual(aValue, 100U);
87     XCTAssertNotEqual(stop, NULL);
88   }];
89   [dict release];
92 - (void)testBasics {
93   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL };
94   const uint32_t kValues[] = { 100U, 101U, 102U };
95   GPBUInt64UInt32Dictionary *dict =
96       [[GPBUInt64UInt32Dictionary alloc] initWithUInt32s:kValues
97                                                  forKeys:kKeys
98                                                    count:GPBARRAYSIZE(kValues)];
99   XCTAssertNotNil(dict);
100   XCTAssertEqual(dict.count, 3U);
101   uint32_t value;
102   XCTAssertTrue([dict getUInt32:NULL forKey:31ULL]);
103   XCTAssertTrue([dict getUInt32:&value forKey:31ULL]);
104   XCTAssertEqual(value, 100U);
105   XCTAssertTrue([dict getUInt32:NULL forKey:32ULL]);
106   XCTAssertTrue([dict getUInt32:&value forKey:32ULL]);
107   XCTAssertEqual(value, 101U);
108   XCTAssertTrue([dict getUInt32:NULL forKey:33ULL]);
109   XCTAssertTrue([dict getUInt32:&value forKey:33ULL]);
110   XCTAssertEqual(value, 102U);
111   XCTAssertFalse([dict getUInt32:NULL forKey:34ULL]);
113   __block NSUInteger idx = 0;
114   uint64_t *seenKeys = malloc(3 * sizeof(uint64_t));
115   uint32_t *seenValues = malloc(3 * sizeof(uint32_t));
116   [dict enumerateKeysAndUInt32sUsingBlock:^(uint64_t aKey, uint32_t aValue, BOOL *stop) {
117     XCTAssertLessThan(idx, 3U);
118     seenKeys[idx] = aKey;
119     seenValues[idx] = aValue;
120     XCTAssertNotEqual(stop, NULL);
121     ++idx;
122   }];
123   for (int i = 0; i < 3; ++i) {
124     BOOL foundKey = NO;
125     for (int j = 0; (j < 3) && !foundKey; ++j) {
126       if (kKeys[i] == seenKeys[j]) {
127         foundKey = YES;
128         XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
129       }
130     }
131     XCTAssertTrue(foundKey, @"i = %d", i);
132   }
133   free(seenKeys);
134   free(seenValues);
136   // Stopping the enumeration.
137   idx = 0;
138   [dict enumerateKeysAndUInt32sUsingBlock:^(__unused uint64_t aKey, __unused uint32_t aValue, BOOL *stop) {
139     if (idx == 1) *stop = YES;
140     XCTAssertNotEqual(idx, 2U);
141     ++idx;
142   }];
143   [dict release];
146 - (void)testEquality {
147   const uint64_t kKeys1[] = { 31ULL, 32ULL, 33ULL, 34ULL };
148   const uint64_t kKeys2[] = { 32ULL, 31ULL, 34ULL };
149   const uint32_t kValues1[] = { 100U, 101U, 102U };
150   const uint32_t kValues2[] = { 100U, 103U, 102U };
151   const uint32_t kValues3[] = { 100U, 101U, 102U, 103U };
152   GPBUInt64UInt32Dictionary *dict1 =
153       [[GPBUInt64UInt32Dictionary alloc] initWithUInt32s:kValues1
154                                                  forKeys:kKeys1
155                                                    count:GPBARRAYSIZE(kValues1)];
156   XCTAssertNotNil(dict1);
157   GPBUInt64UInt32Dictionary *dict1prime =
158       [[GPBUInt64UInt32Dictionary alloc] initWithUInt32s:kValues1
159                                                  forKeys:kKeys1
160                                                    count:GPBARRAYSIZE(kValues1)];
161   XCTAssertNotNil(dict1prime);
162   GPBUInt64UInt32Dictionary *dict2 =
163       [[GPBUInt64UInt32Dictionary alloc] initWithUInt32s:kValues2
164                                                  forKeys:kKeys1
165                                                    count:GPBARRAYSIZE(kValues2)];
166   XCTAssertNotNil(dict2);
167   GPBUInt64UInt32Dictionary *dict3 =
168       [[GPBUInt64UInt32Dictionary alloc] initWithUInt32s:kValues1
169                                                  forKeys:kKeys2
170                                                    count:GPBARRAYSIZE(kValues1)];
171   XCTAssertNotNil(dict3);
172   GPBUInt64UInt32Dictionary *dict4 =
173       [[GPBUInt64UInt32Dictionary alloc] initWithUInt32s:kValues3
174                                                  forKeys:kKeys1
175                                                    count:GPBARRAYSIZE(kValues3)];
176   XCTAssertNotNil(dict4);
178   // 1/1Prime should be different objects, but equal.
179   XCTAssertNotEqual(dict1, dict1prime);
180   XCTAssertEqualObjects(dict1, dict1prime);
181   // Equal, so they must have same hash.
182   XCTAssertEqual([dict1 hash], [dict1prime hash]);
184   // 2 is same keys, different values; not equal.
185   XCTAssertNotEqualObjects(dict1, dict2);
187   // 3 is different keys, same values; not equal.
188   XCTAssertNotEqualObjects(dict1, dict3);
190   // 4 extra pair; not equal
191   XCTAssertNotEqualObjects(dict1, dict4);
193   [dict1 release];
194   [dict1prime release];
195   [dict2 release];
196   [dict3 release];
197   [dict4 release];
200 - (void)testCopy {
201   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
202   const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
203   GPBUInt64UInt32Dictionary *dict =
204       [[GPBUInt64UInt32Dictionary alloc] initWithUInt32s:kValues
205                                                  forKeys:kKeys
206                                                    count:GPBARRAYSIZE(kValues)];
207   XCTAssertNotNil(dict);
209   GPBUInt64UInt32Dictionary *dict2 = [dict copy];
210   XCTAssertNotNil(dict2);
212   // Should be new object but equal.
213   XCTAssertNotEqual(dict, dict2);
214   XCTAssertEqualObjects(dict, dict2);
215   XCTAssertTrue([dict2 isKindOfClass:[GPBUInt64UInt32Dictionary class]]);
217   [dict2 release];
218   [dict release];
221 - (void)testDictionaryFromDictionary {
222   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
223   const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
224   GPBUInt64UInt32Dictionary *dict =
225       [[GPBUInt64UInt32Dictionary alloc] initWithUInt32s:kValues
226                                                  forKeys:kKeys
227                                                    count:GPBARRAYSIZE(kValues)];
228   XCTAssertNotNil(dict);
230   GPBUInt64UInt32Dictionary *dict2 =
231       [[GPBUInt64UInt32Dictionary alloc] initWithDictionary:dict];
232   XCTAssertNotNil(dict2);
234   // Should be new pointer, but equal objects.
235   XCTAssertNotEqual(dict, dict2);
236   XCTAssertEqualObjects(dict, dict2);
237   [dict2 release];
238   [dict release];
241 - (void)testAdds {
242   GPBUInt64UInt32Dictionary *dict = [[GPBUInt64UInt32Dictionary alloc] init];
243   XCTAssertNotNil(dict);
245   XCTAssertEqual(dict.count, 0U);
246   [dict setUInt32:100U forKey:31ULL];
247   XCTAssertEqual(dict.count, 1U);
249   const uint64_t kKeys[] = { 32ULL, 33ULL, 34ULL };
250   const uint32_t kValues[] = { 101U, 102U, 103U };
251   GPBUInt64UInt32Dictionary *dict2 =
252       [[GPBUInt64UInt32Dictionary alloc] initWithUInt32s:kValues
253                                                  forKeys:kKeys
254                                                    count:GPBARRAYSIZE(kValues)];
255   XCTAssertNotNil(dict2);
256   [dict addEntriesFromDictionary:dict2];
257   XCTAssertEqual(dict.count, 4U);
259   uint32_t value;
260   XCTAssertTrue([dict getUInt32:NULL forKey:31ULL]);
261   XCTAssertTrue([dict getUInt32:&value forKey:31ULL]);
262   XCTAssertEqual(value, 100U);
263   XCTAssertTrue([dict getUInt32:NULL forKey:32ULL]);
264   XCTAssertTrue([dict getUInt32:&value forKey:32ULL]);
265   XCTAssertEqual(value, 101U);
266   XCTAssertTrue([dict getUInt32:NULL forKey:33ULL]);
267   XCTAssertTrue([dict getUInt32:&value forKey:33ULL]);
268   XCTAssertEqual(value, 102U);
269   XCTAssertTrue([dict getUInt32:NULL forKey:34ULL]);
270   XCTAssertTrue([dict getUInt32:&value forKey:34ULL]);
271   XCTAssertEqual(value, 103U);
272   [dict2 release];
273   [dict release];
276 - (void)testRemove {
277   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
278   const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
279   GPBUInt64UInt32Dictionary *dict =
280       [[GPBUInt64UInt32Dictionary alloc] initWithUInt32s:kValues
281                                                  forKeys:kKeys
282                                                    count:GPBARRAYSIZE(kValues)];
283   XCTAssertNotNil(dict);
284   XCTAssertEqual(dict.count, 4U);
286   [dict removeUInt32ForKey:32ULL];
287   XCTAssertEqual(dict.count, 3U);
288   uint32_t value;
289   XCTAssertTrue([dict getUInt32:NULL forKey:31ULL]);
290   XCTAssertTrue([dict getUInt32:&value forKey:31ULL]);
291   XCTAssertEqual(value, 100U);
292   XCTAssertFalse([dict getUInt32:NULL forKey:32ULL]);
293   XCTAssertTrue([dict getUInt32:NULL forKey:33ULL]);
294   XCTAssertTrue([dict getUInt32:&value forKey:33ULL]);
295   XCTAssertEqual(value, 102U);
296   XCTAssertTrue([dict getUInt32:NULL forKey:34ULL]);
297   XCTAssertTrue([dict getUInt32:&value forKey:34ULL]);
298   XCTAssertEqual(value, 103U);
300   // Remove again does nothing.
301   [dict removeUInt32ForKey:32ULL];
302   XCTAssertEqual(dict.count, 3U);
303   XCTAssertTrue([dict getUInt32:NULL forKey:31ULL]);
304   XCTAssertTrue([dict getUInt32:&value forKey:31ULL]);
305   XCTAssertEqual(value, 100U);
306   XCTAssertFalse([dict getUInt32:NULL forKey:32ULL]);
307   XCTAssertTrue([dict getUInt32:NULL forKey:33ULL]);
308   XCTAssertTrue([dict getUInt32:&value forKey:33ULL]);
309   XCTAssertEqual(value, 102U);
310   XCTAssertTrue([dict getUInt32:NULL forKey:34ULL]);
311   XCTAssertTrue([dict getUInt32:&value forKey:34ULL]);
312   XCTAssertEqual(value, 103U);
314   [dict removeUInt32ForKey:34ULL];
315   XCTAssertEqual(dict.count, 2U);
316   XCTAssertTrue([dict getUInt32:NULL forKey:31ULL]);
317   XCTAssertTrue([dict getUInt32:&value forKey:31ULL]);
318   XCTAssertEqual(value, 100U);
319   XCTAssertFalse([dict getUInt32:NULL forKey:32ULL]);
320   XCTAssertTrue([dict getUInt32:NULL forKey:33ULL]);
321   XCTAssertTrue([dict getUInt32:&value forKey:33ULL]);
322   XCTAssertEqual(value, 102U);
323   XCTAssertFalse([dict getUInt32:NULL forKey:34ULL]);
325   [dict removeAll];
326   XCTAssertEqual(dict.count, 0U);
327   XCTAssertFalse([dict getUInt32:NULL forKey:31ULL]);
328   XCTAssertFalse([dict getUInt32:NULL forKey:32ULL]);
329   XCTAssertFalse([dict getUInt32:NULL forKey:33ULL]);
330   XCTAssertFalse([dict getUInt32:NULL forKey:34ULL]);
331   [dict release];
334 - (void)testInplaceMutation {
335   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
336   const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
337   GPBUInt64UInt32Dictionary *dict =
338       [[GPBUInt64UInt32Dictionary alloc] initWithUInt32s:kValues
339                                                  forKeys:kKeys
340                                                    count:GPBARRAYSIZE(kValues)];
341   XCTAssertNotNil(dict);
342   XCTAssertEqual(dict.count, 4U);
343   uint32_t value;
344   XCTAssertTrue([dict getUInt32:NULL forKey:31ULL]);
345   XCTAssertTrue([dict getUInt32:&value forKey:31ULL]);
346   XCTAssertEqual(value, 100U);
347   XCTAssertTrue([dict getUInt32:NULL forKey:32ULL]);
348   XCTAssertTrue([dict getUInt32:&value forKey:32ULL]);
349   XCTAssertEqual(value, 101U);
350   XCTAssertTrue([dict getUInt32:NULL forKey:33ULL]);
351   XCTAssertTrue([dict getUInt32:&value forKey:33ULL]);
352   XCTAssertEqual(value, 102U);
353   XCTAssertTrue([dict getUInt32:NULL forKey:34ULL]);
354   XCTAssertTrue([dict getUInt32:&value forKey:34ULL]);
355   XCTAssertEqual(value, 103U);
357   [dict setUInt32:103U forKey:31ULL];
358   XCTAssertEqual(dict.count, 4U);
359   XCTAssertTrue([dict getUInt32:NULL forKey:31ULL]);
360   XCTAssertTrue([dict getUInt32:&value forKey:31ULL]);
361   XCTAssertEqual(value, 103U);
362   XCTAssertTrue([dict getUInt32:NULL forKey:32ULL]);
363   XCTAssertTrue([dict getUInt32:&value forKey:32ULL]);
364   XCTAssertEqual(value, 101U);
365   XCTAssertTrue([dict getUInt32:NULL forKey:33ULL]);
366   XCTAssertTrue([dict getUInt32:&value forKey:33ULL]);
367   XCTAssertEqual(value, 102U);
368   XCTAssertTrue([dict getUInt32:NULL forKey:34ULL]);
369   XCTAssertTrue([dict getUInt32:&value forKey:34ULL]);
370   XCTAssertEqual(value, 103U);
372   [dict setUInt32:101U forKey:34ULL];
373   XCTAssertEqual(dict.count, 4U);
374   XCTAssertTrue([dict getUInt32:NULL forKey:31ULL]);
375   XCTAssertTrue([dict getUInt32:&value forKey:31ULL]);
376   XCTAssertEqual(value, 103U);
377   XCTAssertTrue([dict getUInt32:NULL forKey:32ULL]);
378   XCTAssertTrue([dict getUInt32:&value forKey:32ULL]);
379   XCTAssertEqual(value, 101U);
380   XCTAssertTrue([dict getUInt32:NULL forKey:33ULL]);
381   XCTAssertTrue([dict getUInt32:&value forKey:33ULL]);
382   XCTAssertEqual(value, 102U);
383   XCTAssertTrue([dict getUInt32:NULL forKey:34ULL]);
384   XCTAssertTrue([dict getUInt32:&value forKey:34ULL]);
385   XCTAssertEqual(value, 101U);
387   const uint64_t kKeys2[] = { 32ULL, 33ULL };
388   const uint32_t kValues2[] = { 102U, 100U };
389   GPBUInt64UInt32Dictionary *dict2 =
390       [[GPBUInt64UInt32Dictionary alloc] initWithUInt32s:kValues2
391                                                  forKeys:kKeys2
392                                                    count:GPBARRAYSIZE(kValues2)];
393   XCTAssertNotNil(dict2);
394   [dict addEntriesFromDictionary:dict2];
395   XCTAssertEqual(dict.count, 4U);
396   XCTAssertTrue([dict getUInt32:NULL forKey:31ULL]);
397   XCTAssertTrue([dict getUInt32:&value forKey:31ULL]);
398   XCTAssertEqual(value, 103U);
399   XCTAssertTrue([dict getUInt32:NULL forKey:32ULL]);
400   XCTAssertTrue([dict getUInt32:&value forKey:32ULL]);
401   XCTAssertEqual(value, 102U);
402   XCTAssertTrue([dict getUInt32:NULL forKey:33ULL]);
403   XCTAssertTrue([dict getUInt32:&value forKey:33ULL]);
404   XCTAssertEqual(value, 100U);
405   XCTAssertTrue([dict getUInt32:NULL forKey:34ULL]);
406   XCTAssertTrue([dict getUInt32:&value forKey:34ULL]);
407   XCTAssertEqual(value, 101U);
409   [dict2 release];
410   [dict release];
413 @end
415 #pragma mark - UInt64 -> Int32
417 @interface GPBUInt64Int32DictionaryTests : XCTestCase
418 @end
420 @implementation GPBUInt64Int32DictionaryTests
422 - (void)testEmpty {
423   GPBUInt64Int32Dictionary *dict = [[GPBUInt64Int32Dictionary alloc] init];
424   XCTAssertNotNil(dict);
425   XCTAssertEqual(dict.count, 0U);
426   XCTAssertFalse([dict getInt32:NULL forKey:31ULL]);
427   [dict enumerateKeysAndInt32sUsingBlock:^(__unused uint64_t aKey, __unused int32_t aValue, __unused BOOL *stop) {
428     XCTFail(@"Shouldn't get here!");
429   }];
430   [dict release];
433 - (void)testOne {
434   GPBUInt64Int32Dictionary *dict = [[GPBUInt64Int32Dictionary alloc] init];
435   [dict setInt32:200 forKey:31ULL];
436   XCTAssertNotNil(dict);
437   XCTAssertEqual(dict.count, 1U);
438   int32_t value;
439   XCTAssertTrue([dict getInt32:NULL forKey:31ULL]);
440   XCTAssertTrue([dict getInt32:&value forKey:31ULL]);
441   XCTAssertEqual(value, 200);
442   XCTAssertFalse([dict getInt32:NULL forKey:32ULL]);
443   [dict enumerateKeysAndInt32sUsingBlock:^(uint64_t aKey, int32_t aValue, BOOL *stop) {
444     XCTAssertEqual(aKey, 31ULL);
445     XCTAssertEqual(aValue, 200);
446     XCTAssertNotEqual(stop, NULL);
447   }];
448   [dict release];
451 - (void)testBasics {
452   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL };
453   const int32_t kValues[] = { 200, 201, 202 };
454   GPBUInt64Int32Dictionary *dict =
455       [[GPBUInt64Int32Dictionary alloc] initWithInt32s:kValues
456                                                forKeys:kKeys
457                                                  count:GPBARRAYSIZE(kValues)];
458   XCTAssertNotNil(dict);
459   XCTAssertEqual(dict.count, 3U);
460   int32_t value;
461   XCTAssertTrue([dict getInt32:NULL forKey:31ULL]);
462   XCTAssertTrue([dict getInt32:&value forKey:31ULL]);
463   XCTAssertEqual(value, 200);
464   XCTAssertTrue([dict getInt32:NULL forKey:32ULL]);
465   XCTAssertTrue([dict getInt32:&value forKey:32ULL]);
466   XCTAssertEqual(value, 201);
467   XCTAssertTrue([dict getInt32:NULL forKey:33ULL]);
468   XCTAssertTrue([dict getInt32:&value forKey:33ULL]);
469   XCTAssertEqual(value, 202);
470   XCTAssertFalse([dict getInt32:NULL forKey:34ULL]);
472   __block NSUInteger idx = 0;
473   uint64_t *seenKeys = malloc(3 * sizeof(uint64_t));
474   int32_t *seenValues = malloc(3 * sizeof(int32_t));
475   [dict enumerateKeysAndInt32sUsingBlock:^(uint64_t aKey, int32_t aValue, BOOL *stop) {
476     XCTAssertLessThan(idx, 3U);
477     seenKeys[idx] = aKey;
478     seenValues[idx] = aValue;
479     XCTAssertNotEqual(stop, NULL);
480     ++idx;
481   }];
482   for (int i = 0; i < 3; ++i) {
483     BOOL foundKey = NO;
484     for (int j = 0; (j < 3) && !foundKey; ++j) {
485       if (kKeys[i] == seenKeys[j]) {
486         foundKey = YES;
487         XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
488       }
489     }
490     XCTAssertTrue(foundKey, @"i = %d", i);
491   }
492   free(seenKeys);
493   free(seenValues);
495   // Stopping the enumeration.
496   idx = 0;
497   [dict enumerateKeysAndInt32sUsingBlock:^(__unused uint64_t aKey, __unused int32_t aValue, BOOL *stop) {
498     if (idx == 1) *stop = YES;
499     XCTAssertNotEqual(idx, 2U);
500     ++idx;
501   }];
502   [dict release];
505 - (void)testEquality {
506   const uint64_t kKeys1[] = { 31ULL, 32ULL, 33ULL, 34ULL };
507   const uint64_t kKeys2[] = { 32ULL, 31ULL, 34ULL };
508   const int32_t kValues1[] = { 200, 201, 202 };
509   const int32_t kValues2[] = { 200, 203, 202 };
510   const int32_t kValues3[] = { 200, 201, 202, 203 };
511   GPBUInt64Int32Dictionary *dict1 =
512       [[GPBUInt64Int32Dictionary alloc] initWithInt32s:kValues1
513                                                forKeys:kKeys1
514                                                  count:GPBARRAYSIZE(kValues1)];
515   XCTAssertNotNil(dict1);
516   GPBUInt64Int32Dictionary *dict1prime =
517       [[GPBUInt64Int32Dictionary alloc] initWithInt32s:kValues1
518                                                forKeys:kKeys1
519                                                  count:GPBARRAYSIZE(kValues1)];
520   XCTAssertNotNil(dict1prime);
521   GPBUInt64Int32Dictionary *dict2 =
522       [[GPBUInt64Int32Dictionary alloc] initWithInt32s:kValues2
523                                                forKeys:kKeys1
524                                                  count:GPBARRAYSIZE(kValues2)];
525   XCTAssertNotNil(dict2);
526   GPBUInt64Int32Dictionary *dict3 =
527       [[GPBUInt64Int32Dictionary alloc] initWithInt32s:kValues1
528                                                forKeys:kKeys2
529                                                  count:GPBARRAYSIZE(kValues1)];
530   XCTAssertNotNil(dict3);
531   GPBUInt64Int32Dictionary *dict4 =
532       [[GPBUInt64Int32Dictionary alloc] initWithInt32s:kValues3
533                                                forKeys:kKeys1
534                                                  count:GPBARRAYSIZE(kValues3)];
535   XCTAssertNotNil(dict4);
537   // 1/1Prime should be different objects, but equal.
538   XCTAssertNotEqual(dict1, dict1prime);
539   XCTAssertEqualObjects(dict1, dict1prime);
540   // Equal, so they must have same hash.
541   XCTAssertEqual([dict1 hash], [dict1prime hash]);
543   // 2 is same keys, different values; not equal.
544   XCTAssertNotEqualObjects(dict1, dict2);
546   // 3 is different keys, same values; not equal.
547   XCTAssertNotEqualObjects(dict1, dict3);
549   // 4 extra pair; not equal
550   XCTAssertNotEqualObjects(dict1, dict4);
552   [dict1 release];
553   [dict1prime release];
554   [dict2 release];
555   [dict3 release];
556   [dict4 release];
559 - (void)testCopy {
560   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
561   const int32_t kValues[] = { 200, 201, 202, 203 };
562   GPBUInt64Int32Dictionary *dict =
563       [[GPBUInt64Int32Dictionary alloc] initWithInt32s:kValues
564                                                forKeys:kKeys
565                                                  count:GPBARRAYSIZE(kValues)];
566   XCTAssertNotNil(dict);
568   GPBUInt64Int32Dictionary *dict2 = [dict copy];
569   XCTAssertNotNil(dict2);
571   // Should be new object but equal.
572   XCTAssertNotEqual(dict, dict2);
573   XCTAssertEqualObjects(dict, dict2);
574   XCTAssertTrue([dict2 isKindOfClass:[GPBUInt64Int32Dictionary class]]);
576   [dict2 release];
577   [dict release];
580 - (void)testDictionaryFromDictionary {
581   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
582   const int32_t kValues[] = { 200, 201, 202, 203 };
583   GPBUInt64Int32Dictionary *dict =
584       [[GPBUInt64Int32Dictionary alloc] initWithInt32s:kValues
585                                                forKeys:kKeys
586                                                  count:GPBARRAYSIZE(kValues)];
587   XCTAssertNotNil(dict);
589   GPBUInt64Int32Dictionary *dict2 =
590       [[GPBUInt64Int32Dictionary alloc] initWithDictionary:dict];
591   XCTAssertNotNil(dict2);
593   // Should be new pointer, but equal objects.
594   XCTAssertNotEqual(dict, dict2);
595   XCTAssertEqualObjects(dict, dict2);
596   [dict2 release];
597   [dict release];
600 - (void)testAdds {
601   GPBUInt64Int32Dictionary *dict = [[GPBUInt64Int32Dictionary alloc] init];
602   XCTAssertNotNil(dict);
604   XCTAssertEqual(dict.count, 0U);
605   [dict setInt32:200 forKey:31ULL];
606   XCTAssertEqual(dict.count, 1U);
608   const uint64_t kKeys[] = { 32ULL, 33ULL, 34ULL };
609   const int32_t kValues[] = { 201, 202, 203 };
610   GPBUInt64Int32Dictionary *dict2 =
611       [[GPBUInt64Int32Dictionary alloc] initWithInt32s:kValues
612                                                forKeys:kKeys
613                                                  count:GPBARRAYSIZE(kValues)];
614   XCTAssertNotNil(dict2);
615   [dict addEntriesFromDictionary:dict2];
616   XCTAssertEqual(dict.count, 4U);
618   int32_t value;
619   XCTAssertTrue([dict getInt32:NULL forKey:31ULL]);
620   XCTAssertTrue([dict getInt32:&value forKey:31ULL]);
621   XCTAssertEqual(value, 200);
622   XCTAssertTrue([dict getInt32:NULL forKey:32ULL]);
623   XCTAssertTrue([dict getInt32:&value forKey:32ULL]);
624   XCTAssertEqual(value, 201);
625   XCTAssertTrue([dict getInt32:NULL forKey:33ULL]);
626   XCTAssertTrue([dict getInt32:&value forKey:33ULL]);
627   XCTAssertEqual(value, 202);
628   XCTAssertTrue([dict getInt32:NULL forKey:34ULL]);
629   XCTAssertTrue([dict getInt32:&value forKey:34ULL]);
630   XCTAssertEqual(value, 203);
631   [dict2 release];
632   [dict release];
635 - (void)testRemove {
636   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
637   const int32_t kValues[] = { 200, 201, 202, 203 };
638   GPBUInt64Int32Dictionary *dict =
639       [[GPBUInt64Int32Dictionary alloc] initWithInt32s:kValues
640                                                forKeys:kKeys
641                                                  count:GPBARRAYSIZE(kValues)];
642   XCTAssertNotNil(dict);
643   XCTAssertEqual(dict.count, 4U);
645   [dict removeInt32ForKey:32ULL];
646   XCTAssertEqual(dict.count, 3U);
647   int32_t value;
648   XCTAssertTrue([dict getInt32:NULL forKey:31ULL]);
649   XCTAssertTrue([dict getInt32:&value forKey:31ULL]);
650   XCTAssertEqual(value, 200);
651   XCTAssertFalse([dict getInt32:NULL forKey:32ULL]);
652   XCTAssertTrue([dict getInt32:NULL forKey:33ULL]);
653   XCTAssertTrue([dict getInt32:&value forKey:33ULL]);
654   XCTAssertEqual(value, 202);
655   XCTAssertTrue([dict getInt32:NULL forKey:34ULL]);
656   XCTAssertTrue([dict getInt32:&value forKey:34ULL]);
657   XCTAssertEqual(value, 203);
659   // Remove again does nothing.
660   [dict removeInt32ForKey:32ULL];
661   XCTAssertEqual(dict.count, 3U);
662   XCTAssertTrue([dict getInt32:NULL forKey:31ULL]);
663   XCTAssertTrue([dict getInt32:&value forKey:31ULL]);
664   XCTAssertEqual(value, 200);
665   XCTAssertFalse([dict getInt32:NULL forKey:32ULL]);
666   XCTAssertTrue([dict getInt32:NULL forKey:33ULL]);
667   XCTAssertTrue([dict getInt32:&value forKey:33ULL]);
668   XCTAssertEqual(value, 202);
669   XCTAssertTrue([dict getInt32:NULL forKey:34ULL]);
670   XCTAssertTrue([dict getInt32:&value forKey:34ULL]);
671   XCTAssertEqual(value, 203);
673   [dict removeInt32ForKey:34ULL];
674   XCTAssertEqual(dict.count, 2U);
675   XCTAssertTrue([dict getInt32:NULL forKey:31ULL]);
676   XCTAssertTrue([dict getInt32:&value forKey:31ULL]);
677   XCTAssertEqual(value, 200);
678   XCTAssertFalse([dict getInt32:NULL forKey:32ULL]);
679   XCTAssertTrue([dict getInt32:NULL forKey:33ULL]);
680   XCTAssertTrue([dict getInt32:&value forKey:33ULL]);
681   XCTAssertEqual(value, 202);
682   XCTAssertFalse([dict getInt32:NULL forKey:34ULL]);
684   [dict removeAll];
685   XCTAssertEqual(dict.count, 0U);
686   XCTAssertFalse([dict getInt32:NULL forKey:31ULL]);
687   XCTAssertFalse([dict getInt32:NULL forKey:32ULL]);
688   XCTAssertFalse([dict getInt32:NULL forKey:33ULL]);
689   XCTAssertFalse([dict getInt32:NULL forKey:34ULL]);
690   [dict release];
693 - (void)testInplaceMutation {
694   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
695   const int32_t kValues[] = { 200, 201, 202, 203 };
696   GPBUInt64Int32Dictionary *dict =
697       [[GPBUInt64Int32Dictionary alloc] initWithInt32s:kValues
698                                                forKeys:kKeys
699                                                  count:GPBARRAYSIZE(kValues)];
700   XCTAssertNotNil(dict);
701   XCTAssertEqual(dict.count, 4U);
702   int32_t value;
703   XCTAssertTrue([dict getInt32:NULL forKey:31ULL]);
704   XCTAssertTrue([dict getInt32:&value forKey:31ULL]);
705   XCTAssertEqual(value, 200);
706   XCTAssertTrue([dict getInt32:NULL forKey:32ULL]);
707   XCTAssertTrue([dict getInt32:&value forKey:32ULL]);
708   XCTAssertEqual(value, 201);
709   XCTAssertTrue([dict getInt32:NULL forKey:33ULL]);
710   XCTAssertTrue([dict getInt32:&value forKey:33ULL]);
711   XCTAssertEqual(value, 202);
712   XCTAssertTrue([dict getInt32:NULL forKey:34ULL]);
713   XCTAssertTrue([dict getInt32:&value forKey:34ULL]);
714   XCTAssertEqual(value, 203);
716   [dict setInt32:203 forKey:31ULL];
717   XCTAssertEqual(dict.count, 4U);
718   XCTAssertTrue([dict getInt32:NULL forKey:31ULL]);
719   XCTAssertTrue([dict getInt32:&value forKey:31ULL]);
720   XCTAssertEqual(value, 203);
721   XCTAssertTrue([dict getInt32:NULL forKey:32ULL]);
722   XCTAssertTrue([dict getInt32:&value forKey:32ULL]);
723   XCTAssertEqual(value, 201);
724   XCTAssertTrue([dict getInt32:NULL forKey:33ULL]);
725   XCTAssertTrue([dict getInt32:&value forKey:33ULL]);
726   XCTAssertEqual(value, 202);
727   XCTAssertTrue([dict getInt32:NULL forKey:34ULL]);
728   XCTAssertTrue([dict getInt32:&value forKey:34ULL]);
729   XCTAssertEqual(value, 203);
731   [dict setInt32:201 forKey:34ULL];
732   XCTAssertEqual(dict.count, 4U);
733   XCTAssertTrue([dict getInt32:NULL forKey:31ULL]);
734   XCTAssertTrue([dict getInt32:&value forKey:31ULL]);
735   XCTAssertEqual(value, 203);
736   XCTAssertTrue([dict getInt32:NULL forKey:32ULL]);
737   XCTAssertTrue([dict getInt32:&value forKey:32ULL]);
738   XCTAssertEqual(value, 201);
739   XCTAssertTrue([dict getInt32:NULL forKey:33ULL]);
740   XCTAssertTrue([dict getInt32:&value forKey:33ULL]);
741   XCTAssertEqual(value, 202);
742   XCTAssertTrue([dict getInt32:NULL forKey:34ULL]);
743   XCTAssertTrue([dict getInt32:&value forKey:34ULL]);
744   XCTAssertEqual(value, 201);
746   const uint64_t kKeys2[] = { 32ULL, 33ULL };
747   const int32_t kValues2[] = { 202, 200 };
748   GPBUInt64Int32Dictionary *dict2 =
749       [[GPBUInt64Int32Dictionary alloc] initWithInt32s:kValues2
750                                                forKeys:kKeys2
751                                                  count:GPBARRAYSIZE(kValues2)];
752   XCTAssertNotNil(dict2);
753   [dict addEntriesFromDictionary:dict2];
754   XCTAssertEqual(dict.count, 4U);
755   XCTAssertTrue([dict getInt32:NULL forKey:31ULL]);
756   XCTAssertTrue([dict getInt32:&value forKey:31ULL]);
757   XCTAssertEqual(value, 203);
758   XCTAssertTrue([dict getInt32:NULL forKey:32ULL]);
759   XCTAssertTrue([dict getInt32:&value forKey:32ULL]);
760   XCTAssertEqual(value, 202);
761   XCTAssertTrue([dict getInt32:NULL forKey:33ULL]);
762   XCTAssertTrue([dict getInt32:&value forKey:33ULL]);
763   XCTAssertEqual(value, 200);
764   XCTAssertTrue([dict getInt32:NULL forKey:34ULL]);
765   XCTAssertTrue([dict getInt32:&value forKey:34ULL]);
766   XCTAssertEqual(value, 201);
768   [dict2 release];
769   [dict release];
772 @end
774 #pragma mark - UInt64 -> UInt64
776 @interface GPBUInt64UInt64DictionaryTests : XCTestCase
777 @end
779 @implementation GPBUInt64UInt64DictionaryTests
781 - (void)testEmpty {
782   GPBUInt64UInt64Dictionary *dict = [[GPBUInt64UInt64Dictionary alloc] init];
783   XCTAssertNotNil(dict);
784   XCTAssertEqual(dict.count, 0U);
785   XCTAssertFalse([dict getUInt64:NULL forKey:31ULL]);
786   [dict enumerateKeysAndUInt64sUsingBlock:^(__unused uint64_t aKey, __unused uint64_t aValue, __unused BOOL *stop) {
787     XCTFail(@"Shouldn't get here!");
788   }];
789   [dict release];
792 - (void)testOne {
793   GPBUInt64UInt64Dictionary *dict = [[GPBUInt64UInt64Dictionary alloc] init];
794   [dict setUInt64:300U forKey:31ULL];
795   XCTAssertNotNil(dict);
796   XCTAssertEqual(dict.count, 1U);
797   uint64_t value;
798   XCTAssertTrue([dict getUInt64:NULL forKey:31ULL]);
799   XCTAssertTrue([dict getUInt64:&value forKey:31ULL]);
800   XCTAssertEqual(value, 300U);
801   XCTAssertFalse([dict getUInt64:NULL forKey:32ULL]);
802   [dict enumerateKeysAndUInt64sUsingBlock:^(uint64_t aKey, uint64_t aValue, BOOL *stop) {
803     XCTAssertEqual(aKey, 31ULL);
804     XCTAssertEqual(aValue, 300U);
805     XCTAssertNotEqual(stop, NULL);
806   }];
807   [dict release];
810 - (void)testBasics {
811   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL };
812   const uint64_t kValues[] = { 300U, 301U, 302U };
813   GPBUInt64UInt64Dictionary *dict =
814       [[GPBUInt64UInt64Dictionary alloc] initWithUInt64s:kValues
815                                                  forKeys:kKeys
816                                                    count:GPBARRAYSIZE(kValues)];
817   XCTAssertNotNil(dict);
818   XCTAssertEqual(dict.count, 3U);
819   uint64_t value;
820   XCTAssertTrue([dict getUInt64:NULL forKey:31ULL]);
821   XCTAssertTrue([dict getUInt64:&value forKey:31ULL]);
822   XCTAssertEqual(value, 300U);
823   XCTAssertTrue([dict getUInt64:NULL forKey:32ULL]);
824   XCTAssertTrue([dict getUInt64:&value forKey:32ULL]);
825   XCTAssertEqual(value, 301U);
826   XCTAssertTrue([dict getUInt64:NULL forKey:33ULL]);
827   XCTAssertTrue([dict getUInt64:&value forKey:33ULL]);
828   XCTAssertEqual(value, 302U);
829   XCTAssertFalse([dict getUInt64:NULL forKey:34ULL]);
831   __block NSUInteger idx = 0;
832   uint64_t *seenKeys = malloc(3 * sizeof(uint64_t));
833   uint64_t *seenValues = malloc(3 * sizeof(uint64_t));
834   [dict enumerateKeysAndUInt64sUsingBlock:^(uint64_t aKey, uint64_t aValue, BOOL *stop) {
835     XCTAssertLessThan(idx, 3U);
836     seenKeys[idx] = aKey;
837     seenValues[idx] = aValue;
838     XCTAssertNotEqual(stop, NULL);
839     ++idx;
840   }];
841   for (int i = 0; i < 3; ++i) {
842     BOOL foundKey = NO;
843     for (int j = 0; (j < 3) && !foundKey; ++j) {
844       if (kKeys[i] == seenKeys[j]) {
845         foundKey = YES;
846         XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
847       }
848     }
849     XCTAssertTrue(foundKey, @"i = %d", i);
850   }
851   free(seenKeys);
852   free(seenValues);
854   // Stopping the enumeration.
855   idx = 0;
856   [dict enumerateKeysAndUInt64sUsingBlock:^(__unused uint64_t aKey, __unused uint64_t aValue, BOOL *stop) {
857     if (idx == 1) *stop = YES;
858     XCTAssertNotEqual(idx, 2U);
859     ++idx;
860   }];
861   [dict release];
864 - (void)testEquality {
865   const uint64_t kKeys1[] = { 31ULL, 32ULL, 33ULL, 34ULL };
866   const uint64_t kKeys2[] = { 32ULL, 31ULL, 34ULL };
867   const uint64_t kValues1[] = { 300U, 301U, 302U };
868   const uint64_t kValues2[] = { 300U, 303U, 302U };
869   const uint64_t kValues3[] = { 300U, 301U, 302U, 303U };
870   GPBUInt64UInt64Dictionary *dict1 =
871       [[GPBUInt64UInt64Dictionary alloc] initWithUInt64s:kValues1
872                                                  forKeys:kKeys1
873                                                    count:GPBARRAYSIZE(kValues1)];
874   XCTAssertNotNil(dict1);
875   GPBUInt64UInt64Dictionary *dict1prime =
876       [[GPBUInt64UInt64Dictionary alloc] initWithUInt64s:kValues1
877                                                  forKeys:kKeys1
878                                                    count:GPBARRAYSIZE(kValues1)];
879   XCTAssertNotNil(dict1prime);
880   GPBUInt64UInt64Dictionary *dict2 =
881       [[GPBUInt64UInt64Dictionary alloc] initWithUInt64s:kValues2
882                                                  forKeys:kKeys1
883                                                    count:GPBARRAYSIZE(kValues2)];
884   XCTAssertNotNil(dict2);
885   GPBUInt64UInt64Dictionary *dict3 =
886       [[GPBUInt64UInt64Dictionary alloc] initWithUInt64s:kValues1
887                                                  forKeys:kKeys2
888                                                    count:GPBARRAYSIZE(kValues1)];
889   XCTAssertNotNil(dict3);
890   GPBUInt64UInt64Dictionary *dict4 =
891       [[GPBUInt64UInt64Dictionary alloc] initWithUInt64s:kValues3
892                                                  forKeys:kKeys1
893                                                    count:GPBARRAYSIZE(kValues3)];
894   XCTAssertNotNil(dict4);
896   // 1/1Prime should be different objects, but equal.
897   XCTAssertNotEqual(dict1, dict1prime);
898   XCTAssertEqualObjects(dict1, dict1prime);
899   // Equal, so they must have same hash.
900   XCTAssertEqual([dict1 hash], [dict1prime hash]);
902   // 2 is same keys, different values; not equal.
903   XCTAssertNotEqualObjects(dict1, dict2);
905   // 3 is different keys, same values; not equal.
906   XCTAssertNotEqualObjects(dict1, dict3);
908   // 4 extra pair; not equal
909   XCTAssertNotEqualObjects(dict1, dict4);
911   [dict1 release];
912   [dict1prime release];
913   [dict2 release];
914   [dict3 release];
915   [dict4 release];
918 - (void)testCopy {
919   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
920   const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
921   GPBUInt64UInt64Dictionary *dict =
922       [[GPBUInt64UInt64Dictionary alloc] initWithUInt64s:kValues
923                                                  forKeys:kKeys
924                                                    count:GPBARRAYSIZE(kValues)];
925   XCTAssertNotNil(dict);
927   GPBUInt64UInt64Dictionary *dict2 = [dict copy];
928   XCTAssertNotNil(dict2);
930   // Should be new object but equal.
931   XCTAssertNotEqual(dict, dict2);
932   XCTAssertEqualObjects(dict, dict2);
933   XCTAssertTrue([dict2 isKindOfClass:[GPBUInt64UInt64Dictionary class]]);
935   [dict2 release];
936   [dict release];
939 - (void)testDictionaryFromDictionary {
940   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
941   const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
942   GPBUInt64UInt64Dictionary *dict =
943       [[GPBUInt64UInt64Dictionary alloc] initWithUInt64s:kValues
944                                                  forKeys:kKeys
945                                                    count:GPBARRAYSIZE(kValues)];
946   XCTAssertNotNil(dict);
948   GPBUInt64UInt64Dictionary *dict2 =
949       [[GPBUInt64UInt64Dictionary alloc] initWithDictionary:dict];
950   XCTAssertNotNil(dict2);
952   // Should be new pointer, but equal objects.
953   XCTAssertNotEqual(dict, dict2);
954   XCTAssertEqualObjects(dict, dict2);
955   [dict2 release];
956   [dict release];
959 - (void)testAdds {
960   GPBUInt64UInt64Dictionary *dict = [[GPBUInt64UInt64Dictionary alloc] init];
961   XCTAssertNotNil(dict);
963   XCTAssertEqual(dict.count, 0U);
964   [dict setUInt64:300U forKey:31ULL];
965   XCTAssertEqual(dict.count, 1U);
967   const uint64_t kKeys[] = { 32ULL, 33ULL, 34ULL };
968   const uint64_t kValues[] = { 301U, 302U, 303U };
969   GPBUInt64UInt64Dictionary *dict2 =
970       [[GPBUInt64UInt64Dictionary alloc] initWithUInt64s:kValues
971                                                  forKeys:kKeys
972                                                    count:GPBARRAYSIZE(kValues)];
973   XCTAssertNotNil(dict2);
974   [dict addEntriesFromDictionary:dict2];
975   XCTAssertEqual(dict.count, 4U);
977   uint64_t value;
978   XCTAssertTrue([dict getUInt64:NULL forKey:31ULL]);
979   XCTAssertTrue([dict getUInt64:&value forKey:31ULL]);
980   XCTAssertEqual(value, 300U);
981   XCTAssertTrue([dict getUInt64:NULL forKey:32ULL]);
982   XCTAssertTrue([dict getUInt64:&value forKey:32ULL]);
983   XCTAssertEqual(value, 301U);
984   XCTAssertTrue([dict getUInt64:NULL forKey:33ULL]);
985   XCTAssertTrue([dict getUInt64:&value forKey:33ULL]);
986   XCTAssertEqual(value, 302U);
987   XCTAssertTrue([dict getUInt64:NULL forKey:34ULL]);
988   XCTAssertTrue([dict getUInt64:&value forKey:34ULL]);
989   XCTAssertEqual(value, 303U);
990   [dict2 release];
991   [dict release];
994 - (void)testRemove {
995   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
996   const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
997   GPBUInt64UInt64Dictionary *dict =
998       [[GPBUInt64UInt64Dictionary alloc] initWithUInt64s:kValues
999                                                  forKeys:kKeys
1000                                                    count:GPBARRAYSIZE(kValues)];
1001   XCTAssertNotNil(dict);
1002   XCTAssertEqual(dict.count, 4U);
1004   [dict removeUInt64ForKey:32ULL];
1005   XCTAssertEqual(dict.count, 3U);
1006   uint64_t value;
1007   XCTAssertTrue([dict getUInt64:NULL forKey:31ULL]);
1008   XCTAssertTrue([dict getUInt64:&value forKey:31ULL]);
1009   XCTAssertEqual(value, 300U);
1010   XCTAssertFalse([dict getUInt64:NULL forKey:32ULL]);
1011   XCTAssertTrue([dict getUInt64:NULL forKey:33ULL]);
1012   XCTAssertTrue([dict getUInt64:&value forKey:33ULL]);
1013   XCTAssertEqual(value, 302U);
1014   XCTAssertTrue([dict getUInt64:NULL forKey:34ULL]);
1015   XCTAssertTrue([dict getUInt64:&value forKey:34ULL]);
1016   XCTAssertEqual(value, 303U);
1018   // Remove again does nothing.
1019   [dict removeUInt64ForKey:32ULL];
1020   XCTAssertEqual(dict.count, 3U);
1021   XCTAssertTrue([dict getUInt64:NULL forKey:31ULL]);
1022   XCTAssertTrue([dict getUInt64:&value forKey:31ULL]);
1023   XCTAssertEqual(value, 300U);
1024   XCTAssertFalse([dict getUInt64:NULL forKey:32ULL]);
1025   XCTAssertTrue([dict getUInt64:NULL forKey:33ULL]);
1026   XCTAssertTrue([dict getUInt64:&value forKey:33ULL]);
1027   XCTAssertEqual(value, 302U);
1028   XCTAssertTrue([dict getUInt64:NULL forKey:34ULL]);
1029   XCTAssertTrue([dict getUInt64:&value forKey:34ULL]);
1030   XCTAssertEqual(value, 303U);
1032   [dict removeUInt64ForKey:34ULL];
1033   XCTAssertEqual(dict.count, 2U);
1034   XCTAssertTrue([dict getUInt64:NULL forKey:31ULL]);
1035   XCTAssertTrue([dict getUInt64:&value forKey:31ULL]);
1036   XCTAssertEqual(value, 300U);
1037   XCTAssertFalse([dict getUInt64:NULL forKey:32ULL]);
1038   XCTAssertTrue([dict getUInt64:NULL forKey:33ULL]);
1039   XCTAssertTrue([dict getUInt64:&value forKey:33ULL]);
1040   XCTAssertEqual(value, 302U);
1041   XCTAssertFalse([dict getUInt64:NULL forKey:34ULL]);
1043   [dict removeAll];
1044   XCTAssertEqual(dict.count, 0U);
1045   XCTAssertFalse([dict getUInt64:NULL forKey:31ULL]);
1046   XCTAssertFalse([dict getUInt64:NULL forKey:32ULL]);
1047   XCTAssertFalse([dict getUInt64:NULL forKey:33ULL]);
1048   XCTAssertFalse([dict getUInt64:NULL forKey:34ULL]);
1049   [dict release];
1052 - (void)testInplaceMutation {
1053   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
1054   const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
1055   GPBUInt64UInt64Dictionary *dict =
1056       [[GPBUInt64UInt64Dictionary alloc] initWithUInt64s:kValues
1057                                                  forKeys:kKeys
1058                                                    count:GPBARRAYSIZE(kValues)];
1059   XCTAssertNotNil(dict);
1060   XCTAssertEqual(dict.count, 4U);
1061   uint64_t value;
1062   XCTAssertTrue([dict getUInt64:NULL forKey:31ULL]);
1063   XCTAssertTrue([dict getUInt64:&value forKey:31ULL]);
1064   XCTAssertEqual(value, 300U);
1065   XCTAssertTrue([dict getUInt64:NULL forKey:32ULL]);
1066   XCTAssertTrue([dict getUInt64:&value forKey:32ULL]);
1067   XCTAssertEqual(value, 301U);
1068   XCTAssertTrue([dict getUInt64:NULL forKey:33ULL]);
1069   XCTAssertTrue([dict getUInt64:&value forKey:33ULL]);
1070   XCTAssertEqual(value, 302U);
1071   XCTAssertTrue([dict getUInt64:NULL forKey:34ULL]);
1072   XCTAssertTrue([dict getUInt64:&value forKey:34ULL]);
1073   XCTAssertEqual(value, 303U);
1075   [dict setUInt64:303U forKey:31ULL];
1076   XCTAssertEqual(dict.count, 4U);
1077   XCTAssertTrue([dict getUInt64:NULL forKey:31ULL]);
1078   XCTAssertTrue([dict getUInt64:&value forKey:31ULL]);
1079   XCTAssertEqual(value, 303U);
1080   XCTAssertTrue([dict getUInt64:NULL forKey:32ULL]);
1081   XCTAssertTrue([dict getUInt64:&value forKey:32ULL]);
1082   XCTAssertEqual(value, 301U);
1083   XCTAssertTrue([dict getUInt64:NULL forKey:33ULL]);
1084   XCTAssertTrue([dict getUInt64:&value forKey:33ULL]);
1085   XCTAssertEqual(value, 302U);
1086   XCTAssertTrue([dict getUInt64:NULL forKey:34ULL]);
1087   XCTAssertTrue([dict getUInt64:&value forKey:34ULL]);
1088   XCTAssertEqual(value, 303U);
1090   [dict setUInt64:301U forKey:34ULL];
1091   XCTAssertEqual(dict.count, 4U);
1092   XCTAssertTrue([dict getUInt64:NULL forKey:31ULL]);
1093   XCTAssertTrue([dict getUInt64:&value forKey:31ULL]);
1094   XCTAssertEqual(value, 303U);
1095   XCTAssertTrue([dict getUInt64:NULL forKey:32ULL]);
1096   XCTAssertTrue([dict getUInt64:&value forKey:32ULL]);
1097   XCTAssertEqual(value, 301U);
1098   XCTAssertTrue([dict getUInt64:NULL forKey:33ULL]);
1099   XCTAssertTrue([dict getUInt64:&value forKey:33ULL]);
1100   XCTAssertEqual(value, 302U);
1101   XCTAssertTrue([dict getUInt64:NULL forKey:34ULL]);
1102   XCTAssertTrue([dict getUInt64:&value forKey:34ULL]);
1103   XCTAssertEqual(value, 301U);
1105   const uint64_t kKeys2[] = { 32ULL, 33ULL };
1106   const uint64_t kValues2[] = { 302U, 300U };
1107   GPBUInt64UInt64Dictionary *dict2 =
1108       [[GPBUInt64UInt64Dictionary alloc] initWithUInt64s:kValues2
1109                                                  forKeys:kKeys2
1110                                                    count:GPBARRAYSIZE(kValues2)];
1111   XCTAssertNotNil(dict2);
1112   [dict addEntriesFromDictionary:dict2];
1113   XCTAssertEqual(dict.count, 4U);
1114   XCTAssertTrue([dict getUInt64:NULL forKey:31ULL]);
1115   XCTAssertTrue([dict getUInt64:&value forKey:31ULL]);
1116   XCTAssertEqual(value, 303U);
1117   XCTAssertTrue([dict getUInt64:NULL forKey:32ULL]);
1118   XCTAssertTrue([dict getUInt64:&value forKey:32ULL]);
1119   XCTAssertEqual(value, 302U);
1120   XCTAssertTrue([dict getUInt64:NULL forKey:33ULL]);
1121   XCTAssertTrue([dict getUInt64:&value forKey:33ULL]);
1122   XCTAssertEqual(value, 300U);
1123   XCTAssertTrue([dict getUInt64:NULL forKey:34ULL]);
1124   XCTAssertTrue([dict getUInt64:&value forKey:34ULL]);
1125   XCTAssertEqual(value, 301U);
1127   [dict2 release];
1128   [dict release];
1131 @end
1133 #pragma mark - UInt64 -> Int64
1135 @interface GPBUInt64Int64DictionaryTests : XCTestCase
1136 @end
1138 @implementation GPBUInt64Int64DictionaryTests
1140 - (void)testEmpty {
1141   GPBUInt64Int64Dictionary *dict = [[GPBUInt64Int64Dictionary alloc] init];
1142   XCTAssertNotNil(dict);
1143   XCTAssertEqual(dict.count, 0U);
1144   XCTAssertFalse([dict getInt64:NULL forKey:31ULL]);
1145   [dict enumerateKeysAndInt64sUsingBlock:^(__unused uint64_t aKey, __unused int64_t aValue, __unused BOOL *stop) {
1146     XCTFail(@"Shouldn't get here!");
1147   }];
1148   [dict release];
1151 - (void)testOne {
1152   GPBUInt64Int64Dictionary *dict = [[GPBUInt64Int64Dictionary alloc] init];
1153   [dict setInt64:400 forKey:31ULL];
1154   XCTAssertNotNil(dict);
1155   XCTAssertEqual(dict.count, 1U);
1156   int64_t value;
1157   XCTAssertTrue([dict getInt64:NULL forKey:31ULL]);
1158   XCTAssertTrue([dict getInt64:&value forKey:31ULL]);
1159   XCTAssertEqual(value, 400);
1160   XCTAssertFalse([dict getInt64:NULL forKey:32ULL]);
1161   [dict enumerateKeysAndInt64sUsingBlock:^(uint64_t aKey, int64_t aValue, BOOL *stop) {
1162     XCTAssertEqual(aKey, 31ULL);
1163     XCTAssertEqual(aValue, 400);
1164     XCTAssertNotEqual(stop, NULL);
1165   }];
1166   [dict release];
1169 - (void)testBasics {
1170   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL };
1171   const int64_t kValues[] = { 400, 401, 402 };
1172   GPBUInt64Int64Dictionary *dict =
1173       [[GPBUInt64Int64Dictionary alloc] initWithInt64s:kValues
1174                                                forKeys:kKeys
1175                                                  count:GPBARRAYSIZE(kValues)];
1176   XCTAssertNotNil(dict);
1177   XCTAssertEqual(dict.count, 3U);
1178   int64_t value;
1179   XCTAssertTrue([dict getInt64:NULL forKey:31ULL]);
1180   XCTAssertTrue([dict getInt64:&value forKey:31ULL]);
1181   XCTAssertEqual(value, 400);
1182   XCTAssertTrue([dict getInt64:NULL forKey:32ULL]);
1183   XCTAssertTrue([dict getInt64:&value forKey:32ULL]);
1184   XCTAssertEqual(value, 401);
1185   XCTAssertTrue([dict getInt64:NULL forKey:33ULL]);
1186   XCTAssertTrue([dict getInt64:&value forKey:33ULL]);
1187   XCTAssertEqual(value, 402);
1188   XCTAssertFalse([dict getInt64:NULL forKey:34ULL]);
1190   __block NSUInteger idx = 0;
1191   uint64_t *seenKeys = malloc(3 * sizeof(uint64_t));
1192   int64_t *seenValues = malloc(3 * sizeof(int64_t));
1193   [dict enumerateKeysAndInt64sUsingBlock:^(uint64_t aKey, int64_t aValue, BOOL *stop) {
1194     XCTAssertLessThan(idx, 3U);
1195     seenKeys[idx] = aKey;
1196     seenValues[idx] = aValue;
1197     XCTAssertNotEqual(stop, NULL);
1198     ++idx;
1199   }];
1200   for (int i = 0; i < 3; ++i) {
1201     BOOL foundKey = NO;
1202     for (int j = 0; (j < 3) && !foundKey; ++j) {
1203       if (kKeys[i] == seenKeys[j]) {
1204         foundKey = YES;
1205         XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
1206       }
1207     }
1208     XCTAssertTrue(foundKey, @"i = %d", i);
1209   }
1210   free(seenKeys);
1211   free(seenValues);
1213   // Stopping the enumeration.
1214   idx = 0;
1215   [dict enumerateKeysAndInt64sUsingBlock:^(__unused uint64_t aKey, __unused int64_t aValue, BOOL *stop) {
1216     if (idx == 1) *stop = YES;
1217     XCTAssertNotEqual(idx, 2U);
1218     ++idx;
1219   }];
1220   [dict release];
1223 - (void)testEquality {
1224   const uint64_t kKeys1[] = { 31ULL, 32ULL, 33ULL, 34ULL };
1225   const uint64_t kKeys2[] = { 32ULL, 31ULL, 34ULL };
1226   const int64_t kValues1[] = { 400, 401, 402 };
1227   const int64_t kValues2[] = { 400, 403, 402 };
1228   const int64_t kValues3[] = { 400, 401, 402, 403 };
1229   GPBUInt64Int64Dictionary *dict1 =
1230       [[GPBUInt64Int64Dictionary alloc] initWithInt64s:kValues1
1231                                                forKeys:kKeys1
1232                                                  count:GPBARRAYSIZE(kValues1)];
1233   XCTAssertNotNil(dict1);
1234   GPBUInt64Int64Dictionary *dict1prime =
1235       [[GPBUInt64Int64Dictionary alloc] initWithInt64s:kValues1
1236                                                forKeys:kKeys1
1237                                                  count:GPBARRAYSIZE(kValues1)];
1238   XCTAssertNotNil(dict1prime);
1239   GPBUInt64Int64Dictionary *dict2 =
1240       [[GPBUInt64Int64Dictionary alloc] initWithInt64s:kValues2
1241                                                forKeys:kKeys1
1242                                                  count:GPBARRAYSIZE(kValues2)];
1243   XCTAssertNotNil(dict2);
1244   GPBUInt64Int64Dictionary *dict3 =
1245       [[GPBUInt64Int64Dictionary alloc] initWithInt64s:kValues1
1246                                                forKeys:kKeys2
1247                                                  count:GPBARRAYSIZE(kValues1)];
1248   XCTAssertNotNil(dict3);
1249   GPBUInt64Int64Dictionary *dict4 =
1250       [[GPBUInt64Int64Dictionary alloc] initWithInt64s:kValues3
1251                                                forKeys:kKeys1
1252                                                  count:GPBARRAYSIZE(kValues3)];
1253   XCTAssertNotNil(dict4);
1255   // 1/1Prime should be different objects, but equal.
1256   XCTAssertNotEqual(dict1, dict1prime);
1257   XCTAssertEqualObjects(dict1, dict1prime);
1258   // Equal, so they must have same hash.
1259   XCTAssertEqual([dict1 hash], [dict1prime hash]);
1261   // 2 is same keys, different values; not equal.
1262   XCTAssertNotEqualObjects(dict1, dict2);
1264   // 3 is different keys, same values; not equal.
1265   XCTAssertNotEqualObjects(dict1, dict3);
1267   // 4 extra pair; not equal
1268   XCTAssertNotEqualObjects(dict1, dict4);
1270   [dict1 release];
1271   [dict1prime release];
1272   [dict2 release];
1273   [dict3 release];
1274   [dict4 release];
1277 - (void)testCopy {
1278   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
1279   const int64_t kValues[] = { 400, 401, 402, 403 };
1280   GPBUInt64Int64Dictionary *dict =
1281       [[GPBUInt64Int64Dictionary alloc] initWithInt64s:kValues
1282                                                forKeys:kKeys
1283                                                  count:GPBARRAYSIZE(kValues)];
1284   XCTAssertNotNil(dict);
1286   GPBUInt64Int64Dictionary *dict2 = [dict copy];
1287   XCTAssertNotNil(dict2);
1289   // Should be new object but equal.
1290   XCTAssertNotEqual(dict, dict2);
1291   XCTAssertEqualObjects(dict, dict2);
1292   XCTAssertTrue([dict2 isKindOfClass:[GPBUInt64Int64Dictionary class]]);
1294   [dict2 release];
1295   [dict release];
1298 - (void)testDictionaryFromDictionary {
1299   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
1300   const int64_t kValues[] = { 400, 401, 402, 403 };
1301   GPBUInt64Int64Dictionary *dict =
1302       [[GPBUInt64Int64Dictionary alloc] initWithInt64s:kValues
1303                                                forKeys:kKeys
1304                                                  count:GPBARRAYSIZE(kValues)];
1305   XCTAssertNotNil(dict);
1307   GPBUInt64Int64Dictionary *dict2 =
1308       [[GPBUInt64Int64Dictionary alloc] initWithDictionary:dict];
1309   XCTAssertNotNil(dict2);
1311   // Should be new pointer, but equal objects.
1312   XCTAssertNotEqual(dict, dict2);
1313   XCTAssertEqualObjects(dict, dict2);
1314   [dict2 release];
1315   [dict release];
1318 - (void)testAdds {
1319   GPBUInt64Int64Dictionary *dict = [[GPBUInt64Int64Dictionary alloc] init];
1320   XCTAssertNotNil(dict);
1322   XCTAssertEqual(dict.count, 0U);
1323   [dict setInt64:400 forKey:31ULL];
1324   XCTAssertEqual(dict.count, 1U);
1326   const uint64_t kKeys[] = { 32ULL, 33ULL, 34ULL };
1327   const int64_t kValues[] = { 401, 402, 403 };
1328   GPBUInt64Int64Dictionary *dict2 =
1329       [[GPBUInt64Int64Dictionary alloc] initWithInt64s:kValues
1330                                                forKeys:kKeys
1331                                                  count:GPBARRAYSIZE(kValues)];
1332   XCTAssertNotNil(dict2);
1333   [dict addEntriesFromDictionary:dict2];
1334   XCTAssertEqual(dict.count, 4U);
1336   int64_t value;
1337   XCTAssertTrue([dict getInt64:NULL forKey:31ULL]);
1338   XCTAssertTrue([dict getInt64:&value forKey:31ULL]);
1339   XCTAssertEqual(value, 400);
1340   XCTAssertTrue([dict getInt64:NULL forKey:32ULL]);
1341   XCTAssertTrue([dict getInt64:&value forKey:32ULL]);
1342   XCTAssertEqual(value, 401);
1343   XCTAssertTrue([dict getInt64:NULL forKey:33ULL]);
1344   XCTAssertTrue([dict getInt64:&value forKey:33ULL]);
1345   XCTAssertEqual(value, 402);
1346   XCTAssertTrue([dict getInt64:NULL forKey:34ULL]);
1347   XCTAssertTrue([dict getInt64:&value forKey:34ULL]);
1348   XCTAssertEqual(value, 403);
1349   [dict2 release];
1350   [dict release];
1353 - (void)testRemove {
1354   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
1355   const int64_t kValues[] = { 400, 401, 402, 403 };
1356   GPBUInt64Int64Dictionary *dict =
1357       [[GPBUInt64Int64Dictionary alloc] initWithInt64s:kValues
1358                                                forKeys:kKeys
1359                                                  count:GPBARRAYSIZE(kValues)];
1360   XCTAssertNotNil(dict);
1361   XCTAssertEqual(dict.count, 4U);
1363   [dict removeInt64ForKey:32ULL];
1364   XCTAssertEqual(dict.count, 3U);
1365   int64_t value;
1366   XCTAssertTrue([dict getInt64:NULL forKey:31ULL]);
1367   XCTAssertTrue([dict getInt64:&value forKey:31ULL]);
1368   XCTAssertEqual(value, 400);
1369   XCTAssertFalse([dict getInt64:NULL forKey:32ULL]);
1370   XCTAssertTrue([dict getInt64:NULL forKey:33ULL]);
1371   XCTAssertTrue([dict getInt64:&value forKey:33ULL]);
1372   XCTAssertEqual(value, 402);
1373   XCTAssertTrue([dict getInt64:NULL forKey:34ULL]);
1374   XCTAssertTrue([dict getInt64:&value forKey:34ULL]);
1375   XCTAssertEqual(value, 403);
1377   // Remove again does nothing.
1378   [dict removeInt64ForKey:32ULL];
1379   XCTAssertEqual(dict.count, 3U);
1380   XCTAssertTrue([dict getInt64:NULL forKey:31ULL]);
1381   XCTAssertTrue([dict getInt64:&value forKey:31ULL]);
1382   XCTAssertEqual(value, 400);
1383   XCTAssertFalse([dict getInt64:NULL forKey:32ULL]);
1384   XCTAssertTrue([dict getInt64:NULL forKey:33ULL]);
1385   XCTAssertTrue([dict getInt64:&value forKey:33ULL]);
1386   XCTAssertEqual(value, 402);
1387   XCTAssertTrue([dict getInt64:NULL forKey:34ULL]);
1388   XCTAssertTrue([dict getInt64:&value forKey:34ULL]);
1389   XCTAssertEqual(value, 403);
1391   [dict removeInt64ForKey:34ULL];
1392   XCTAssertEqual(dict.count, 2U);
1393   XCTAssertTrue([dict getInt64:NULL forKey:31ULL]);
1394   XCTAssertTrue([dict getInt64:&value forKey:31ULL]);
1395   XCTAssertEqual(value, 400);
1396   XCTAssertFalse([dict getInt64:NULL forKey:32ULL]);
1397   XCTAssertTrue([dict getInt64:NULL forKey:33ULL]);
1398   XCTAssertTrue([dict getInt64:&value forKey:33ULL]);
1399   XCTAssertEqual(value, 402);
1400   XCTAssertFalse([dict getInt64:NULL forKey:34ULL]);
1402   [dict removeAll];
1403   XCTAssertEqual(dict.count, 0U);
1404   XCTAssertFalse([dict getInt64:NULL forKey:31ULL]);
1405   XCTAssertFalse([dict getInt64:NULL forKey:32ULL]);
1406   XCTAssertFalse([dict getInt64:NULL forKey:33ULL]);
1407   XCTAssertFalse([dict getInt64:NULL forKey:34ULL]);
1408   [dict release];
1411 - (void)testInplaceMutation {
1412   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
1413   const int64_t kValues[] = { 400, 401, 402, 403 };
1414   GPBUInt64Int64Dictionary *dict =
1415       [[GPBUInt64Int64Dictionary alloc] initWithInt64s:kValues
1416                                                forKeys:kKeys
1417                                                  count:GPBARRAYSIZE(kValues)];
1418   XCTAssertNotNil(dict);
1419   XCTAssertEqual(dict.count, 4U);
1420   int64_t value;
1421   XCTAssertTrue([dict getInt64:NULL forKey:31ULL]);
1422   XCTAssertTrue([dict getInt64:&value forKey:31ULL]);
1423   XCTAssertEqual(value, 400);
1424   XCTAssertTrue([dict getInt64:NULL forKey:32ULL]);
1425   XCTAssertTrue([dict getInt64:&value forKey:32ULL]);
1426   XCTAssertEqual(value, 401);
1427   XCTAssertTrue([dict getInt64:NULL forKey:33ULL]);
1428   XCTAssertTrue([dict getInt64:&value forKey:33ULL]);
1429   XCTAssertEqual(value, 402);
1430   XCTAssertTrue([dict getInt64:NULL forKey:34ULL]);
1431   XCTAssertTrue([dict getInt64:&value forKey:34ULL]);
1432   XCTAssertEqual(value, 403);
1434   [dict setInt64:403 forKey:31ULL];
1435   XCTAssertEqual(dict.count, 4U);
1436   XCTAssertTrue([dict getInt64:NULL forKey:31ULL]);
1437   XCTAssertTrue([dict getInt64:&value forKey:31ULL]);
1438   XCTAssertEqual(value, 403);
1439   XCTAssertTrue([dict getInt64:NULL forKey:32ULL]);
1440   XCTAssertTrue([dict getInt64:&value forKey:32ULL]);
1441   XCTAssertEqual(value, 401);
1442   XCTAssertTrue([dict getInt64:NULL forKey:33ULL]);
1443   XCTAssertTrue([dict getInt64:&value forKey:33ULL]);
1444   XCTAssertEqual(value, 402);
1445   XCTAssertTrue([dict getInt64:NULL forKey:34ULL]);
1446   XCTAssertTrue([dict getInt64:&value forKey:34ULL]);
1447   XCTAssertEqual(value, 403);
1449   [dict setInt64:401 forKey:34ULL];
1450   XCTAssertEqual(dict.count, 4U);
1451   XCTAssertTrue([dict getInt64:NULL forKey:31ULL]);
1452   XCTAssertTrue([dict getInt64:&value forKey:31ULL]);
1453   XCTAssertEqual(value, 403);
1454   XCTAssertTrue([dict getInt64:NULL forKey:32ULL]);
1455   XCTAssertTrue([dict getInt64:&value forKey:32ULL]);
1456   XCTAssertEqual(value, 401);
1457   XCTAssertTrue([dict getInt64:NULL forKey:33ULL]);
1458   XCTAssertTrue([dict getInt64:&value forKey:33ULL]);
1459   XCTAssertEqual(value, 402);
1460   XCTAssertTrue([dict getInt64:NULL forKey:34ULL]);
1461   XCTAssertTrue([dict getInt64:&value forKey:34ULL]);
1462   XCTAssertEqual(value, 401);
1464   const uint64_t kKeys2[] = { 32ULL, 33ULL };
1465   const int64_t kValues2[] = { 402, 400 };
1466   GPBUInt64Int64Dictionary *dict2 =
1467       [[GPBUInt64Int64Dictionary alloc] initWithInt64s:kValues2
1468                                                forKeys:kKeys2
1469                                                  count:GPBARRAYSIZE(kValues2)];
1470   XCTAssertNotNil(dict2);
1471   [dict addEntriesFromDictionary:dict2];
1472   XCTAssertEqual(dict.count, 4U);
1473   XCTAssertTrue([dict getInt64:NULL forKey:31ULL]);
1474   XCTAssertTrue([dict getInt64:&value forKey:31ULL]);
1475   XCTAssertEqual(value, 403);
1476   XCTAssertTrue([dict getInt64:NULL forKey:32ULL]);
1477   XCTAssertTrue([dict getInt64:&value forKey:32ULL]);
1478   XCTAssertEqual(value, 402);
1479   XCTAssertTrue([dict getInt64:NULL forKey:33ULL]);
1480   XCTAssertTrue([dict getInt64:&value forKey:33ULL]);
1481   XCTAssertEqual(value, 400);
1482   XCTAssertTrue([dict getInt64:NULL forKey:34ULL]);
1483   XCTAssertTrue([dict getInt64:&value forKey:34ULL]);
1484   XCTAssertEqual(value, 401);
1486   [dict2 release];
1487   [dict release];
1490 @end
1492 #pragma mark - UInt64 -> Bool
1494 @interface GPBUInt64BoolDictionaryTests : XCTestCase
1495 @end
1497 @implementation GPBUInt64BoolDictionaryTests
1499 - (void)testEmpty {
1500   GPBUInt64BoolDictionary *dict = [[GPBUInt64BoolDictionary alloc] init];
1501   XCTAssertNotNil(dict);
1502   XCTAssertEqual(dict.count, 0U);
1503   XCTAssertFalse([dict getBool:NULL forKey:31ULL]);
1504   [dict enumerateKeysAndBoolsUsingBlock:^(__unused uint64_t aKey, __unused BOOL aValue, __unused BOOL *stop) {
1505     XCTFail(@"Shouldn't get here!");
1506   }];
1507   [dict release];
1510 - (void)testOne {
1511   GPBUInt64BoolDictionary *dict = [[GPBUInt64BoolDictionary alloc] init];
1512   [dict setBool:YES forKey:31ULL];
1513   XCTAssertNotNil(dict);
1514   XCTAssertEqual(dict.count, 1U);
1515   BOOL value;
1516   XCTAssertTrue([dict getBool:NULL forKey:31ULL]);
1517   XCTAssertTrue([dict getBool:&value forKey:31ULL]);
1518   XCTAssertEqual(value, YES);
1519   XCTAssertFalse([dict getBool:NULL forKey:32ULL]);
1520   [dict enumerateKeysAndBoolsUsingBlock:^(uint64_t aKey, BOOL aValue, BOOL *stop) {
1521     XCTAssertEqual(aKey, 31ULL);
1522     XCTAssertEqual(aValue, YES);
1523     XCTAssertNotEqual(stop, NULL);
1524   }];
1525   [dict release];
1528 - (void)testBasics {
1529   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL };
1530   const BOOL kValues[] = { YES, YES, NO };
1531   GPBUInt64BoolDictionary *dict =
1532       [[GPBUInt64BoolDictionary alloc] initWithBools:kValues
1533                                              forKeys:kKeys
1534                                                count:GPBARRAYSIZE(kValues)];
1535   XCTAssertNotNil(dict);
1536   XCTAssertEqual(dict.count, 3U);
1537   BOOL value;
1538   XCTAssertTrue([dict getBool:NULL forKey:31ULL]);
1539   XCTAssertTrue([dict getBool:&value forKey:31ULL]);
1540   XCTAssertEqual(value, YES);
1541   XCTAssertTrue([dict getBool:NULL forKey:32ULL]);
1542   XCTAssertTrue([dict getBool:&value forKey:32ULL]);
1543   XCTAssertEqual(value, YES);
1544   XCTAssertTrue([dict getBool:NULL forKey:33ULL]);
1545   XCTAssertTrue([dict getBool:&value forKey:33ULL]);
1546   XCTAssertEqual(value, NO);
1547   XCTAssertFalse([dict getBool:NULL forKey:34ULL]);
1549   __block NSUInteger idx = 0;
1550   uint64_t *seenKeys = malloc(3 * sizeof(uint64_t));
1551   BOOL *seenValues = malloc(3 * sizeof(BOOL));
1552   [dict enumerateKeysAndBoolsUsingBlock:^(uint64_t aKey, BOOL aValue, BOOL *stop) {
1553     XCTAssertLessThan(idx, 3U);
1554     seenKeys[idx] = aKey;
1555     seenValues[idx] = aValue;
1556     XCTAssertNotEqual(stop, NULL);
1557     ++idx;
1558   }];
1559   for (int i = 0; i < 3; ++i) {
1560     BOOL foundKey = NO;
1561     for (int j = 0; (j < 3) && !foundKey; ++j) {
1562       if (kKeys[i] == seenKeys[j]) {
1563         foundKey = YES;
1564         XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
1565       }
1566     }
1567     XCTAssertTrue(foundKey, @"i = %d", i);
1568   }
1569   free(seenKeys);
1570   free(seenValues);
1572   // Stopping the enumeration.
1573   idx = 0;
1574   [dict enumerateKeysAndBoolsUsingBlock:^(__unused uint64_t aKey, __unused BOOL aValue, BOOL *stop) {
1575     if (idx == 1) *stop = YES;
1576     XCTAssertNotEqual(idx, 2U);
1577     ++idx;
1578   }];
1579   [dict release];
1582 - (void)testEquality {
1583   const uint64_t kKeys1[] = { 31ULL, 32ULL, 33ULL, 34ULL };
1584   const uint64_t kKeys2[] = { 32ULL, 31ULL, 34ULL };
1585   const BOOL kValues1[] = { YES, YES, NO };
1586   const BOOL kValues2[] = { YES, NO, NO };
1587   const BOOL kValues3[] = { YES, YES, NO, NO };
1588   GPBUInt64BoolDictionary *dict1 =
1589       [[GPBUInt64BoolDictionary alloc] initWithBools:kValues1
1590                                              forKeys:kKeys1
1591                                                count:GPBARRAYSIZE(kValues1)];
1592   XCTAssertNotNil(dict1);
1593   GPBUInt64BoolDictionary *dict1prime =
1594       [[GPBUInt64BoolDictionary alloc] initWithBools:kValues1
1595                                              forKeys:kKeys1
1596                                                count:GPBARRAYSIZE(kValues1)];
1597   XCTAssertNotNil(dict1prime);
1598   GPBUInt64BoolDictionary *dict2 =
1599       [[GPBUInt64BoolDictionary alloc] initWithBools:kValues2
1600                                              forKeys:kKeys1
1601                                                count:GPBARRAYSIZE(kValues2)];
1602   XCTAssertNotNil(dict2);
1603   GPBUInt64BoolDictionary *dict3 =
1604       [[GPBUInt64BoolDictionary alloc] initWithBools:kValues1
1605                                              forKeys:kKeys2
1606                                                count:GPBARRAYSIZE(kValues1)];
1607   XCTAssertNotNil(dict3);
1608   GPBUInt64BoolDictionary *dict4 =
1609       [[GPBUInt64BoolDictionary alloc] initWithBools:kValues3
1610                                              forKeys:kKeys1
1611                                                count:GPBARRAYSIZE(kValues3)];
1612   XCTAssertNotNil(dict4);
1614   // 1/1Prime should be different objects, but equal.
1615   XCTAssertNotEqual(dict1, dict1prime);
1616   XCTAssertEqualObjects(dict1, dict1prime);
1617   // Equal, so they must have same hash.
1618   XCTAssertEqual([dict1 hash], [dict1prime hash]);
1620   // 2 is same keys, different values; not equal.
1621   XCTAssertNotEqualObjects(dict1, dict2);
1623   // 3 is different keys, same values; not equal.
1624   XCTAssertNotEqualObjects(dict1, dict3);
1626   // 4 extra pair; not equal
1627   XCTAssertNotEqualObjects(dict1, dict4);
1629   [dict1 release];
1630   [dict1prime release];
1631   [dict2 release];
1632   [dict3 release];
1633   [dict4 release];
1636 - (void)testCopy {
1637   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
1638   const BOOL kValues[] = { YES, YES, NO, NO };
1639   GPBUInt64BoolDictionary *dict =
1640       [[GPBUInt64BoolDictionary alloc] initWithBools:kValues
1641                                              forKeys:kKeys
1642                                                count:GPBARRAYSIZE(kValues)];
1643   XCTAssertNotNil(dict);
1645   GPBUInt64BoolDictionary *dict2 = [dict copy];
1646   XCTAssertNotNil(dict2);
1648   // Should be new object but equal.
1649   XCTAssertNotEqual(dict, dict2);
1650   XCTAssertEqualObjects(dict, dict2);
1651   XCTAssertTrue([dict2 isKindOfClass:[GPBUInt64BoolDictionary class]]);
1653   [dict2 release];
1654   [dict release];
1657 - (void)testDictionaryFromDictionary {
1658   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
1659   const BOOL kValues[] = { YES, YES, NO, NO };
1660   GPBUInt64BoolDictionary *dict =
1661       [[GPBUInt64BoolDictionary alloc] initWithBools:kValues
1662                                              forKeys:kKeys
1663                                                count:GPBARRAYSIZE(kValues)];
1664   XCTAssertNotNil(dict);
1666   GPBUInt64BoolDictionary *dict2 =
1667       [[GPBUInt64BoolDictionary alloc] initWithDictionary:dict];
1668   XCTAssertNotNil(dict2);
1670   // Should be new pointer, but equal objects.
1671   XCTAssertNotEqual(dict, dict2);
1672   XCTAssertEqualObjects(dict, dict2);
1673   [dict2 release];
1674   [dict release];
1677 - (void)testAdds {
1678   GPBUInt64BoolDictionary *dict = [[GPBUInt64BoolDictionary alloc] init];
1679   XCTAssertNotNil(dict);
1681   XCTAssertEqual(dict.count, 0U);
1682   [dict setBool:YES forKey:31ULL];
1683   XCTAssertEqual(dict.count, 1U);
1685   const uint64_t kKeys[] = { 32ULL, 33ULL, 34ULL };
1686   const BOOL kValues[] = { YES, NO, NO };
1687   GPBUInt64BoolDictionary *dict2 =
1688       [[GPBUInt64BoolDictionary alloc] initWithBools:kValues
1689                                              forKeys:kKeys
1690                                                count:GPBARRAYSIZE(kValues)];
1691   XCTAssertNotNil(dict2);
1692   [dict addEntriesFromDictionary:dict2];
1693   XCTAssertEqual(dict.count, 4U);
1695   BOOL value;
1696   XCTAssertTrue([dict getBool:NULL forKey:31ULL]);
1697   XCTAssertTrue([dict getBool:&value forKey:31ULL]);
1698   XCTAssertEqual(value, YES);
1699   XCTAssertTrue([dict getBool:NULL forKey:32ULL]);
1700   XCTAssertTrue([dict getBool:&value forKey:32ULL]);
1701   XCTAssertEqual(value, YES);
1702   XCTAssertTrue([dict getBool:NULL forKey:33ULL]);
1703   XCTAssertTrue([dict getBool:&value forKey:33ULL]);
1704   XCTAssertEqual(value, NO);
1705   XCTAssertTrue([dict getBool:NULL forKey:34ULL]);
1706   XCTAssertTrue([dict getBool:&value forKey:34ULL]);
1707   XCTAssertEqual(value, NO);
1708   [dict2 release];
1709   [dict release];
1712 - (void)testRemove {
1713   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
1714   const BOOL kValues[] = { YES, YES, NO, NO };
1715   GPBUInt64BoolDictionary *dict =
1716       [[GPBUInt64BoolDictionary alloc] initWithBools:kValues
1717                                              forKeys:kKeys
1718                                                count:GPBARRAYSIZE(kValues)];
1719   XCTAssertNotNil(dict);
1720   XCTAssertEqual(dict.count, 4U);
1722   [dict removeBoolForKey:32ULL];
1723   XCTAssertEqual(dict.count, 3U);
1724   BOOL value;
1725   XCTAssertTrue([dict getBool:NULL forKey:31ULL]);
1726   XCTAssertTrue([dict getBool:&value forKey:31ULL]);
1727   XCTAssertEqual(value, YES);
1728   XCTAssertFalse([dict getBool:NULL forKey:32ULL]);
1729   XCTAssertTrue([dict getBool:NULL forKey:33ULL]);
1730   XCTAssertTrue([dict getBool:&value forKey:33ULL]);
1731   XCTAssertEqual(value, NO);
1732   XCTAssertTrue([dict getBool:NULL forKey:34ULL]);
1733   XCTAssertTrue([dict getBool:&value forKey:34ULL]);
1734   XCTAssertEqual(value, NO);
1736   // Remove again does nothing.
1737   [dict removeBoolForKey:32ULL];
1738   XCTAssertEqual(dict.count, 3U);
1739   XCTAssertTrue([dict getBool:NULL forKey:31ULL]);
1740   XCTAssertTrue([dict getBool:&value forKey:31ULL]);
1741   XCTAssertEqual(value, YES);
1742   XCTAssertFalse([dict getBool:NULL forKey:32ULL]);
1743   XCTAssertTrue([dict getBool:NULL forKey:33ULL]);
1744   XCTAssertTrue([dict getBool:&value forKey:33ULL]);
1745   XCTAssertEqual(value, NO);
1746   XCTAssertTrue([dict getBool:NULL forKey:34ULL]);
1747   XCTAssertTrue([dict getBool:&value forKey:34ULL]);
1748   XCTAssertEqual(value, NO);
1750   [dict removeBoolForKey:34ULL];
1751   XCTAssertEqual(dict.count, 2U);
1752   XCTAssertTrue([dict getBool:NULL forKey:31ULL]);
1753   XCTAssertTrue([dict getBool:&value forKey:31ULL]);
1754   XCTAssertEqual(value, YES);
1755   XCTAssertFalse([dict getBool:NULL forKey:32ULL]);
1756   XCTAssertTrue([dict getBool:NULL forKey:33ULL]);
1757   XCTAssertTrue([dict getBool:&value forKey:33ULL]);
1758   XCTAssertEqual(value, NO);
1759   XCTAssertFalse([dict getBool:NULL forKey:34ULL]);
1761   [dict removeAll];
1762   XCTAssertEqual(dict.count, 0U);
1763   XCTAssertFalse([dict getBool:NULL forKey:31ULL]);
1764   XCTAssertFalse([dict getBool:NULL forKey:32ULL]);
1765   XCTAssertFalse([dict getBool:NULL forKey:33ULL]);
1766   XCTAssertFalse([dict getBool:NULL forKey:34ULL]);
1767   [dict release];
1770 - (void)testInplaceMutation {
1771   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
1772   const BOOL kValues[] = { YES, YES, NO, NO };
1773   GPBUInt64BoolDictionary *dict =
1774       [[GPBUInt64BoolDictionary alloc] initWithBools:kValues
1775                                              forKeys:kKeys
1776                                                count:GPBARRAYSIZE(kValues)];
1777   XCTAssertNotNil(dict);
1778   XCTAssertEqual(dict.count, 4U);
1779   BOOL value;
1780   XCTAssertTrue([dict getBool:NULL forKey:31ULL]);
1781   XCTAssertTrue([dict getBool:&value forKey:31ULL]);
1782   XCTAssertEqual(value, YES);
1783   XCTAssertTrue([dict getBool:NULL forKey:32ULL]);
1784   XCTAssertTrue([dict getBool:&value forKey:32ULL]);
1785   XCTAssertEqual(value, YES);
1786   XCTAssertTrue([dict getBool:NULL forKey:33ULL]);
1787   XCTAssertTrue([dict getBool:&value forKey:33ULL]);
1788   XCTAssertEqual(value, NO);
1789   XCTAssertTrue([dict getBool:NULL forKey:34ULL]);
1790   XCTAssertTrue([dict getBool:&value forKey:34ULL]);
1791   XCTAssertEqual(value, NO);
1793   [dict setBool:NO forKey:31ULL];
1794   XCTAssertEqual(dict.count, 4U);
1795   XCTAssertTrue([dict getBool:NULL forKey:31ULL]);
1796   XCTAssertTrue([dict getBool:&value forKey:31ULL]);
1797   XCTAssertEqual(value, NO);
1798   XCTAssertTrue([dict getBool:NULL forKey:32ULL]);
1799   XCTAssertTrue([dict getBool:&value forKey:32ULL]);
1800   XCTAssertEqual(value, YES);
1801   XCTAssertTrue([dict getBool:NULL forKey:33ULL]);
1802   XCTAssertTrue([dict getBool:&value forKey:33ULL]);
1803   XCTAssertEqual(value, NO);
1804   XCTAssertTrue([dict getBool:NULL forKey:34ULL]);
1805   XCTAssertTrue([dict getBool:&value forKey:34ULL]);
1806   XCTAssertEqual(value, NO);
1808   [dict setBool:YES forKey:34ULL];
1809   XCTAssertEqual(dict.count, 4U);
1810   XCTAssertTrue([dict getBool:NULL forKey:31ULL]);
1811   XCTAssertTrue([dict getBool:&value forKey:31ULL]);
1812   XCTAssertEqual(value, NO);
1813   XCTAssertTrue([dict getBool:NULL forKey:32ULL]);
1814   XCTAssertTrue([dict getBool:&value forKey:32ULL]);
1815   XCTAssertEqual(value, YES);
1816   XCTAssertTrue([dict getBool:NULL forKey:33ULL]);
1817   XCTAssertTrue([dict getBool:&value forKey:33ULL]);
1818   XCTAssertEqual(value, NO);
1819   XCTAssertTrue([dict getBool:NULL forKey:34ULL]);
1820   XCTAssertTrue([dict getBool:&value forKey:34ULL]);
1821   XCTAssertEqual(value, YES);
1823   const uint64_t kKeys2[] = { 32ULL, 33ULL };
1824   const BOOL kValues2[] = { NO, YES };
1825   GPBUInt64BoolDictionary *dict2 =
1826       [[GPBUInt64BoolDictionary alloc] initWithBools:kValues2
1827                                              forKeys:kKeys2
1828                                                count:GPBARRAYSIZE(kValues2)];
1829   XCTAssertNotNil(dict2);
1830   [dict addEntriesFromDictionary:dict2];
1831   XCTAssertEqual(dict.count, 4U);
1832   XCTAssertTrue([dict getBool:NULL forKey:31ULL]);
1833   XCTAssertTrue([dict getBool:&value forKey:31ULL]);
1834   XCTAssertEqual(value, NO);
1835   XCTAssertTrue([dict getBool:NULL forKey:32ULL]);
1836   XCTAssertTrue([dict getBool:&value forKey:32ULL]);
1837   XCTAssertEqual(value, NO);
1838   XCTAssertTrue([dict getBool:NULL forKey:33ULL]);
1839   XCTAssertTrue([dict getBool:&value forKey:33ULL]);
1840   XCTAssertEqual(value, YES);
1841   XCTAssertTrue([dict getBool:NULL forKey:34ULL]);
1842   XCTAssertTrue([dict getBool:&value forKey:34ULL]);
1843   XCTAssertEqual(value, YES);
1845   [dict2 release];
1846   [dict release];
1849 @end
1851 #pragma mark - UInt64 -> Float
1853 @interface GPBUInt64FloatDictionaryTests : XCTestCase
1854 @end
1856 @implementation GPBUInt64FloatDictionaryTests
1858 - (void)testEmpty {
1859   GPBUInt64FloatDictionary *dict = [[GPBUInt64FloatDictionary alloc] init];
1860   XCTAssertNotNil(dict);
1861   XCTAssertEqual(dict.count, 0U);
1862   XCTAssertFalse([dict getFloat:NULL forKey:31ULL]);
1863   [dict enumerateKeysAndFloatsUsingBlock:^(__unused uint64_t aKey, __unused float aValue, __unused BOOL *stop) {
1864     XCTFail(@"Shouldn't get here!");
1865   }];
1866   [dict release];
1869 - (void)testOne {
1870   GPBUInt64FloatDictionary *dict = [[GPBUInt64FloatDictionary alloc] init];
1871   [dict setFloat:500.f forKey:31ULL];
1872   XCTAssertNotNil(dict);
1873   XCTAssertEqual(dict.count, 1U);
1874   float value;
1875   XCTAssertTrue([dict getFloat:NULL forKey:31ULL]);
1876   XCTAssertTrue([dict getFloat:&value forKey:31ULL]);
1877   XCTAssertEqual(value, 500.f);
1878   XCTAssertFalse([dict getFloat:NULL forKey:32ULL]);
1879   [dict enumerateKeysAndFloatsUsingBlock:^(uint64_t aKey, float aValue, BOOL *stop) {
1880     XCTAssertEqual(aKey, 31ULL);
1881     XCTAssertEqual(aValue, 500.f);
1882     XCTAssertNotEqual(stop, NULL);
1883   }];
1884   [dict release];
1887 - (void)testBasics {
1888   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL };
1889   const float kValues[] = { 500.f, 501.f, 502.f };
1890   GPBUInt64FloatDictionary *dict =
1891       [[GPBUInt64FloatDictionary alloc] initWithFloats:kValues
1892                                                forKeys:kKeys
1893                                                  count:GPBARRAYSIZE(kValues)];
1894   XCTAssertNotNil(dict);
1895   XCTAssertEqual(dict.count, 3U);
1896   float value;
1897   XCTAssertTrue([dict getFloat:NULL forKey:31ULL]);
1898   XCTAssertTrue([dict getFloat:&value forKey:31ULL]);
1899   XCTAssertEqual(value, 500.f);
1900   XCTAssertTrue([dict getFloat:NULL forKey:32ULL]);
1901   XCTAssertTrue([dict getFloat:&value forKey:32ULL]);
1902   XCTAssertEqual(value, 501.f);
1903   XCTAssertTrue([dict getFloat:NULL forKey:33ULL]);
1904   XCTAssertTrue([dict getFloat:&value forKey:33ULL]);
1905   XCTAssertEqual(value, 502.f);
1906   XCTAssertFalse([dict getFloat:NULL forKey:34ULL]);
1908   __block NSUInteger idx = 0;
1909   uint64_t *seenKeys = malloc(3 * sizeof(uint64_t));
1910   float *seenValues = malloc(3 * sizeof(float));
1911   [dict enumerateKeysAndFloatsUsingBlock:^(uint64_t aKey, float aValue, BOOL *stop) {
1912     XCTAssertLessThan(idx, 3U);
1913     seenKeys[idx] = aKey;
1914     seenValues[idx] = aValue;
1915     XCTAssertNotEqual(stop, NULL);
1916     ++idx;
1917   }];
1918   for (int i = 0; i < 3; ++i) {
1919     BOOL foundKey = NO;
1920     for (int j = 0; (j < 3) && !foundKey; ++j) {
1921       if (kKeys[i] == seenKeys[j]) {
1922         foundKey = YES;
1923         XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
1924       }
1925     }
1926     XCTAssertTrue(foundKey, @"i = %d", i);
1927   }
1928   free(seenKeys);
1929   free(seenValues);
1931   // Stopping the enumeration.
1932   idx = 0;
1933   [dict enumerateKeysAndFloatsUsingBlock:^(__unused uint64_t aKey, __unused float aValue, BOOL *stop) {
1934     if (idx == 1) *stop = YES;
1935     XCTAssertNotEqual(idx, 2U);
1936     ++idx;
1937   }];
1938   [dict release];
1941 - (void)testEquality {
1942   const uint64_t kKeys1[] = { 31ULL, 32ULL, 33ULL, 34ULL };
1943   const uint64_t kKeys2[] = { 32ULL, 31ULL, 34ULL };
1944   const float kValues1[] = { 500.f, 501.f, 502.f };
1945   const float kValues2[] = { 500.f, 503.f, 502.f };
1946   const float kValues3[] = { 500.f, 501.f, 502.f, 503.f };
1947   GPBUInt64FloatDictionary *dict1 =
1948       [[GPBUInt64FloatDictionary alloc] initWithFloats:kValues1
1949                                                forKeys:kKeys1
1950                                                  count:GPBARRAYSIZE(kValues1)];
1951   XCTAssertNotNil(dict1);
1952   GPBUInt64FloatDictionary *dict1prime =
1953       [[GPBUInt64FloatDictionary alloc] initWithFloats:kValues1
1954                                                forKeys:kKeys1
1955                                                  count:GPBARRAYSIZE(kValues1)];
1956   XCTAssertNotNil(dict1prime);
1957   GPBUInt64FloatDictionary *dict2 =
1958       [[GPBUInt64FloatDictionary alloc] initWithFloats:kValues2
1959                                                forKeys:kKeys1
1960                                                  count:GPBARRAYSIZE(kValues2)];
1961   XCTAssertNotNil(dict2);
1962   GPBUInt64FloatDictionary *dict3 =
1963       [[GPBUInt64FloatDictionary alloc] initWithFloats:kValues1
1964                                                forKeys:kKeys2
1965                                                  count:GPBARRAYSIZE(kValues1)];
1966   XCTAssertNotNil(dict3);
1967   GPBUInt64FloatDictionary *dict4 =
1968       [[GPBUInt64FloatDictionary alloc] initWithFloats:kValues3
1969                                                forKeys:kKeys1
1970                                                  count:GPBARRAYSIZE(kValues3)];
1971   XCTAssertNotNil(dict4);
1973   // 1/1Prime should be different objects, but equal.
1974   XCTAssertNotEqual(dict1, dict1prime);
1975   XCTAssertEqualObjects(dict1, dict1prime);
1976   // Equal, so they must have same hash.
1977   XCTAssertEqual([dict1 hash], [dict1prime hash]);
1979   // 2 is same keys, different values; not equal.
1980   XCTAssertNotEqualObjects(dict1, dict2);
1982   // 3 is different keys, same values; not equal.
1983   XCTAssertNotEqualObjects(dict1, dict3);
1985   // 4 extra pair; not equal
1986   XCTAssertNotEqualObjects(dict1, dict4);
1988   [dict1 release];
1989   [dict1prime release];
1990   [dict2 release];
1991   [dict3 release];
1992   [dict4 release];
1995 - (void)testCopy {
1996   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
1997   const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
1998   GPBUInt64FloatDictionary *dict =
1999       [[GPBUInt64FloatDictionary alloc] initWithFloats:kValues
2000                                                forKeys:kKeys
2001                                                  count:GPBARRAYSIZE(kValues)];
2002   XCTAssertNotNil(dict);
2004   GPBUInt64FloatDictionary *dict2 = [dict copy];
2005   XCTAssertNotNil(dict2);
2007   // Should be new object but equal.
2008   XCTAssertNotEqual(dict, dict2);
2009   XCTAssertEqualObjects(dict, dict2);
2010   XCTAssertTrue([dict2 isKindOfClass:[GPBUInt64FloatDictionary class]]);
2012   [dict2 release];
2013   [dict release];
2016 - (void)testDictionaryFromDictionary {
2017   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
2018   const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
2019   GPBUInt64FloatDictionary *dict =
2020       [[GPBUInt64FloatDictionary alloc] initWithFloats:kValues
2021                                                forKeys:kKeys
2022                                                  count:GPBARRAYSIZE(kValues)];
2023   XCTAssertNotNil(dict);
2025   GPBUInt64FloatDictionary *dict2 =
2026       [[GPBUInt64FloatDictionary alloc] initWithDictionary:dict];
2027   XCTAssertNotNil(dict2);
2029   // Should be new pointer, but equal objects.
2030   XCTAssertNotEqual(dict, dict2);
2031   XCTAssertEqualObjects(dict, dict2);
2032   [dict2 release];
2033   [dict release];
2036 - (void)testAdds {
2037   GPBUInt64FloatDictionary *dict = [[GPBUInt64FloatDictionary alloc] init];
2038   XCTAssertNotNil(dict);
2040   XCTAssertEqual(dict.count, 0U);
2041   [dict setFloat:500.f forKey:31ULL];
2042   XCTAssertEqual(dict.count, 1U);
2044   const uint64_t kKeys[] = { 32ULL, 33ULL, 34ULL };
2045   const float kValues[] = { 501.f, 502.f, 503.f };
2046   GPBUInt64FloatDictionary *dict2 =
2047       [[GPBUInt64FloatDictionary alloc] initWithFloats:kValues
2048                                                forKeys:kKeys
2049                                                  count:GPBARRAYSIZE(kValues)];
2050   XCTAssertNotNil(dict2);
2051   [dict addEntriesFromDictionary:dict2];
2052   XCTAssertEqual(dict.count, 4U);
2054   float value;
2055   XCTAssertTrue([dict getFloat:NULL forKey:31ULL]);
2056   XCTAssertTrue([dict getFloat:&value forKey:31ULL]);
2057   XCTAssertEqual(value, 500.f);
2058   XCTAssertTrue([dict getFloat:NULL forKey:32ULL]);
2059   XCTAssertTrue([dict getFloat:&value forKey:32ULL]);
2060   XCTAssertEqual(value, 501.f);
2061   XCTAssertTrue([dict getFloat:NULL forKey:33ULL]);
2062   XCTAssertTrue([dict getFloat:&value forKey:33ULL]);
2063   XCTAssertEqual(value, 502.f);
2064   XCTAssertTrue([dict getFloat:NULL forKey:34ULL]);
2065   XCTAssertTrue([dict getFloat:&value forKey:34ULL]);
2066   XCTAssertEqual(value, 503.f);
2067   [dict2 release];
2068   [dict release];
2071 - (void)testRemove {
2072   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
2073   const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
2074   GPBUInt64FloatDictionary *dict =
2075       [[GPBUInt64FloatDictionary alloc] initWithFloats:kValues
2076                                                forKeys:kKeys
2077                                                  count:GPBARRAYSIZE(kValues)];
2078   XCTAssertNotNil(dict);
2079   XCTAssertEqual(dict.count, 4U);
2081   [dict removeFloatForKey:32ULL];
2082   XCTAssertEqual(dict.count, 3U);
2083   float value;
2084   XCTAssertTrue([dict getFloat:NULL forKey:31ULL]);
2085   XCTAssertTrue([dict getFloat:&value forKey:31ULL]);
2086   XCTAssertEqual(value, 500.f);
2087   XCTAssertFalse([dict getFloat:NULL forKey:32ULL]);
2088   XCTAssertTrue([dict getFloat:NULL forKey:33ULL]);
2089   XCTAssertTrue([dict getFloat:&value forKey:33ULL]);
2090   XCTAssertEqual(value, 502.f);
2091   XCTAssertTrue([dict getFloat:NULL forKey:34ULL]);
2092   XCTAssertTrue([dict getFloat:&value forKey:34ULL]);
2093   XCTAssertEqual(value, 503.f);
2095   // Remove again does nothing.
2096   [dict removeFloatForKey:32ULL];
2097   XCTAssertEqual(dict.count, 3U);
2098   XCTAssertTrue([dict getFloat:NULL forKey:31ULL]);
2099   XCTAssertTrue([dict getFloat:&value forKey:31ULL]);
2100   XCTAssertEqual(value, 500.f);
2101   XCTAssertFalse([dict getFloat:NULL forKey:32ULL]);
2102   XCTAssertTrue([dict getFloat:NULL forKey:33ULL]);
2103   XCTAssertTrue([dict getFloat:&value forKey:33ULL]);
2104   XCTAssertEqual(value, 502.f);
2105   XCTAssertTrue([dict getFloat:NULL forKey:34ULL]);
2106   XCTAssertTrue([dict getFloat:&value forKey:34ULL]);
2107   XCTAssertEqual(value, 503.f);
2109   [dict removeFloatForKey:34ULL];
2110   XCTAssertEqual(dict.count, 2U);
2111   XCTAssertTrue([dict getFloat:NULL forKey:31ULL]);
2112   XCTAssertTrue([dict getFloat:&value forKey:31ULL]);
2113   XCTAssertEqual(value, 500.f);
2114   XCTAssertFalse([dict getFloat:NULL forKey:32ULL]);
2115   XCTAssertTrue([dict getFloat:NULL forKey:33ULL]);
2116   XCTAssertTrue([dict getFloat:&value forKey:33ULL]);
2117   XCTAssertEqual(value, 502.f);
2118   XCTAssertFalse([dict getFloat:NULL forKey:34ULL]);
2120   [dict removeAll];
2121   XCTAssertEqual(dict.count, 0U);
2122   XCTAssertFalse([dict getFloat:NULL forKey:31ULL]);
2123   XCTAssertFalse([dict getFloat:NULL forKey:32ULL]);
2124   XCTAssertFalse([dict getFloat:NULL forKey:33ULL]);
2125   XCTAssertFalse([dict getFloat:NULL forKey:34ULL]);
2126   [dict release];
2129 - (void)testInplaceMutation {
2130   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
2131   const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
2132   GPBUInt64FloatDictionary *dict =
2133       [[GPBUInt64FloatDictionary alloc] initWithFloats:kValues
2134                                                forKeys:kKeys
2135                                                  count:GPBARRAYSIZE(kValues)];
2136   XCTAssertNotNil(dict);
2137   XCTAssertEqual(dict.count, 4U);
2138   float value;
2139   XCTAssertTrue([dict getFloat:NULL forKey:31ULL]);
2140   XCTAssertTrue([dict getFloat:&value forKey:31ULL]);
2141   XCTAssertEqual(value, 500.f);
2142   XCTAssertTrue([dict getFloat:NULL forKey:32ULL]);
2143   XCTAssertTrue([dict getFloat:&value forKey:32ULL]);
2144   XCTAssertEqual(value, 501.f);
2145   XCTAssertTrue([dict getFloat:NULL forKey:33ULL]);
2146   XCTAssertTrue([dict getFloat:&value forKey:33ULL]);
2147   XCTAssertEqual(value, 502.f);
2148   XCTAssertTrue([dict getFloat:NULL forKey:34ULL]);
2149   XCTAssertTrue([dict getFloat:&value forKey:34ULL]);
2150   XCTAssertEqual(value, 503.f);
2152   [dict setFloat:503.f forKey:31ULL];
2153   XCTAssertEqual(dict.count, 4U);
2154   XCTAssertTrue([dict getFloat:NULL forKey:31ULL]);
2155   XCTAssertTrue([dict getFloat:&value forKey:31ULL]);
2156   XCTAssertEqual(value, 503.f);
2157   XCTAssertTrue([dict getFloat:NULL forKey:32ULL]);
2158   XCTAssertTrue([dict getFloat:&value forKey:32ULL]);
2159   XCTAssertEqual(value, 501.f);
2160   XCTAssertTrue([dict getFloat:NULL forKey:33ULL]);
2161   XCTAssertTrue([dict getFloat:&value forKey:33ULL]);
2162   XCTAssertEqual(value, 502.f);
2163   XCTAssertTrue([dict getFloat:NULL forKey:34ULL]);
2164   XCTAssertTrue([dict getFloat:&value forKey:34ULL]);
2165   XCTAssertEqual(value, 503.f);
2167   [dict setFloat:501.f forKey:34ULL];
2168   XCTAssertEqual(dict.count, 4U);
2169   XCTAssertTrue([dict getFloat:NULL forKey:31ULL]);
2170   XCTAssertTrue([dict getFloat:&value forKey:31ULL]);
2171   XCTAssertEqual(value, 503.f);
2172   XCTAssertTrue([dict getFloat:NULL forKey:32ULL]);
2173   XCTAssertTrue([dict getFloat:&value forKey:32ULL]);
2174   XCTAssertEqual(value, 501.f);
2175   XCTAssertTrue([dict getFloat:NULL forKey:33ULL]);
2176   XCTAssertTrue([dict getFloat:&value forKey:33ULL]);
2177   XCTAssertEqual(value, 502.f);
2178   XCTAssertTrue([dict getFloat:NULL forKey:34ULL]);
2179   XCTAssertTrue([dict getFloat:&value forKey:34ULL]);
2180   XCTAssertEqual(value, 501.f);
2182   const uint64_t kKeys2[] = { 32ULL, 33ULL };
2183   const float kValues2[] = { 502.f, 500.f };
2184   GPBUInt64FloatDictionary *dict2 =
2185       [[GPBUInt64FloatDictionary alloc] initWithFloats:kValues2
2186                                                forKeys:kKeys2
2187                                                  count:GPBARRAYSIZE(kValues2)];
2188   XCTAssertNotNil(dict2);
2189   [dict addEntriesFromDictionary:dict2];
2190   XCTAssertEqual(dict.count, 4U);
2191   XCTAssertTrue([dict getFloat:NULL forKey:31ULL]);
2192   XCTAssertTrue([dict getFloat:&value forKey:31ULL]);
2193   XCTAssertEqual(value, 503.f);
2194   XCTAssertTrue([dict getFloat:NULL forKey:32ULL]);
2195   XCTAssertTrue([dict getFloat:&value forKey:32ULL]);
2196   XCTAssertEqual(value, 502.f);
2197   XCTAssertTrue([dict getFloat:NULL forKey:33ULL]);
2198   XCTAssertTrue([dict getFloat:&value forKey:33ULL]);
2199   XCTAssertEqual(value, 500.f);
2200   XCTAssertTrue([dict getFloat:NULL forKey:34ULL]);
2201   XCTAssertTrue([dict getFloat:&value forKey:34ULL]);
2202   XCTAssertEqual(value, 501.f);
2204   [dict2 release];
2205   [dict release];
2208 @end
2210 #pragma mark - UInt64 -> Double
2212 @interface GPBUInt64DoubleDictionaryTests : XCTestCase
2213 @end
2215 @implementation GPBUInt64DoubleDictionaryTests
2217 - (void)testEmpty {
2218   GPBUInt64DoubleDictionary *dict = [[GPBUInt64DoubleDictionary alloc] init];
2219   XCTAssertNotNil(dict);
2220   XCTAssertEqual(dict.count, 0U);
2221   XCTAssertFalse([dict getDouble:NULL forKey:31ULL]);
2222   [dict enumerateKeysAndDoublesUsingBlock:^(__unused uint64_t aKey, __unused double aValue, __unused BOOL *stop) {
2223     XCTFail(@"Shouldn't get here!");
2224   }];
2225   [dict release];
2228 - (void)testOne {
2229   GPBUInt64DoubleDictionary *dict = [[GPBUInt64DoubleDictionary alloc] init];
2230   [dict setDouble:600. forKey:31ULL];
2231   XCTAssertNotNil(dict);
2232   XCTAssertEqual(dict.count, 1U);
2233   double value;
2234   XCTAssertTrue([dict getDouble:NULL forKey:31ULL]);
2235   XCTAssertTrue([dict getDouble:&value forKey:31ULL]);
2236   XCTAssertEqual(value, 600.);
2237   XCTAssertFalse([dict getDouble:NULL forKey:32ULL]);
2238   [dict enumerateKeysAndDoublesUsingBlock:^(uint64_t aKey, double aValue, BOOL *stop) {
2239     XCTAssertEqual(aKey, 31ULL);
2240     XCTAssertEqual(aValue, 600.);
2241     XCTAssertNotEqual(stop, NULL);
2242   }];
2243   [dict release];
2246 - (void)testBasics {
2247   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL };
2248   const double kValues[] = { 600., 601., 602. };
2249   GPBUInt64DoubleDictionary *dict =
2250       [[GPBUInt64DoubleDictionary alloc] initWithDoubles:kValues
2251                                                  forKeys:kKeys
2252                                                    count:GPBARRAYSIZE(kValues)];
2253   XCTAssertNotNil(dict);
2254   XCTAssertEqual(dict.count, 3U);
2255   double value;
2256   XCTAssertTrue([dict getDouble:NULL forKey:31ULL]);
2257   XCTAssertTrue([dict getDouble:&value forKey:31ULL]);
2258   XCTAssertEqual(value, 600.);
2259   XCTAssertTrue([dict getDouble:NULL forKey:32ULL]);
2260   XCTAssertTrue([dict getDouble:&value forKey:32ULL]);
2261   XCTAssertEqual(value, 601.);
2262   XCTAssertTrue([dict getDouble:NULL forKey:33ULL]);
2263   XCTAssertTrue([dict getDouble:&value forKey:33ULL]);
2264   XCTAssertEqual(value, 602.);
2265   XCTAssertFalse([dict getDouble:NULL forKey:34ULL]);
2267   __block NSUInteger idx = 0;
2268   uint64_t *seenKeys = malloc(3 * sizeof(uint64_t));
2269   double *seenValues = malloc(3 * sizeof(double));
2270   [dict enumerateKeysAndDoublesUsingBlock:^(uint64_t aKey, double aValue, BOOL *stop) {
2271     XCTAssertLessThan(idx, 3U);
2272     seenKeys[idx] = aKey;
2273     seenValues[idx] = aValue;
2274     XCTAssertNotEqual(stop, NULL);
2275     ++idx;
2276   }];
2277   for (int i = 0; i < 3; ++i) {
2278     BOOL foundKey = NO;
2279     for (int j = 0; (j < 3) && !foundKey; ++j) {
2280       if (kKeys[i] == seenKeys[j]) {
2281         foundKey = YES;
2282         XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
2283       }
2284     }
2285     XCTAssertTrue(foundKey, @"i = %d", i);
2286   }
2287   free(seenKeys);
2288   free(seenValues);
2290   // Stopping the enumeration.
2291   idx = 0;
2292   [dict enumerateKeysAndDoublesUsingBlock:^(__unused uint64_t aKey, __unused double aValue, BOOL *stop) {
2293     if (idx == 1) *stop = YES;
2294     XCTAssertNotEqual(idx, 2U);
2295     ++idx;
2296   }];
2297   [dict release];
2300 - (void)testEquality {
2301   const uint64_t kKeys1[] = { 31ULL, 32ULL, 33ULL, 34ULL };
2302   const uint64_t kKeys2[] = { 32ULL, 31ULL, 34ULL };
2303   const double kValues1[] = { 600., 601., 602. };
2304   const double kValues2[] = { 600., 603., 602. };
2305   const double kValues3[] = { 600., 601., 602., 603. };
2306   GPBUInt64DoubleDictionary *dict1 =
2307       [[GPBUInt64DoubleDictionary alloc] initWithDoubles:kValues1
2308                                                  forKeys:kKeys1
2309                                                    count:GPBARRAYSIZE(kValues1)];
2310   XCTAssertNotNil(dict1);
2311   GPBUInt64DoubleDictionary *dict1prime =
2312       [[GPBUInt64DoubleDictionary alloc] initWithDoubles:kValues1
2313                                                  forKeys:kKeys1
2314                                                    count:GPBARRAYSIZE(kValues1)];
2315   XCTAssertNotNil(dict1prime);
2316   GPBUInt64DoubleDictionary *dict2 =
2317       [[GPBUInt64DoubleDictionary alloc] initWithDoubles:kValues2
2318                                                  forKeys:kKeys1
2319                                                    count:GPBARRAYSIZE(kValues2)];
2320   XCTAssertNotNil(dict2);
2321   GPBUInt64DoubleDictionary *dict3 =
2322       [[GPBUInt64DoubleDictionary alloc] initWithDoubles:kValues1
2323                                                  forKeys:kKeys2
2324                                                    count:GPBARRAYSIZE(kValues1)];
2325   XCTAssertNotNil(dict3);
2326   GPBUInt64DoubleDictionary *dict4 =
2327       [[GPBUInt64DoubleDictionary alloc] initWithDoubles:kValues3
2328                                                  forKeys:kKeys1
2329                                                    count:GPBARRAYSIZE(kValues3)];
2330   XCTAssertNotNil(dict4);
2332   // 1/1Prime should be different objects, but equal.
2333   XCTAssertNotEqual(dict1, dict1prime);
2334   XCTAssertEqualObjects(dict1, dict1prime);
2335   // Equal, so they must have same hash.
2336   XCTAssertEqual([dict1 hash], [dict1prime hash]);
2338   // 2 is same keys, different values; not equal.
2339   XCTAssertNotEqualObjects(dict1, dict2);
2341   // 3 is different keys, same values; not equal.
2342   XCTAssertNotEqualObjects(dict1, dict3);
2344   // 4 extra pair; not equal
2345   XCTAssertNotEqualObjects(dict1, dict4);
2347   [dict1 release];
2348   [dict1prime release];
2349   [dict2 release];
2350   [dict3 release];
2351   [dict4 release];
2354 - (void)testCopy {
2355   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
2356   const double kValues[] = { 600., 601., 602., 603. };
2357   GPBUInt64DoubleDictionary *dict =
2358       [[GPBUInt64DoubleDictionary alloc] initWithDoubles:kValues
2359                                                  forKeys:kKeys
2360                                                    count:GPBARRAYSIZE(kValues)];
2361   XCTAssertNotNil(dict);
2363   GPBUInt64DoubleDictionary *dict2 = [dict copy];
2364   XCTAssertNotNil(dict2);
2366   // Should be new object but equal.
2367   XCTAssertNotEqual(dict, dict2);
2368   XCTAssertEqualObjects(dict, dict2);
2369   XCTAssertTrue([dict2 isKindOfClass:[GPBUInt64DoubleDictionary class]]);
2371   [dict2 release];
2372   [dict release];
2375 - (void)testDictionaryFromDictionary {
2376   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
2377   const double kValues[] = { 600., 601., 602., 603. };
2378   GPBUInt64DoubleDictionary *dict =
2379       [[GPBUInt64DoubleDictionary alloc] initWithDoubles:kValues
2380                                                  forKeys:kKeys
2381                                                    count:GPBARRAYSIZE(kValues)];
2382   XCTAssertNotNil(dict);
2384   GPBUInt64DoubleDictionary *dict2 =
2385       [[GPBUInt64DoubleDictionary alloc] initWithDictionary:dict];
2386   XCTAssertNotNil(dict2);
2388   // Should be new pointer, but equal objects.
2389   XCTAssertNotEqual(dict, dict2);
2390   XCTAssertEqualObjects(dict, dict2);
2391   [dict2 release];
2392   [dict release];
2395 - (void)testAdds {
2396   GPBUInt64DoubleDictionary *dict = [[GPBUInt64DoubleDictionary alloc] init];
2397   XCTAssertNotNil(dict);
2399   XCTAssertEqual(dict.count, 0U);
2400   [dict setDouble:600. forKey:31ULL];
2401   XCTAssertEqual(dict.count, 1U);
2403   const uint64_t kKeys[] = { 32ULL, 33ULL, 34ULL };
2404   const double kValues[] = { 601., 602., 603. };
2405   GPBUInt64DoubleDictionary *dict2 =
2406       [[GPBUInt64DoubleDictionary alloc] initWithDoubles:kValues
2407                                                  forKeys:kKeys
2408                                                    count:GPBARRAYSIZE(kValues)];
2409   XCTAssertNotNil(dict2);
2410   [dict addEntriesFromDictionary:dict2];
2411   XCTAssertEqual(dict.count, 4U);
2413   double value;
2414   XCTAssertTrue([dict getDouble:NULL forKey:31ULL]);
2415   XCTAssertTrue([dict getDouble:&value forKey:31ULL]);
2416   XCTAssertEqual(value, 600.);
2417   XCTAssertTrue([dict getDouble:NULL forKey:32ULL]);
2418   XCTAssertTrue([dict getDouble:&value forKey:32ULL]);
2419   XCTAssertEqual(value, 601.);
2420   XCTAssertTrue([dict getDouble:NULL forKey:33ULL]);
2421   XCTAssertTrue([dict getDouble:&value forKey:33ULL]);
2422   XCTAssertEqual(value, 602.);
2423   XCTAssertTrue([dict getDouble:NULL forKey:34ULL]);
2424   XCTAssertTrue([dict getDouble:&value forKey:34ULL]);
2425   XCTAssertEqual(value, 603.);
2426   [dict2 release];
2427   [dict release];
2430 - (void)testRemove {
2431   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
2432   const double kValues[] = { 600., 601., 602., 603. };
2433   GPBUInt64DoubleDictionary *dict =
2434       [[GPBUInt64DoubleDictionary alloc] initWithDoubles:kValues
2435                                                  forKeys:kKeys
2436                                                    count:GPBARRAYSIZE(kValues)];
2437   XCTAssertNotNil(dict);
2438   XCTAssertEqual(dict.count, 4U);
2440   [dict removeDoubleForKey:32ULL];
2441   XCTAssertEqual(dict.count, 3U);
2442   double value;
2443   XCTAssertTrue([dict getDouble:NULL forKey:31ULL]);
2444   XCTAssertTrue([dict getDouble:&value forKey:31ULL]);
2445   XCTAssertEqual(value, 600.);
2446   XCTAssertFalse([dict getDouble:NULL forKey:32ULL]);
2447   XCTAssertTrue([dict getDouble:NULL forKey:33ULL]);
2448   XCTAssertTrue([dict getDouble:&value forKey:33ULL]);
2449   XCTAssertEqual(value, 602.);
2450   XCTAssertTrue([dict getDouble:NULL forKey:34ULL]);
2451   XCTAssertTrue([dict getDouble:&value forKey:34ULL]);
2452   XCTAssertEqual(value, 603.);
2454   // Remove again does nothing.
2455   [dict removeDoubleForKey:32ULL];
2456   XCTAssertEqual(dict.count, 3U);
2457   XCTAssertTrue([dict getDouble:NULL forKey:31ULL]);
2458   XCTAssertTrue([dict getDouble:&value forKey:31ULL]);
2459   XCTAssertEqual(value, 600.);
2460   XCTAssertFalse([dict getDouble:NULL forKey:32ULL]);
2461   XCTAssertTrue([dict getDouble:NULL forKey:33ULL]);
2462   XCTAssertTrue([dict getDouble:&value forKey:33ULL]);
2463   XCTAssertEqual(value, 602.);
2464   XCTAssertTrue([dict getDouble:NULL forKey:34ULL]);
2465   XCTAssertTrue([dict getDouble:&value forKey:34ULL]);
2466   XCTAssertEqual(value, 603.);
2468   [dict removeDoubleForKey:34ULL];
2469   XCTAssertEqual(dict.count, 2U);
2470   XCTAssertTrue([dict getDouble:NULL forKey:31ULL]);
2471   XCTAssertTrue([dict getDouble:&value forKey:31ULL]);
2472   XCTAssertEqual(value, 600.);
2473   XCTAssertFalse([dict getDouble:NULL forKey:32ULL]);
2474   XCTAssertTrue([dict getDouble:NULL forKey:33ULL]);
2475   XCTAssertTrue([dict getDouble:&value forKey:33ULL]);
2476   XCTAssertEqual(value, 602.);
2477   XCTAssertFalse([dict getDouble:NULL forKey:34ULL]);
2479   [dict removeAll];
2480   XCTAssertEqual(dict.count, 0U);
2481   XCTAssertFalse([dict getDouble:NULL forKey:31ULL]);
2482   XCTAssertFalse([dict getDouble:NULL forKey:32ULL]);
2483   XCTAssertFalse([dict getDouble:NULL forKey:33ULL]);
2484   XCTAssertFalse([dict getDouble:NULL forKey:34ULL]);
2485   [dict release];
2488 - (void)testInplaceMutation {
2489   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
2490   const double kValues[] = { 600., 601., 602., 603. };
2491   GPBUInt64DoubleDictionary *dict =
2492       [[GPBUInt64DoubleDictionary alloc] initWithDoubles:kValues
2493                                                  forKeys:kKeys
2494                                                    count:GPBARRAYSIZE(kValues)];
2495   XCTAssertNotNil(dict);
2496   XCTAssertEqual(dict.count, 4U);
2497   double value;
2498   XCTAssertTrue([dict getDouble:NULL forKey:31ULL]);
2499   XCTAssertTrue([dict getDouble:&value forKey:31ULL]);
2500   XCTAssertEqual(value, 600.);
2501   XCTAssertTrue([dict getDouble:NULL forKey:32ULL]);
2502   XCTAssertTrue([dict getDouble:&value forKey:32ULL]);
2503   XCTAssertEqual(value, 601.);
2504   XCTAssertTrue([dict getDouble:NULL forKey:33ULL]);
2505   XCTAssertTrue([dict getDouble:&value forKey:33ULL]);
2506   XCTAssertEqual(value, 602.);
2507   XCTAssertTrue([dict getDouble:NULL forKey:34ULL]);
2508   XCTAssertTrue([dict getDouble:&value forKey:34ULL]);
2509   XCTAssertEqual(value, 603.);
2511   [dict setDouble:603. forKey:31ULL];
2512   XCTAssertEqual(dict.count, 4U);
2513   XCTAssertTrue([dict getDouble:NULL forKey:31ULL]);
2514   XCTAssertTrue([dict getDouble:&value forKey:31ULL]);
2515   XCTAssertEqual(value, 603.);
2516   XCTAssertTrue([dict getDouble:NULL forKey:32ULL]);
2517   XCTAssertTrue([dict getDouble:&value forKey:32ULL]);
2518   XCTAssertEqual(value, 601.);
2519   XCTAssertTrue([dict getDouble:NULL forKey:33ULL]);
2520   XCTAssertTrue([dict getDouble:&value forKey:33ULL]);
2521   XCTAssertEqual(value, 602.);
2522   XCTAssertTrue([dict getDouble:NULL forKey:34ULL]);
2523   XCTAssertTrue([dict getDouble:&value forKey:34ULL]);
2524   XCTAssertEqual(value, 603.);
2526   [dict setDouble:601. forKey:34ULL];
2527   XCTAssertEqual(dict.count, 4U);
2528   XCTAssertTrue([dict getDouble:NULL forKey:31ULL]);
2529   XCTAssertTrue([dict getDouble:&value forKey:31ULL]);
2530   XCTAssertEqual(value, 603.);
2531   XCTAssertTrue([dict getDouble:NULL forKey:32ULL]);
2532   XCTAssertTrue([dict getDouble:&value forKey:32ULL]);
2533   XCTAssertEqual(value, 601.);
2534   XCTAssertTrue([dict getDouble:NULL forKey:33ULL]);
2535   XCTAssertTrue([dict getDouble:&value forKey:33ULL]);
2536   XCTAssertEqual(value, 602.);
2537   XCTAssertTrue([dict getDouble:NULL forKey:34ULL]);
2538   XCTAssertTrue([dict getDouble:&value forKey:34ULL]);
2539   XCTAssertEqual(value, 601.);
2541   const uint64_t kKeys2[] = { 32ULL, 33ULL };
2542   const double kValues2[] = { 602., 600. };
2543   GPBUInt64DoubleDictionary *dict2 =
2544       [[GPBUInt64DoubleDictionary alloc] initWithDoubles:kValues2
2545                                                  forKeys:kKeys2
2546                                                    count:GPBARRAYSIZE(kValues2)];
2547   XCTAssertNotNil(dict2);
2548   [dict addEntriesFromDictionary:dict2];
2549   XCTAssertEqual(dict.count, 4U);
2550   XCTAssertTrue([dict getDouble:NULL forKey:31ULL]);
2551   XCTAssertTrue([dict getDouble:&value forKey:31ULL]);
2552   XCTAssertEqual(value, 603.);
2553   XCTAssertTrue([dict getDouble:NULL forKey:32ULL]);
2554   XCTAssertTrue([dict getDouble:&value forKey:32ULL]);
2555   XCTAssertEqual(value, 602.);
2556   XCTAssertTrue([dict getDouble:NULL forKey:33ULL]);
2557   XCTAssertTrue([dict getDouble:&value forKey:33ULL]);
2558   XCTAssertEqual(value, 600.);
2559   XCTAssertTrue([dict getDouble:NULL forKey:34ULL]);
2560   XCTAssertTrue([dict getDouble:&value forKey:34ULL]);
2561   XCTAssertEqual(value, 601.);
2563   [dict2 release];
2564   [dict release];
2567 @end
2569 #pragma mark - UInt64 -> Enum
2571 @interface GPBUInt64EnumDictionaryTests : XCTestCase
2572 @end
2574 @implementation GPBUInt64EnumDictionaryTests
2576 - (void)testEmpty {
2577   GPBUInt64EnumDictionary *dict = [[GPBUInt64EnumDictionary alloc] init];
2578   XCTAssertNotNil(dict);
2579   XCTAssertEqual(dict.count, 0U);
2580   XCTAssertFalse([dict getEnum:NULL forKey:31ULL]);
2581   [dict enumerateKeysAndEnumsUsingBlock:^(__unused uint64_t aKey, __unused int32_t aValue, __unused BOOL *stop) {
2582     XCTFail(@"Shouldn't get here!");
2583   }];
2584   [dict release];
2587 - (void)testOne {
2588   GPBUInt64EnumDictionary *dict = [[GPBUInt64EnumDictionary alloc] init];
2589   [dict setEnum:700 forKey:31ULL];
2590   XCTAssertNotNil(dict);
2591   XCTAssertEqual(dict.count, 1U);
2592   int32_t value;
2593   XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
2594   XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
2595   XCTAssertEqual(value, 700);
2596   XCTAssertFalse([dict getEnum:NULL forKey:32ULL]);
2597   [dict enumerateKeysAndEnumsUsingBlock:^(uint64_t aKey, int32_t aValue, BOOL *stop) {
2598     XCTAssertEqual(aKey, 31ULL);
2599     XCTAssertEqual(aValue, 700);
2600     XCTAssertNotEqual(stop, NULL);
2601   }];
2602   [dict release];
2605 - (void)testBasics {
2606   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL };
2607   const int32_t kValues[] = { 700, 701, 702 };
2608   GPBUInt64EnumDictionary *dict =
2609       [[GPBUInt64EnumDictionary alloc] initWithEnums:kValues
2610                                              forKeys:kKeys
2611                                                count:GPBARRAYSIZE(kValues)];
2612   XCTAssertNotNil(dict);
2613   XCTAssertEqual(dict.count, 3U);
2614   int32_t value;
2615   XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
2616   XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
2617   XCTAssertEqual(value, 700);
2618   XCTAssertTrue([dict getEnum:NULL forKey:32ULL]);
2619   XCTAssertTrue([dict getEnum:&value forKey:32ULL]);
2620   XCTAssertEqual(value, 701);
2621   XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
2622   XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
2623   XCTAssertEqual(value, 702);
2624   XCTAssertFalse([dict getEnum:NULL forKey:34ULL]);
2626   __block NSUInteger idx = 0;
2627   uint64_t *seenKeys = malloc(3 * sizeof(uint64_t));
2628   int32_t *seenValues = malloc(3 * sizeof(int32_t));
2629   [dict enumerateKeysAndEnumsUsingBlock:^(uint64_t aKey, int32_t aValue, BOOL *stop) {
2630     XCTAssertLessThan(idx, 3U);
2631     seenKeys[idx] = aKey;
2632     seenValues[idx] = aValue;
2633     XCTAssertNotEqual(stop, NULL);
2634     ++idx;
2635   }];
2636   for (int i = 0; i < 3; ++i) {
2637     BOOL foundKey = NO;
2638     for (int j = 0; (j < 3) && !foundKey; ++j) {
2639       if (kKeys[i] == seenKeys[j]) {
2640         foundKey = YES;
2641         XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
2642       }
2643     }
2644     XCTAssertTrue(foundKey, @"i = %d", i);
2645   }
2646   free(seenKeys);
2647   free(seenValues);
2649   // Stopping the enumeration.
2650   idx = 0;
2651   [dict enumerateKeysAndEnumsUsingBlock:^(__unused uint64_t aKey, __unused int32_t aValue, BOOL *stop) {
2652     if (idx == 1) *stop = YES;
2653     XCTAssertNotEqual(idx, 2U);
2654     ++idx;
2655   }];
2656   [dict release];
2659 - (void)testEquality {
2660   const uint64_t kKeys1[] = { 31ULL, 32ULL, 33ULL, 34ULL };
2661   const uint64_t kKeys2[] = { 32ULL, 31ULL, 34ULL };
2662   const int32_t kValues1[] = { 700, 701, 702 };
2663   const int32_t kValues2[] = { 700, 703, 702 };
2664   const int32_t kValues3[] = { 700, 701, 702, 703 };
2665   GPBUInt64EnumDictionary *dict1 =
2666       [[GPBUInt64EnumDictionary alloc] initWithEnums:kValues1
2667                                              forKeys:kKeys1
2668                                                count:GPBARRAYSIZE(kValues1)];
2669   XCTAssertNotNil(dict1);
2670   GPBUInt64EnumDictionary *dict1prime =
2671       [[GPBUInt64EnumDictionary alloc] initWithEnums:kValues1
2672                                              forKeys:kKeys1
2673                                                count:GPBARRAYSIZE(kValues1)];
2674   XCTAssertNotNil(dict1prime);
2675   GPBUInt64EnumDictionary *dict2 =
2676       [[GPBUInt64EnumDictionary alloc] initWithEnums:kValues2
2677                                              forKeys:kKeys1
2678                                                count:GPBARRAYSIZE(kValues2)];
2679   XCTAssertNotNil(dict2);
2680   GPBUInt64EnumDictionary *dict3 =
2681       [[GPBUInt64EnumDictionary alloc] initWithEnums:kValues1
2682                                              forKeys:kKeys2
2683                                                count:GPBARRAYSIZE(kValues1)];
2684   XCTAssertNotNil(dict3);
2685   GPBUInt64EnumDictionary *dict4 =
2686       [[GPBUInt64EnumDictionary alloc] initWithEnums:kValues3
2687                                              forKeys:kKeys1
2688                                                count:GPBARRAYSIZE(kValues3)];
2689   XCTAssertNotNil(dict4);
2691   // 1/1Prime should be different objects, but equal.
2692   XCTAssertNotEqual(dict1, dict1prime);
2693   XCTAssertEqualObjects(dict1, dict1prime);
2694   // Equal, so they must have same hash.
2695   XCTAssertEqual([dict1 hash], [dict1prime hash]);
2697   // 2 is same keys, different values; not equal.
2698   XCTAssertNotEqualObjects(dict1, dict2);
2700   // 3 is different keys, same values; not equal.
2701   XCTAssertNotEqualObjects(dict1, dict3);
2703   // 4 extra pair; not equal
2704   XCTAssertNotEqualObjects(dict1, dict4);
2706   [dict1 release];
2707   [dict1prime release];
2708   [dict2 release];
2709   [dict3 release];
2710   [dict4 release];
2713 - (void)testCopy {
2714   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
2715   const int32_t kValues[] = { 700, 701, 702, 703 };
2716   GPBUInt64EnumDictionary *dict =
2717       [[GPBUInt64EnumDictionary alloc] initWithEnums:kValues
2718                                              forKeys:kKeys
2719                                                count:GPBARRAYSIZE(kValues)];
2720   XCTAssertNotNil(dict);
2722   GPBUInt64EnumDictionary *dict2 = [dict copy];
2723   XCTAssertNotNil(dict2);
2725   // Should be new object but equal.
2726   XCTAssertNotEqual(dict, dict2);
2727   XCTAssertEqualObjects(dict, dict2);
2728   XCTAssertTrue([dict2 isKindOfClass:[GPBUInt64EnumDictionary class]]);
2730   [dict2 release];
2731   [dict release];
2734 - (void)testDictionaryFromDictionary {
2735   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
2736   const int32_t kValues[] = { 700, 701, 702, 703 };
2737   GPBUInt64EnumDictionary *dict =
2738       [[GPBUInt64EnumDictionary alloc] initWithEnums:kValues
2739                                              forKeys:kKeys
2740                                                count:GPBARRAYSIZE(kValues)];
2741   XCTAssertNotNil(dict);
2743   GPBUInt64EnumDictionary *dict2 =
2744       [[GPBUInt64EnumDictionary alloc] initWithDictionary:dict];
2745   XCTAssertNotNil(dict2);
2747   // Should be new pointer, but equal objects.
2748   XCTAssertNotEqual(dict, dict2);
2749   XCTAssertEqualObjects(dict, dict2);
2750   [dict2 release];
2751   [dict release];
2754 - (void)testAdds {
2755   GPBUInt64EnumDictionary *dict = [[GPBUInt64EnumDictionary alloc] init];
2756   XCTAssertNotNil(dict);
2758   XCTAssertEqual(dict.count, 0U);
2759   [dict setEnum:700 forKey:31ULL];
2760   XCTAssertEqual(dict.count, 1U);
2762   const uint64_t kKeys[] = { 32ULL, 33ULL, 34ULL };
2763   const int32_t kValues[] = { 701, 702, 703 };
2764   GPBUInt64EnumDictionary *dict2 =
2765       [[GPBUInt64EnumDictionary alloc] initWithEnums:kValues
2766                                              forKeys:kKeys
2767                                                count:GPBARRAYSIZE(kValues)];
2768   XCTAssertNotNil(dict2);
2769   [dict addRawEntriesFromDictionary:dict2];
2770   XCTAssertEqual(dict.count, 4U);
2772   int32_t value;
2773   XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
2774   XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
2775   XCTAssertEqual(value, 700);
2776   XCTAssertTrue([dict getEnum:NULL forKey:32ULL]);
2777   XCTAssertTrue([dict getEnum:&value forKey:32ULL]);
2778   XCTAssertEqual(value, 701);
2779   XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
2780   XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
2781   XCTAssertEqual(value, 702);
2782   XCTAssertTrue([dict getEnum:NULL forKey:34ULL]);
2783   XCTAssertTrue([dict getEnum:&value forKey:34ULL]);
2784   XCTAssertEqual(value, 703);
2785   [dict2 release];
2786   [dict release];
2789 - (void)testRemove {
2790   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
2791   const int32_t kValues[] = { 700, 701, 702, 703 };
2792   GPBUInt64EnumDictionary *dict =
2793       [[GPBUInt64EnumDictionary alloc] initWithEnums:kValues
2794                                              forKeys:kKeys
2795                                                count:GPBARRAYSIZE(kValues)];
2796   XCTAssertNotNil(dict);
2797   XCTAssertEqual(dict.count, 4U);
2799   [dict removeEnumForKey:32ULL];
2800   XCTAssertEqual(dict.count, 3U);
2801   int32_t value;
2802   XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
2803   XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
2804   XCTAssertEqual(value, 700);
2805   XCTAssertFalse([dict getEnum:NULL forKey:32ULL]);
2806   XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
2807   XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
2808   XCTAssertEqual(value, 702);
2809   XCTAssertTrue([dict getEnum:NULL forKey:34ULL]);
2810   XCTAssertTrue([dict getEnum:&value forKey:34ULL]);
2811   XCTAssertEqual(value, 703);
2813   // Remove again does nothing.
2814   [dict removeEnumForKey:32ULL];
2815   XCTAssertEqual(dict.count, 3U);
2816   XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
2817   XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
2818   XCTAssertEqual(value, 700);
2819   XCTAssertFalse([dict getEnum:NULL forKey:32ULL]);
2820   XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
2821   XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
2822   XCTAssertEqual(value, 702);
2823   XCTAssertTrue([dict getEnum:NULL forKey:34ULL]);
2824   XCTAssertTrue([dict getEnum:&value forKey:34ULL]);
2825   XCTAssertEqual(value, 703);
2827   [dict removeEnumForKey:34ULL];
2828   XCTAssertEqual(dict.count, 2U);
2829   XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
2830   XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
2831   XCTAssertEqual(value, 700);
2832   XCTAssertFalse([dict getEnum:NULL forKey:32ULL]);
2833   XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
2834   XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
2835   XCTAssertEqual(value, 702);
2836   XCTAssertFalse([dict getEnum:NULL forKey:34ULL]);
2838   [dict removeAll];
2839   XCTAssertEqual(dict.count, 0U);
2840   XCTAssertFalse([dict getEnum:NULL forKey:31ULL]);
2841   XCTAssertFalse([dict getEnum:NULL forKey:32ULL]);
2842   XCTAssertFalse([dict getEnum:NULL forKey:33ULL]);
2843   XCTAssertFalse([dict getEnum:NULL forKey:34ULL]);
2844   [dict release];
2847 - (void)testInplaceMutation {
2848   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
2849   const int32_t kValues[] = { 700, 701, 702, 703 };
2850   GPBUInt64EnumDictionary *dict =
2851       [[GPBUInt64EnumDictionary alloc] initWithEnums:kValues
2852                                              forKeys:kKeys
2853                                                count:GPBARRAYSIZE(kValues)];
2854   XCTAssertNotNil(dict);
2855   XCTAssertEqual(dict.count, 4U);
2856   int32_t value;
2857   XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
2858   XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
2859   XCTAssertEqual(value, 700);
2860   XCTAssertTrue([dict getEnum:NULL forKey:32ULL]);
2861   XCTAssertTrue([dict getEnum:&value forKey:32ULL]);
2862   XCTAssertEqual(value, 701);
2863   XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
2864   XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
2865   XCTAssertEqual(value, 702);
2866   XCTAssertTrue([dict getEnum:NULL forKey:34ULL]);
2867   XCTAssertTrue([dict getEnum:&value forKey:34ULL]);
2868   XCTAssertEqual(value, 703);
2870   [dict setEnum:703 forKey:31ULL];
2871   XCTAssertEqual(dict.count, 4U);
2872   XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
2873   XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
2874   XCTAssertEqual(value, 703);
2875   XCTAssertTrue([dict getEnum:NULL forKey:32ULL]);
2876   XCTAssertTrue([dict getEnum:&value forKey:32ULL]);
2877   XCTAssertEqual(value, 701);
2878   XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
2879   XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
2880   XCTAssertEqual(value, 702);
2881   XCTAssertTrue([dict getEnum:NULL forKey:34ULL]);
2882   XCTAssertTrue([dict getEnum:&value forKey:34ULL]);
2883   XCTAssertEqual(value, 703);
2885   [dict setEnum:701 forKey:34ULL];
2886   XCTAssertEqual(dict.count, 4U);
2887   XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
2888   XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
2889   XCTAssertEqual(value, 703);
2890   XCTAssertTrue([dict getEnum:NULL forKey:32ULL]);
2891   XCTAssertTrue([dict getEnum:&value forKey:32ULL]);
2892   XCTAssertEqual(value, 701);
2893   XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
2894   XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
2895   XCTAssertEqual(value, 702);
2896   XCTAssertTrue([dict getEnum:NULL forKey:34ULL]);
2897   XCTAssertTrue([dict getEnum:&value forKey:34ULL]);
2898   XCTAssertEqual(value, 701);
2900   const uint64_t kKeys2[] = { 32ULL, 33ULL };
2901   const int32_t kValues2[] = { 702, 700 };
2902   GPBUInt64EnumDictionary *dict2 =
2903       [[GPBUInt64EnumDictionary alloc] initWithEnums:kValues2
2904                                              forKeys:kKeys2
2905                                                count:GPBARRAYSIZE(kValues2)];
2906   XCTAssertNotNil(dict2);
2907   [dict addRawEntriesFromDictionary:dict2];
2908   XCTAssertEqual(dict.count, 4U);
2909   XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
2910   XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
2911   XCTAssertEqual(value, 703);
2912   XCTAssertTrue([dict getEnum:NULL forKey:32ULL]);
2913   XCTAssertTrue([dict getEnum:&value forKey:32ULL]);
2914   XCTAssertEqual(value, 702);
2915   XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
2916   XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
2917   XCTAssertEqual(value, 700);
2918   XCTAssertTrue([dict getEnum:NULL forKey:34ULL]);
2919   XCTAssertTrue([dict getEnum:&value forKey:34ULL]);
2920   XCTAssertEqual(value, 701);
2922   [dict2 release];
2923   [dict release];
2926 @end
2928 #pragma mark - UInt64 -> Enum (Unknown Enums)
2930 @interface GPBUInt64EnumDictionaryUnknownEnumTests : XCTestCase
2931 @end
2933 @implementation GPBUInt64EnumDictionaryUnknownEnumTests
2935 - (void)testRawBasics {
2936   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL };
2937   const int32_t kValues[] = { 700, 801, 702 };
2938   GPBUInt64EnumDictionary *dict =
2939       [[GPBUInt64EnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
2940                                                         rawValues:kValues
2941                                                           forKeys:kKeys
2942                                                             count:GPBARRAYSIZE(kValues)];
2943   XCTAssertNotNil(dict);
2944   XCTAssertEqual(dict.count, 3U);
2945   XCTAssertTrue(dict.validationFunc == TestingEnum_IsValidValue);  // Pointer comparison
2946   int32_t value;
2947   XCTAssertTrue([dict getRawValue:NULL forKey:31ULL]);
2948   XCTAssertTrue([dict getRawValue:&value forKey:31ULL]);
2949   XCTAssertEqual(value, 700);
2950   XCTAssertTrue([dict getEnum:NULL forKey:32ULL]);
2951   XCTAssertTrue([dict getEnum:&value forKey:32ULL]);
2952   XCTAssertEqual(value, kGPBUnrecognizedEnumeratorValue);
2953   XCTAssertTrue([dict getRawValue:NULL forKey:32ULL]);
2954   XCTAssertTrue([dict getRawValue:&value forKey:32ULL]);
2955   XCTAssertEqual(value, 801);
2956   XCTAssertTrue([dict getRawValue:NULL forKey:33ULL]);
2957   XCTAssertTrue([dict getRawValue:&value forKey:33ULL]);
2958   XCTAssertEqual(value, 702);
2959   XCTAssertFalse([dict getRawValue:NULL forKey:34ULL]);
2961   __block NSUInteger idx = 0;
2962   uint64_t *seenKeys = malloc(3 * sizeof(uint64_t));
2963   int32_t *seenValues = malloc(3 * sizeof(int32_t));
2964   [dict enumerateKeysAndEnumsUsingBlock:^(uint64_t aKey, int32_t aValue, BOOL *stop) {
2965     XCTAssertLessThan(idx, 3U);
2966     seenKeys[idx] = aKey;
2967     seenValues[idx] = aValue;
2968     XCTAssertNotEqual(stop, NULL);
2969     ++idx;
2970   }];
2971   for (int i = 0; i < 3; ++i) {
2972     BOOL foundKey = NO;
2973     for (int j = 0; (j < 3) && !foundKey; ++j) {
2974       if (kKeys[i] == seenKeys[j]) {
2975         foundKey = YES;
2976         if (i == 1) {
2977           XCTAssertEqual(kGPBUnrecognizedEnumeratorValue, seenValues[j], @"i = %d, j = %d", i, j);
2978         } else {
2979           XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
2980         }
2981       }
2982     }
2983     XCTAssertTrue(foundKey, @"i = %d", i);
2984   }
2985   idx = 0;
2986   [dict enumerateKeysAndRawValuesUsingBlock:^(uint64_t aKey, int32_t aValue, BOOL *stop) {
2987     XCTAssertLessThan(idx, 3U);
2988     seenKeys[idx] = aKey;
2989     seenValues[idx] = aValue;
2990     XCTAssertNotEqual(stop, NULL);
2991     ++idx;
2992   }];
2993   for (int i = 0; i < 3; ++i) {
2994     BOOL foundKey = NO;
2995     for (int j = 0; (j < 3) && !foundKey; ++j) {
2996       if (kKeys[i] == seenKeys[j]) {
2997         foundKey = YES;
2998         XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
2999       }
3000     }
3001     XCTAssertTrue(foundKey, @"i = %d", i);
3002   }
3003   free(seenKeys);
3004   free(seenValues);
3006   // Stopping the enumeration.
3007   idx = 0;
3008   [dict enumerateKeysAndRawValuesUsingBlock:^(__unused uint64_t aKey, __unused int32_t aValue, BOOL *stop) {
3009     if (idx == 1) *stop = YES;
3010     XCTAssertNotEqual(idx, 2U);
3011     ++idx;
3012   }];
3013   [dict release];
3016 - (void)testEqualityWithUnknowns {
3017   const uint64_t kKeys1[] = { 31ULL, 32ULL, 33ULL, 34ULL };
3018   const uint64_t kKeys2[] = { 32ULL, 31ULL, 34ULL };
3019   const int32_t kValues1[] = { 700, 801, 702 };  // Unknown
3020   const int32_t kValues2[] = { 700, 803, 702 };  // Unknown
3021   const int32_t kValues3[] = { 700, 801, 702, 803 };  // Unknowns
3022   GPBUInt64EnumDictionary *dict1 =
3023       [[GPBUInt64EnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3024                                                         rawValues:kValues1
3025                                                           forKeys:kKeys1
3026                                                             count:GPBARRAYSIZE(kValues1)];
3027   XCTAssertNotNil(dict1);
3028   GPBUInt64EnumDictionary *dict1prime =
3029       [[GPBUInt64EnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3030                                                         rawValues:kValues1
3031                                                           forKeys:kKeys1
3032                                                             count:GPBARRAYSIZE(kValues1)];
3033   XCTAssertNotNil(dict1prime);
3034   GPBUInt64EnumDictionary *dict2 =
3035       [[GPBUInt64EnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3036                                                         rawValues:kValues2
3037                                                           forKeys:kKeys1
3038                                                             count:GPBARRAYSIZE(kValues2)];
3039   XCTAssertNotNil(dict2);
3040   GPBUInt64EnumDictionary *dict3 =
3041       [[GPBUInt64EnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3042                                                         rawValues:kValues1
3043                                                           forKeys:kKeys2
3044                                                             count:GPBARRAYSIZE(kValues1)];
3045   XCTAssertNotNil(dict3);
3046   GPBUInt64EnumDictionary *dict4 =
3047       [[GPBUInt64EnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3048                                                         rawValues:kValues3
3049                                                           forKeys:kKeys1
3050                                                             count:GPBARRAYSIZE(kValues3)];
3051   XCTAssertNotNil(dict4);
3053   // 1/1Prime should be different objects, but equal.
3054   XCTAssertNotEqual(dict1, dict1prime);
3055   XCTAssertEqualObjects(dict1, dict1prime);
3056   // Equal, so they must have same hash.
3057   XCTAssertEqual([dict1 hash], [dict1prime hash]);
3059   // 2 is same keys, different values; not equal.
3060   XCTAssertNotEqualObjects(dict1, dict2);
3062   // 3 is different keys, same values; not equal.
3063   XCTAssertNotEqualObjects(dict1, dict3);
3065   // 4 extra pair; not equal
3066   XCTAssertNotEqualObjects(dict1, dict4);
3068   [dict1 release];
3069   [dict1prime release];
3070   [dict2 release];
3071   [dict3 release];
3072   [dict4 release];
3075 - (void)testCopyWithUnknowns {
3076   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
3077   const int32_t kValues[] = { 700, 801, 702, 803 };  // Unknown
3078   GPBUInt64EnumDictionary *dict =
3079       [[GPBUInt64EnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3080                                                         rawValues:kValues
3081                                                           forKeys:kKeys
3082                                                             count:GPBARRAYSIZE(kValues)];
3083   XCTAssertNotNil(dict);
3085   GPBUInt64EnumDictionary *dict2 = [dict copy];
3086   XCTAssertNotNil(dict2);
3088   // Should be new pointer, but equal objects.
3089   XCTAssertNotEqual(dict, dict2);
3090   XCTAssertEqual(dict.validationFunc, dict2.validationFunc);  // Pointer comparison
3091   XCTAssertEqualObjects(dict, dict2);
3093   [dict2 release];
3094   [dict release];
3097 - (void)testDictionaryFromDictionary {
3098   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
3099   const int32_t kValues[] = { 700, 801, 702, 803 };  // Unknowns
3100   GPBUInt64EnumDictionary *dict =
3101       [[GPBUInt64EnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3102                                                         rawValues:kValues
3103                                                           forKeys:kKeys
3104                                                             count:GPBARRAYSIZE(kValues)];
3105   XCTAssertNotNil(dict);
3107   GPBUInt64EnumDictionary *dict2 =
3108       [[GPBUInt64EnumDictionary alloc] initWithDictionary:dict];
3109   XCTAssertNotNil(dict2);
3111   // Should be new pointer, but equal objects.
3112   XCTAssertNotEqual(dict, dict2);
3113   XCTAssertEqualObjects(dict, dict2);
3114   XCTAssertEqual(dict.validationFunc, dict2.validationFunc);  // Pointer comparison
3115   [dict2 release];
3116   [dict release];
3119 - (void)testUnknownAdds {
3120   GPBUInt64EnumDictionary *dict =
3121       [[GPBUInt64EnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue];
3122   XCTAssertNotNil(dict);
3124   XCTAssertEqual(dict.count, 0U);
3125   XCTAssertThrowsSpecificNamed([dict setEnum:801 forKey:32ULL],  // Unknown
3126                                NSException, NSInvalidArgumentException);
3127   XCTAssertEqual(dict.count, 0U);
3128   [dict setRawValue:801 forKey:32ULL];  // Unknown
3129   XCTAssertEqual(dict.count, 1U);
3131   const uint64_t kKeys[] = { 31ULL, 33ULL, 34ULL };
3132   const int32_t kValues[] = { 700, 702, 803 };  // Unknown
3133   GPBUInt64EnumDictionary *dict2 =
3134       [[GPBUInt64EnumDictionary alloc] initWithEnums:kValues
3135                                                forKeys:kKeys
3136                                                  count:GPBARRAYSIZE(kValues)];
3137   XCTAssertNotNil(dict2);
3138   [dict addRawEntriesFromDictionary:dict2];
3139   XCTAssertEqual(dict.count, 4U);
3141   int32_t value;
3142   XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
3143   XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
3144   XCTAssertEqual(value, 700);
3145   XCTAssertTrue([dict getEnum:NULL forKey:32ULL]);
3146   XCTAssertTrue([dict getEnum:&value forKey:32ULL]);
3147   XCTAssertEqual(value, kGPBUnrecognizedEnumeratorValue);
3148   XCTAssertTrue([dict getRawValue:NULL forKey:32ULL]);
3149   XCTAssertTrue([dict getRawValue:&value forKey:32ULL]);
3150   XCTAssertEqual(value, 801);
3151   XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
3152   XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
3153   XCTAssertEqual(value, 702);
3154   XCTAssertTrue([dict getEnum:NULL forKey:34ULL]);
3155   XCTAssertTrue([dict getEnum:&value forKey:34ULL]);
3156   XCTAssertEqual(value, kGPBUnrecognizedEnumeratorValue);
3157   XCTAssertTrue([dict getRawValue:NULL forKey:34ULL]);
3158   XCTAssertTrue([dict getRawValue:&value forKey:34ULL]);
3159   XCTAssertEqual(value, 803);
3160   [dict2 release];
3161   [dict release];
3164 - (void)testUnknownRemove {
3165   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
3166   const int32_t kValues[] = { 700, 801, 702, 803 };  // Unknowns
3167   GPBUInt64EnumDictionary *dict =
3168       [[GPBUInt64EnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3169                                                         rawValues:kValues
3170                                                           forKeys:kKeys
3171                                                             count:GPBARRAYSIZE(kValues)];
3172   XCTAssertNotNil(dict);
3173   XCTAssertEqual(dict.count, 4U);
3175   [dict removeEnumForKey:32ULL];
3176   XCTAssertEqual(dict.count, 3U);
3177   int32_t value;
3178   XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
3179   XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
3180   XCTAssertEqual(value, 700);
3181   XCTAssertFalse([dict getEnum:NULL forKey:32ULL]);
3182   XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
3183   XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
3184   XCTAssertEqual(value, 702);
3185   XCTAssertTrue([dict getRawValue:NULL forKey:34ULL]);
3186   XCTAssertTrue([dict getRawValue:&value forKey:34ULL]);
3187   XCTAssertEqual(value, 803);
3189   // Remove again does nothing.
3190   [dict removeEnumForKey:32ULL];
3191   XCTAssertEqual(dict.count, 3U);
3192   XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
3193   XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
3194   XCTAssertEqual(value, 700);
3195   XCTAssertFalse([dict getEnum:NULL forKey:32ULL]);
3196   XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
3197   XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
3198   XCTAssertEqual(value, 702);
3199   XCTAssertTrue([dict getRawValue:NULL forKey:34ULL]);
3200   XCTAssertTrue([dict getRawValue:&value forKey:34ULL]);
3201   XCTAssertEqual(value, 803);
3203   [dict removeEnumForKey:34ULL];
3204   XCTAssertEqual(dict.count, 2U);
3205   XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
3206   XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
3207   XCTAssertEqual(value, 700);
3208   XCTAssertFalse([dict getEnum:NULL forKey:32ULL]);
3209   XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
3210   XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
3211   XCTAssertEqual(value, 702);
3212   XCTAssertFalse([dict getEnum:NULL forKey:34ULL]);
3214   [dict removeAll];
3215   XCTAssertEqual(dict.count, 0U);
3216   XCTAssertFalse([dict getEnum:NULL forKey:31ULL]);
3217   XCTAssertFalse([dict getEnum:NULL forKey:32ULL]);
3218   XCTAssertFalse([dict getEnum:NULL forKey:33ULL]);
3219   XCTAssertFalse([dict getEnum:NULL forKey:34ULL]);
3220   [dict release];
3223 - (void)testInplaceMutationUnknowns {
3224   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
3225   const int32_t kValues[] = { 700, 801, 702, 803 };  // Unknowns
3226   GPBUInt64EnumDictionary *dict =
3227       [[GPBUInt64EnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3228                                                         rawValues:kValues
3229                                                           forKeys:kKeys
3230                                                             count:GPBARRAYSIZE(kValues)];
3231   XCTAssertNotNil(dict);
3232   XCTAssertEqual(dict.count, 4U);
3233   int32_t value;
3234   XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
3235   XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
3236   XCTAssertEqual(value, 700);
3237   XCTAssertTrue([dict getRawValue:NULL forKey:32ULL]);
3238   XCTAssertTrue([dict getRawValue:&value forKey:32ULL]);
3239   XCTAssertEqual(value, 801);
3240   XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
3241   XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
3242   XCTAssertEqual(value, 702);
3243   XCTAssertTrue([dict getRawValue:NULL forKey:34ULL]);
3244   XCTAssertTrue([dict getRawValue:&value forKey:34ULL]);
3245   XCTAssertEqual(value, 803);
3247   XCTAssertThrowsSpecificNamed([dict setEnum:803 forKey:31ULL],  // Unknown
3248                                NSException, NSInvalidArgumentException);
3249   XCTAssertEqual(dict.count, 4U);
3250   XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
3251   XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
3252   XCTAssertEqual(value, 700);
3253   XCTAssertTrue([dict getRawValue:NULL forKey:32ULL]);
3254   XCTAssertTrue([dict getRawValue:&value forKey:32ULL]);
3255   XCTAssertEqual(value, 801);
3256   XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
3257   XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
3258   XCTAssertEqual(value, 702);
3259   XCTAssertTrue([dict getRawValue:NULL forKey:34ULL]);
3260   XCTAssertTrue([dict getRawValue:&value forKey:34ULL]);
3261   XCTAssertEqual(value, 803);
3263   [dict setRawValue:803 forKey:31ULL];  // Unknown
3264   XCTAssertEqual(dict.count, 4U);
3265   XCTAssertTrue([dict getRawValue:NULL forKey:31ULL]);
3266   XCTAssertTrue([dict getRawValue:&value forKey:31ULL]);
3267   XCTAssertEqual(value, 803);
3268   XCTAssertTrue([dict getRawValue:NULL forKey:32ULL]);
3269   XCTAssertTrue([dict getRawValue:&value forKey:32ULL]);
3270   XCTAssertEqual(value, 801);
3271   XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
3272   XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
3273   XCTAssertEqual(value, 702);
3274   XCTAssertTrue([dict getRawValue:NULL forKey:34ULL]);
3275   XCTAssertTrue([dict getRawValue:&value forKey:34ULL]);
3276   XCTAssertEqual(value, 803);
3278   [dict setRawValue:700 forKey:34ULL];
3279   XCTAssertEqual(dict.count, 4U);
3280   XCTAssertTrue([dict getRawValue:NULL forKey:31ULL]);
3281   XCTAssertTrue([dict getRawValue:&value forKey:31ULL]);
3282   XCTAssertEqual(value, 803);
3283   XCTAssertTrue([dict getRawValue:NULL forKey:32ULL]);
3284   XCTAssertTrue([dict getRawValue:&value forKey:32ULL]);
3285   XCTAssertEqual(value, 801);
3286   XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
3287   XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
3288   XCTAssertEqual(value, 702);
3289   XCTAssertTrue([dict getEnum:NULL forKey:34ULL]);
3290   XCTAssertTrue([dict getEnum:&value forKey:34ULL]);
3291   XCTAssertEqual(value, 700);
3293   const uint64_t kKeys2[] = { 32ULL, 33ULL };
3294   const int32_t kValues2[] = { 702, 801 };  // Unknown
3295   GPBUInt64EnumDictionary *dict2 =
3296       [[GPBUInt64EnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3297                                                         rawValues:kValues2
3298                                                           forKeys:kKeys2
3299                                                             count:GPBARRAYSIZE(kValues2)];
3300   XCTAssertNotNil(dict2);
3301   [dict addRawEntriesFromDictionary:dict2];
3302   XCTAssertEqual(dict.count, 4U);
3303   XCTAssertTrue([dict getRawValue:NULL forKey:31ULL]);
3304   XCTAssertTrue([dict getRawValue:&value forKey:31ULL]);
3305   XCTAssertEqual(value, 803);
3306   XCTAssertTrue([dict getEnum:NULL forKey:32ULL]);
3307   XCTAssertTrue([dict getEnum:&value forKey:32ULL]);
3308   XCTAssertEqual(value, 702);
3309   XCTAssertTrue([dict getRawValue:NULL forKey:33ULL]);
3310   XCTAssertTrue([dict getRawValue:&value forKey:33ULL]);
3311   XCTAssertEqual(value, 801);
3312   XCTAssertTrue([dict getEnum:NULL forKey:34ULL]);
3313   XCTAssertTrue([dict getEnum:&value forKey:34ULL]);
3314   XCTAssertEqual(value, 700);
3316   [dict2 release];
3317   [dict release];
3320 - (void)testCopyUnknowns {
3321   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
3322   const int32_t kValues[] = { 700, 801, 702, 803 };
3323   GPBUInt64EnumDictionary *dict =
3324       [[GPBUInt64EnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3325                                                         rawValues:kValues
3326                                                           forKeys:kKeys
3327                                                             count:GPBARRAYSIZE(kValues)];
3328   XCTAssertNotNil(dict);
3330   GPBUInt64EnumDictionary *dict2 = [dict copy];
3331   XCTAssertNotNil(dict2);
3333   // Should be new pointer, but equal objects.
3334   XCTAssertNotEqual(dict, dict2);
3335   XCTAssertEqualObjects(dict, dict2);
3336   XCTAssertEqual(dict.validationFunc, dict2.validationFunc);  // Pointer comparison
3337   XCTAssertTrue([dict2 isKindOfClass:[GPBUInt64EnumDictionary class]]);
3339   [dict2 release];
3340   [dict release];
3343 @end
3345 #pragma mark - UInt64 -> Object
3347 @interface GPBUInt64ObjectDictionaryTests : XCTestCase
3348 @end
3350 @implementation GPBUInt64ObjectDictionaryTests
3352 - (void)testEmpty {
3353   GPBUInt64ObjectDictionary<NSString*> *dict = [[GPBUInt64ObjectDictionary alloc] init];
3354   XCTAssertNotNil(dict);
3355   XCTAssertEqual(dict.count, 0U);
3356   XCTAssertNil([dict objectForKey:31ULL]);
3357   [dict enumerateKeysAndObjectsUsingBlock:^(__unused uint64_t aKey, __unused NSString* aObject, __unused BOOL *stop) {
3358     XCTFail(@"Shouldn't get here!");
3359   }];
3360   [dict release];
3363 - (void)testOne {
3364   GPBUInt64ObjectDictionary<NSString*> *dict = [[GPBUInt64ObjectDictionary alloc] init];
3365   [dict setObject:@"abc" forKey:31ULL];
3366   XCTAssertNotNil(dict);
3367   XCTAssertEqual(dict.count, 1U);
3368   XCTAssertEqualObjects([dict objectForKey:31ULL], @"abc");
3369   XCTAssertNil([dict objectForKey:32ULL]);
3370   [dict enumerateKeysAndObjectsUsingBlock:^(uint64_t aKey, NSString* aObject, BOOL *stop) {
3371     XCTAssertEqual(aKey, 31ULL);
3372     XCTAssertEqualObjects(aObject, @"abc");
3373     XCTAssertNotEqual(stop, NULL);
3374   }];
3375   [dict release];
3378 - (void)testBasics {
3379   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL };
3380   const NSString* kObjects[] = { @"abc", @"def", @"ghi" };
3381   GPBUInt64ObjectDictionary<NSString*> *dict =
3382       [[GPBUInt64ObjectDictionary alloc] initWithObjects:kObjects
3383                                                  forKeys:kKeys
3384                                                    count:GPBARRAYSIZE(kObjects)];
3385   XCTAssertNotNil(dict);
3386   XCTAssertEqual(dict.count, 3U);
3387   XCTAssertEqualObjects([dict objectForKey:31ULL], @"abc");
3388   XCTAssertEqualObjects([dict objectForKey:32ULL], @"def");
3389   XCTAssertEqualObjects([dict objectForKey:33ULL], @"ghi");
3390   XCTAssertNil([dict objectForKey:34ULL]);
3392   __block NSUInteger idx = 0;
3393   uint64_t *seenKeys = malloc(3 * sizeof(uint64_t));
3394   NSString* *seenObjects = malloc(3 * sizeof(NSString*));
3395   [dict enumerateKeysAndObjectsUsingBlock:^(uint64_t aKey, NSString* aObject, BOOL *stop) {
3396     XCTAssertLessThan(idx, 3U);
3397     seenKeys[idx] = aKey;
3398     seenObjects[idx] = aObject;
3399     XCTAssertNotEqual(stop, NULL);
3400     ++idx;
3401   }];
3402   for (int i = 0; i < 3; ++i) {
3403     BOOL foundKey = NO;
3404     for (int j = 0; (j < 3) && !foundKey; ++j) {
3405       if (kKeys[i] == seenKeys[j]) {
3406         foundKey = YES;
3407         XCTAssertEqualObjects(kObjects[i], seenObjects[j], @"i = %d, j = %d", i, j);
3408       }
3409     }
3410     XCTAssertTrue(foundKey, @"i = %d", i);
3411   }
3412   free(seenKeys);
3413   free(seenObjects);
3415   // Stopping the enumeration.
3416   idx = 0;
3417   [dict enumerateKeysAndObjectsUsingBlock:^(__unused uint64_t aKey, __unused NSString* aObject, BOOL *stop) {
3418     if (idx == 1) *stop = YES;
3419     XCTAssertNotEqual(idx, 2U);
3420     ++idx;
3421   }];
3422   [dict release];
3425 - (void)testEquality {
3426   const uint64_t kKeys1[] = { 31ULL, 32ULL, 33ULL, 34ULL };
3427   const uint64_t kKeys2[] = { 32ULL, 31ULL, 34ULL };
3428   const NSString* kObjects1[] = { @"abc", @"def", @"ghi" };
3429   const NSString* kObjects2[] = { @"abc", @"jkl", @"ghi" };
3430   const NSString* kObjects3[] = { @"abc", @"def", @"ghi", @"jkl" };
3431   GPBUInt64ObjectDictionary<NSString*> *dict1 =
3432       [[GPBUInt64ObjectDictionary alloc] initWithObjects:kObjects1
3433                                                  forKeys:kKeys1
3434                                                    count:GPBARRAYSIZE(kObjects1)];
3435   XCTAssertNotNil(dict1);
3436   GPBUInt64ObjectDictionary<NSString*> *dict1prime =
3437       [[GPBUInt64ObjectDictionary alloc] initWithObjects:kObjects1
3438                                                  forKeys:kKeys1
3439                                                    count:GPBARRAYSIZE(kObjects1)];
3440   XCTAssertNotNil(dict1prime);
3441   GPBUInt64ObjectDictionary<NSString*> *dict2 =
3442       [[GPBUInt64ObjectDictionary alloc] initWithObjects:kObjects2
3443                                                  forKeys:kKeys1
3444                                                    count:GPBARRAYSIZE(kObjects2)];
3445   XCTAssertNotNil(dict2);
3446   GPBUInt64ObjectDictionary<NSString*> *dict3 =
3447       [[GPBUInt64ObjectDictionary alloc] initWithObjects:kObjects1
3448                                                  forKeys:kKeys2
3449                                                    count:GPBARRAYSIZE(kObjects1)];
3450   XCTAssertNotNil(dict3);
3451   GPBUInt64ObjectDictionary<NSString*> *dict4 =
3452       [[GPBUInt64ObjectDictionary alloc] initWithObjects:kObjects3
3453                                                  forKeys:kKeys1
3454                                                    count:GPBARRAYSIZE(kObjects3)];
3455   XCTAssertNotNil(dict4);
3457   // 1/1Prime should be different objects, but equal.
3458   XCTAssertNotEqual(dict1, dict1prime);
3459   XCTAssertEqualObjects(dict1, dict1prime);
3460   // Equal, so they must have same hash.
3461   XCTAssertEqual([dict1 hash], [dict1prime hash]);
3463   // 2 is same keys, different objects; not equal.
3464   XCTAssertNotEqualObjects(dict1, dict2);
3466   // 3 is different keys, same objects; not equal.
3467   XCTAssertNotEqualObjects(dict1, dict3);
3469   // 4 extra pair; not equal
3470   XCTAssertNotEqualObjects(dict1, dict4);
3472   [dict1 release];
3473   [dict1prime release];
3474   [dict2 release];
3475   [dict3 release];
3476   [dict4 release];
3479 - (void)testCopy {
3480   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
3481   const NSString* kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
3482   GPBUInt64ObjectDictionary<NSString*> *dict =
3483       [[GPBUInt64ObjectDictionary alloc] initWithObjects:kObjects
3484                                                  forKeys:kKeys
3485                                                    count:GPBARRAYSIZE(kObjects)];
3486   XCTAssertNotNil(dict);
3488   GPBUInt64ObjectDictionary<NSString*> *dict2 = [dict copy];
3489   XCTAssertNotNil(dict2);
3491   // Should be new object but equal.
3492   XCTAssertNotEqual(dict, dict2);
3493   XCTAssertEqualObjects(dict, dict2);
3494   XCTAssertTrue([dict2 isKindOfClass:[GPBUInt64ObjectDictionary class]]);
3496   [dict2 release];
3497   [dict release];
3500 - (void)testDictionaryFromDictionary {
3501   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
3502   const NSString* kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
3503   GPBUInt64ObjectDictionary<NSString*> *dict =
3504       [[GPBUInt64ObjectDictionary alloc] initWithObjects:kObjects
3505                                                  forKeys:kKeys
3506                                                    count:GPBARRAYSIZE(kObjects)];
3507   XCTAssertNotNil(dict);
3509   GPBUInt64ObjectDictionary<NSString*> *dict2 =
3510       [[GPBUInt64ObjectDictionary alloc] initWithDictionary:dict];
3511   XCTAssertNotNil(dict2);
3513   // Should be new pointer, but equal objects.
3514   XCTAssertNotEqual(dict, dict2);
3515   XCTAssertEqualObjects(dict, dict2);
3516   [dict2 release];
3517   [dict release];
3520 - (void)testAdds {
3521   GPBUInt64ObjectDictionary<NSString*> *dict = [[GPBUInt64ObjectDictionary alloc] init];
3522   XCTAssertNotNil(dict);
3524   XCTAssertEqual(dict.count, 0U);
3525   [dict setObject:@"abc" forKey:31ULL];
3526   XCTAssertEqual(dict.count, 1U);
3528   const uint64_t kKeys[] = { 32ULL, 33ULL, 34ULL };
3529   const NSString* kObjects[] = { @"def", @"ghi", @"jkl" };
3530   GPBUInt64ObjectDictionary<NSString*> *dict2 =
3531       [[GPBUInt64ObjectDictionary alloc] initWithObjects:kObjects
3532                                                  forKeys:kKeys
3533                                                    count:GPBARRAYSIZE(kObjects)];
3534   XCTAssertNotNil(dict2);
3535   [dict addEntriesFromDictionary:dict2];
3536   XCTAssertEqual(dict.count, 4U);
3538   XCTAssertEqualObjects([dict objectForKey:31ULL], @"abc");
3539   XCTAssertEqualObjects([dict objectForKey:32ULL], @"def");
3540   XCTAssertEqualObjects([dict objectForKey:33ULL], @"ghi");
3541   XCTAssertEqualObjects([dict objectForKey:34ULL], @"jkl");
3542   [dict2 release];
3543   [dict release];
3546 - (void)testRemove {
3547   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
3548   const NSString* kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
3549   GPBUInt64ObjectDictionary<NSString*> *dict =
3550       [[GPBUInt64ObjectDictionary alloc] initWithObjects:kObjects
3551                                                  forKeys:kKeys
3552                                                    count:GPBARRAYSIZE(kObjects)];
3553   XCTAssertNotNil(dict);
3554   XCTAssertEqual(dict.count, 4U);
3556   [dict removeObjectForKey:32ULL];
3557   XCTAssertEqual(dict.count, 3U);
3558   XCTAssertEqualObjects([dict objectForKey:31ULL], @"abc");
3559   XCTAssertNil([dict objectForKey:32ULL]);
3560   XCTAssertEqualObjects([dict objectForKey:33ULL], @"ghi");
3561   XCTAssertEqualObjects([dict objectForKey:34ULL], @"jkl");
3563   // Remove again does nothing.
3564   [dict removeObjectForKey:32ULL];
3565   XCTAssertEqual(dict.count, 3U);
3566   XCTAssertEqualObjects([dict objectForKey:31ULL], @"abc");
3567   XCTAssertNil([dict objectForKey:32ULL]);
3568   XCTAssertEqualObjects([dict objectForKey:33ULL], @"ghi");
3569   XCTAssertEqualObjects([dict objectForKey:34ULL], @"jkl");
3571   [dict removeObjectForKey:34ULL];
3572   XCTAssertEqual(dict.count, 2U);
3573   XCTAssertEqualObjects([dict objectForKey:31ULL], @"abc");
3574   XCTAssertNil([dict objectForKey:32ULL]);
3575   XCTAssertEqualObjects([dict objectForKey:33ULL], @"ghi");
3576   XCTAssertNil([dict objectForKey:34ULL]);
3578   [dict removeAll];
3579   XCTAssertEqual(dict.count, 0U);
3580   XCTAssertNil([dict objectForKey:31ULL]);
3581   XCTAssertNil([dict objectForKey:32ULL]);
3582   XCTAssertNil([dict objectForKey:33ULL]);
3583   XCTAssertNil([dict objectForKey:34ULL]);
3584   [dict release];
3587 - (void)testInplaceMutation {
3588   const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
3589   const NSString* kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
3590   GPBUInt64ObjectDictionary<NSString*> *dict =
3591       [[GPBUInt64ObjectDictionary alloc] initWithObjects:kObjects
3592                                                  forKeys:kKeys
3593                                                    count:GPBARRAYSIZE(kObjects)];
3594   XCTAssertNotNil(dict);
3595   XCTAssertEqual(dict.count, 4U);
3596   XCTAssertEqualObjects([dict objectForKey:31ULL], @"abc");
3597   XCTAssertEqualObjects([dict objectForKey:32ULL], @"def");
3598   XCTAssertEqualObjects([dict objectForKey:33ULL], @"ghi");
3599   XCTAssertEqualObjects([dict objectForKey:34ULL], @"jkl");
3601   [dict setObject:@"jkl" forKey:31ULL];
3602   XCTAssertEqual(dict.count, 4U);
3603   XCTAssertEqualObjects([dict objectForKey:31ULL], @"jkl");
3604   XCTAssertEqualObjects([dict objectForKey:32ULL], @"def");
3605   XCTAssertEqualObjects([dict objectForKey:33ULL], @"ghi");
3606   XCTAssertEqualObjects([dict objectForKey:34ULL], @"jkl");
3608   [dict setObject:@"def" forKey:34ULL];
3609   XCTAssertEqual(dict.count, 4U);
3610   XCTAssertEqualObjects([dict objectForKey:31ULL], @"jkl");
3611   XCTAssertEqualObjects([dict objectForKey:32ULL], @"def");
3612   XCTAssertEqualObjects([dict objectForKey:33ULL], @"ghi");
3613   XCTAssertEqualObjects([dict objectForKey:34ULL], @"def");
3615   const uint64_t kKeys2[] = { 32ULL, 33ULL };
3616   const NSString* kObjects2[] = { @"ghi", @"abc" };
3617   GPBUInt64ObjectDictionary<NSString*> *dict2 =
3618       [[GPBUInt64ObjectDictionary alloc] initWithObjects:kObjects2
3619                                                  forKeys:kKeys2
3620                                                    count:GPBARRAYSIZE(kObjects2)];
3621   XCTAssertNotNil(dict2);
3622   [dict addEntriesFromDictionary:dict2];
3623   XCTAssertEqual(dict.count, 4U);
3624   XCTAssertEqualObjects([dict objectForKey:31ULL], @"jkl");
3625   XCTAssertEqualObjects([dict objectForKey:32ULL], @"ghi");
3626   XCTAssertEqualObjects([dict objectForKey:33ULL], @"abc");
3627   XCTAssertEqualObjects([dict objectForKey:34ULL], @"def");
3629   [dict2 release];
3630   [dict release];
3633 @end
3635 //%PDDM-EXPAND-END TEST_FOR_POD_KEY(UInt64, uint64_t, 31ULL, 32ULL, 33ULL, 34ULL)