Pull new version of protobuf sources.
[chromium-blink-merge.git] / third_party / protobuf / objectivec / Tests / GPBDictionaryTests+Int64.m
blob4a94e0337d871b1482b58dcd960b15dfd183a5da
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2015 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #import <Foundation/Foundation.h>
32 #import <XCTest/XCTest.h>
34 #import "GPBDictionary.h"
36 #import "GPBTestUtilities.h"
37 #import "google/protobuf/UnittestRuntimeProto2.pbobjc.h"
39 // Pull in the macros (using an external file because expanding all tests
40 // in a single file makes a file that is failing to work with within Xcode.
41 //%PDDM-IMPORT-DEFINES GPBDictionaryTests.pddm
43 //%PDDM-EXPAND TEST_FOR_POD_KEY(Int64, int64_t, 21LL, 22LL, 23LL, 24LL)
44 // This block of code is generated, do not edit it directly.
46 // To let the testing macros work, add some extra methods to simplify things.
47 @interface GPBInt64EnumDictionary (TestingTweak)
48 + (instancetype)dictionaryWithValue:(int32_t)value forKey:(int64_t)key;
49 - (instancetype)initWithValues:(const int32_t [])values
50                        forKeys:(const int64_t [])keys
51                          count:(NSUInteger)count;
52 @end
54 static BOOL TestingEnum_IsValidValue(int32_t value) {
55   switch (value) {
56     case 700:
57     case 701:
58     case 702:
59     case 703:
60       return YES;
61     default:
62       return NO;
63   }
66 @implementation GPBInt64EnumDictionary (TestingTweak)
67 + (instancetype)dictionaryWithValue:(int32_t)value forKey:(int64_t)key {
68   // Cast is needed to compiler knows what class we are invoking initWithValues: on to get the
69   // type correct.
70   return [[(GPBInt64EnumDictionary*)[self alloc] initWithValidationFunction:TestingEnum_IsValidValue
71                                                                   rawValues:&value
72                                                                     forKeys:&key
73                                                                       count:1] autorelease];
75 - (instancetype)initWithValues:(const int32_t [])values
76                        forKeys:(const int64_t [])keys
77                          count:(NSUInteger)count {
78   return [self initWithValidationFunction:TestingEnum_IsValidValue
79                                 rawValues:values
80                                   forKeys:keys
81                                     count:count];
83 @end
86 #pragma mark - Int64 -> UInt32
88 @interface GPBInt64UInt32DictionaryTests : XCTestCase
89 @end
91 @implementation GPBInt64UInt32DictionaryTests
93 - (void)testEmpty {
94   GPBInt64UInt32Dictionary *dict = [[GPBInt64UInt32Dictionary alloc] init];
95   XCTAssertNotNil(dict);
96   XCTAssertEqual(dict.count, 0U);
97   XCTAssertFalse([dict valueForKey:21LL value:NULL]);
98   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, uint32_t aValue, BOOL *stop) {
99     #pragma unused(aKey, aValue, stop)
100     XCTFail(@"Shouldn't get here!");
101   }];
102   [dict release];
105 - (void)testOne {
106   GPBInt64UInt32Dictionary *dict = [GPBInt64UInt32Dictionary dictionaryWithValue:100U forKey:21LL];
107   XCTAssertNotNil(dict);
108   XCTAssertEqual(dict.count, 1U);
109   uint32_t value;
110   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
111   XCTAssertTrue([dict valueForKey:21LL value:&value]);
112   XCTAssertEqual(value, 100U);
113   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
114   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, uint32_t aValue, BOOL *stop) {
115     XCTAssertEqual(aKey, 21LL);
116     XCTAssertEqual(aValue, 100U);
117     XCTAssertNotEqual(stop, NULL);
118   }];
121 - (void)testBasics {
122   const int64_t kKeys[] = { 21LL, 22LL, 23LL };
123   const uint32_t kValues[] = { 100U, 101U, 102U };
124   GPBInt64UInt32Dictionary *dict =
125       [[GPBInt64UInt32Dictionary alloc] initWithValues:kValues
126                                                forKeys:kKeys
127                                                  count:GPBARRAYSIZE(kValues)];
128   XCTAssertNotNil(dict);
129   XCTAssertEqual(dict.count, 3U);
130   uint32_t value;
131   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
132   XCTAssertTrue([dict valueForKey:21LL value:&value]);
133   XCTAssertEqual(value, 100U);
134   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
135   XCTAssertTrue([dict valueForKey:22LL value:&value]);
136   XCTAssertEqual(value, 101U);
137   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
138   XCTAssertTrue([dict valueForKey:23LL value:&value]);
139   XCTAssertEqual(value, 102U);
140   XCTAssertFalse([dict valueForKey:24LL value:NULL]);
142   __block NSUInteger idx = 0;
143   int64_t *seenKeys = malloc(3 * sizeof(int64_t));
144   uint32_t *seenValues = malloc(3 * sizeof(uint32_t));
145   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, uint32_t aValue, BOOL *stop) {
146     XCTAssertLessThan(idx, 3U);
147     seenKeys[idx] = aKey;
148     seenValues[idx] = aValue;
149     XCTAssertNotEqual(stop, NULL);
150     ++idx;
151   }];
152   for (int i = 0; i < 3; ++i) {
153     BOOL foundKey = NO;
154     for (int j = 0; (j < 3) && !foundKey; ++j) {
155       if (kKeys[i] == seenKeys[j]) {
156         foundKey = YES;
157         XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
158       }
159     }
160     XCTAssertTrue(foundKey, @"i = %d", i);
161   }
162   free(seenKeys);
163   free(seenValues);
165   // Stopping the enumeration.
166   idx = 0;
167   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, uint32_t aValue, BOOL *stop) {
168     #pragma unused(aKey, aValue)
169     if (idx == 1) *stop = YES;
170     XCTAssertNotEqual(idx, 2U);
171     ++idx;
172   }];
173   [dict release];
176 - (void)testEquality {
177   const int64_t kKeys1[] = { 21LL, 22LL, 23LL, 24LL };
178   const int64_t kKeys2[] = { 22LL, 21LL, 24LL };
179   const uint32_t kValues1[] = { 100U, 101U, 102U };
180   const uint32_t kValues2[] = { 100U, 103U, 102U };
181   const uint32_t kValues3[] = { 100U, 101U, 102U, 103U };
182   GPBInt64UInt32Dictionary *dict1 =
183       [[GPBInt64UInt32Dictionary alloc] initWithValues:kValues1
184                                                forKeys:kKeys1
185                                                  count:GPBARRAYSIZE(kValues1)];
186   XCTAssertNotNil(dict1);
187   GPBInt64UInt32Dictionary *dict1prime =
188       [[GPBInt64UInt32Dictionary alloc] initWithValues:kValues1
189                                                forKeys:kKeys1
190                                                  count:GPBARRAYSIZE(kValues1)];
191   XCTAssertNotNil(dict1prime);
192   GPBInt64UInt32Dictionary *dict2 =
193       [[GPBInt64UInt32Dictionary alloc] initWithValues:kValues2
194                                                forKeys:kKeys1
195                                                  count:GPBARRAYSIZE(kValues2)];
196   XCTAssertNotNil(dict2);
197   GPBInt64UInt32Dictionary *dict3 =
198       [[GPBInt64UInt32Dictionary alloc] initWithValues:kValues1
199                                                forKeys:kKeys2
200                                                  count:GPBARRAYSIZE(kValues1)];
201   XCTAssertNotNil(dict3);
202   GPBInt64UInt32Dictionary *dict4 =
203       [[GPBInt64UInt32Dictionary alloc] initWithValues:kValues3
204                                                forKeys:kKeys1
205                                                  count:GPBARRAYSIZE(kValues3)];
206   XCTAssertNotNil(dict4);
208   // 1/1Prime should be different objects, but equal.
209   XCTAssertNotEqual(dict1, dict1prime);
210   XCTAssertEqualObjects(dict1, dict1prime);
211   // Equal, so they must have same hash.
212   XCTAssertEqual([dict1 hash], [dict1prime hash]);
214   // 2 is save keys, different values; not equal.
215   XCTAssertNotEqualObjects(dict1, dict2);
217   // 3 is different keys, samae values; not equal.
218   XCTAssertNotEqualObjects(dict1, dict3);
220   // 4 extra pair; not equal
221   XCTAssertNotEqualObjects(dict1, dict4);
223   [dict1 release];
224   [dict1prime release];
225   [dict2 release];
226   [dict3 release];
227   [dict4 release];
230 - (void)testCopy {
231   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
232   const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
233   GPBInt64UInt32Dictionary *dict =
234       [[GPBInt64UInt32Dictionary alloc] initWithValues:kValues
235                                                forKeys:kKeys
236                                                  count:GPBARRAYSIZE(kValues)];
237   XCTAssertNotNil(dict);
239   GPBInt64UInt32Dictionary *dict2 = [dict copy];
240   XCTAssertNotNil(dict2);
242   // Should be new object but equal.
243   XCTAssertNotEqual(dict, dict2);
244   XCTAssertEqualObjects(dict, dict2);
245   XCTAssertTrue([dict2 isKindOfClass:[GPBInt64UInt32Dictionary class]]);
247   [dict2 release];
248   [dict release];
251 - (void)testDictionaryFromDictionary {
252   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
253   const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
254   GPBInt64UInt32Dictionary *dict =
255       [[GPBInt64UInt32Dictionary alloc] initWithValues:kValues
256                                                forKeys:kKeys
257                                                  count:GPBARRAYSIZE(kValues)];
258   XCTAssertNotNil(dict);
260   GPBInt64UInt32Dictionary *dict2 =
261       [GPBInt64UInt32Dictionary dictionaryWithDictionary:dict];
262   XCTAssertNotNil(dict2);
264   // Should be new pointer, but equal objects.
265   XCTAssertNotEqual(dict, dict2);
266   XCTAssertEqualObjects(dict, dict2);
267   [dict release];
270 - (void)testAdds {
271   GPBInt64UInt32Dictionary *dict = [GPBInt64UInt32Dictionary dictionary];
272   XCTAssertNotNil(dict);
274   XCTAssertEqual(dict.count, 0U);
275   [dict setValue:100U forKey:21LL];
276   XCTAssertEqual(dict.count, 1U);
278   const int64_t kKeys[] = { 22LL, 23LL, 24LL };
279   const uint32_t kValues[] = { 101U, 102U, 103U };
280   GPBInt64UInt32Dictionary *dict2 =
281       [[GPBInt64UInt32Dictionary alloc] initWithValues:kValues
282                                                forKeys:kKeys
283                                                  count:GPBARRAYSIZE(kValues)];
284   XCTAssertNotNil(dict2);
285   [dict addEntriesFromDictionary:dict2];
286   XCTAssertEqual(dict.count, 4U);
288   uint32_t value;
289   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
290   XCTAssertTrue([dict valueForKey:21LL value:&value]);
291   XCTAssertEqual(value, 100U);
292   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
293   XCTAssertTrue([dict valueForKey:22LL value:&value]);
294   XCTAssertEqual(value, 101U);
295   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
296   XCTAssertTrue([dict valueForKey:23LL value:&value]);
297   XCTAssertEqual(value, 102U);
298   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
299   XCTAssertTrue([dict valueForKey:24LL value:&value]);
300   XCTAssertEqual(value, 103U);
301   [dict2 release];
304 - (void)testRemove {
305   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
306   const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
307   GPBInt64UInt32Dictionary *dict =
308       [[GPBInt64UInt32Dictionary alloc] initWithValues:kValues
309                                         forKeys:kKeys
310                                           count:GPBARRAYSIZE(kValues)];
311   XCTAssertNotNil(dict);
312   XCTAssertEqual(dict.count, 4U);
314   [dict removeValueForKey:22LL];
315   XCTAssertEqual(dict.count, 3U);
316   uint32_t value;
317   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
318   XCTAssertTrue([dict valueForKey:21LL value:&value]);
319   XCTAssertEqual(value, 100U);
320   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
321   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
322   XCTAssertTrue([dict valueForKey:23LL value:&value]);
323   XCTAssertEqual(value, 102U);
324   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
325   XCTAssertTrue([dict valueForKey:24LL value:&value]);
326   XCTAssertEqual(value, 103U);
328   // Remove again does nothing.
329   [dict removeValueForKey:22LL];
330   XCTAssertEqual(dict.count, 3U);
331   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
332   XCTAssertTrue([dict valueForKey:21LL value:&value]);
333   XCTAssertEqual(value, 100U);
334   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
335   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
336   XCTAssertTrue([dict valueForKey:23LL value:&value]);
337   XCTAssertEqual(value, 102U);
338   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
339   XCTAssertTrue([dict valueForKey:24LL value:&value]);
340   XCTAssertEqual(value, 103U);
342   [dict removeValueForKey:24LL];
343   XCTAssertEqual(dict.count, 2U);
344   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
345   XCTAssertTrue([dict valueForKey:21LL value:&value]);
346   XCTAssertEqual(value, 100U);
347   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
348   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
349   XCTAssertTrue([dict valueForKey:23LL value:&value]);
350   XCTAssertEqual(value, 102U);
351   XCTAssertFalse([dict valueForKey:24LL value:NULL]);
353   [dict removeAll];
354   XCTAssertEqual(dict.count, 0U);
355   XCTAssertFalse([dict valueForKey:21LL value:NULL]);
356   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
357   XCTAssertFalse([dict valueForKey:23LL value:NULL]);
358   XCTAssertFalse([dict valueForKey:24LL value:NULL]);
359   [dict release];
362 - (void)testInplaceMutation {
363   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
364   const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
365   GPBInt64UInt32Dictionary *dict =
366       [[GPBInt64UInt32Dictionary alloc] initWithValues:kValues
367                                         forKeys:kKeys
368                                           count:GPBARRAYSIZE(kValues)];
369   XCTAssertNotNil(dict);
370   XCTAssertEqual(dict.count, 4U);
371   uint32_t value;
372   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
373   XCTAssertTrue([dict valueForKey:21LL value:&value]);
374   XCTAssertEqual(value, 100U);
375   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
376   XCTAssertTrue([dict valueForKey:22LL value:&value]);
377   XCTAssertEqual(value, 101U);
378   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
379   XCTAssertTrue([dict valueForKey:23LL value:&value]);
380   XCTAssertEqual(value, 102U);
381   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
382   XCTAssertTrue([dict valueForKey:24LL value:&value]);
383   XCTAssertEqual(value, 103U);
385   [dict setValue:103U forKey:21LL];
386   XCTAssertEqual(dict.count, 4U);
387   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
388   XCTAssertTrue([dict valueForKey:21LL value:&value]);
389   XCTAssertEqual(value, 103U);
390   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
391   XCTAssertTrue([dict valueForKey:22LL value:&value]);
392   XCTAssertEqual(value, 101U);
393   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
394   XCTAssertTrue([dict valueForKey:23LL value:&value]);
395   XCTAssertEqual(value, 102U);
396   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
397   XCTAssertTrue([dict valueForKey:24LL value:&value]);
398   XCTAssertEqual(value, 103U);
400   [dict setValue:101U forKey:24LL];
401   XCTAssertEqual(dict.count, 4U);
402   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
403   XCTAssertTrue([dict valueForKey:21LL value:&value]);
404   XCTAssertEqual(value, 103U);
405   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
406   XCTAssertTrue([dict valueForKey:22LL value:&value]);
407   XCTAssertEqual(value, 101U);
408   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
409   XCTAssertTrue([dict valueForKey:23LL value:&value]);
410   XCTAssertEqual(value, 102U);
411   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
412   XCTAssertTrue([dict valueForKey:24LL value:&value]);
413   XCTAssertEqual(value, 101U);
415   const int64_t kKeys2[] = { 22LL, 23LL };
416   const uint32_t kValues2[] = { 102U, 100U };
417   GPBInt64UInt32Dictionary *dict2 =
418       [[GPBInt64UInt32Dictionary alloc] initWithValues:kValues2
419                                                forKeys:kKeys2
420                                                  count:GPBARRAYSIZE(kValues2)];
421   XCTAssertNotNil(dict2);
422   [dict addEntriesFromDictionary:dict2];
423   XCTAssertEqual(dict.count, 4U);
424   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
425   XCTAssertTrue([dict valueForKey:21LL value:&value]);
426   XCTAssertEqual(value, 103U);
427   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
428   XCTAssertTrue([dict valueForKey:22LL value:&value]);
429   XCTAssertEqual(value, 102U);
430   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
431   XCTAssertTrue([dict valueForKey:23LL value:&value]);
432   XCTAssertEqual(value, 100U);
433   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
434   XCTAssertTrue([dict valueForKey:24LL value:&value]);
435   XCTAssertEqual(value, 101U);
437   [dict2 release];
438   [dict release];
441 @end
443 #pragma mark - Int64 -> Int32
445 @interface GPBInt64Int32DictionaryTests : XCTestCase
446 @end
448 @implementation GPBInt64Int32DictionaryTests
450 - (void)testEmpty {
451   GPBInt64Int32Dictionary *dict = [[GPBInt64Int32Dictionary alloc] init];
452   XCTAssertNotNil(dict);
453   XCTAssertEqual(dict.count, 0U);
454   XCTAssertFalse([dict valueForKey:21LL value:NULL]);
455   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
456     #pragma unused(aKey, aValue, stop)
457     XCTFail(@"Shouldn't get here!");
458   }];
459   [dict release];
462 - (void)testOne {
463   GPBInt64Int32Dictionary *dict = [GPBInt64Int32Dictionary dictionaryWithValue:200 forKey:21LL];
464   XCTAssertNotNil(dict);
465   XCTAssertEqual(dict.count, 1U);
466   int32_t value;
467   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
468   XCTAssertTrue([dict valueForKey:21LL value:&value]);
469   XCTAssertEqual(value, 200);
470   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
471   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
472     XCTAssertEqual(aKey, 21LL);
473     XCTAssertEqual(aValue, 200);
474     XCTAssertNotEqual(stop, NULL);
475   }];
478 - (void)testBasics {
479   const int64_t kKeys[] = { 21LL, 22LL, 23LL };
480   const int32_t kValues[] = { 200, 201, 202 };
481   GPBInt64Int32Dictionary *dict =
482       [[GPBInt64Int32Dictionary alloc] initWithValues:kValues
483                                               forKeys:kKeys
484                                                 count:GPBARRAYSIZE(kValues)];
485   XCTAssertNotNil(dict);
486   XCTAssertEqual(dict.count, 3U);
487   int32_t value;
488   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
489   XCTAssertTrue([dict valueForKey:21LL value:&value]);
490   XCTAssertEqual(value, 200);
491   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
492   XCTAssertTrue([dict valueForKey:22LL value:&value]);
493   XCTAssertEqual(value, 201);
494   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
495   XCTAssertTrue([dict valueForKey:23LL value:&value]);
496   XCTAssertEqual(value, 202);
497   XCTAssertFalse([dict valueForKey:24LL value:NULL]);
499   __block NSUInteger idx = 0;
500   int64_t *seenKeys = malloc(3 * sizeof(int64_t));
501   int32_t *seenValues = malloc(3 * sizeof(int32_t));
502   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
503     XCTAssertLessThan(idx, 3U);
504     seenKeys[idx] = aKey;
505     seenValues[idx] = aValue;
506     XCTAssertNotEqual(stop, NULL);
507     ++idx;
508   }];
509   for (int i = 0; i < 3; ++i) {
510     BOOL foundKey = NO;
511     for (int j = 0; (j < 3) && !foundKey; ++j) {
512       if (kKeys[i] == seenKeys[j]) {
513         foundKey = YES;
514         XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
515       }
516     }
517     XCTAssertTrue(foundKey, @"i = %d", i);
518   }
519   free(seenKeys);
520   free(seenValues);
522   // Stopping the enumeration.
523   idx = 0;
524   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
525     #pragma unused(aKey, aValue)
526     if (idx == 1) *stop = YES;
527     XCTAssertNotEqual(idx, 2U);
528     ++idx;
529   }];
530   [dict release];
533 - (void)testEquality {
534   const int64_t kKeys1[] = { 21LL, 22LL, 23LL, 24LL };
535   const int64_t kKeys2[] = { 22LL, 21LL, 24LL };
536   const int32_t kValues1[] = { 200, 201, 202 };
537   const int32_t kValues2[] = { 200, 203, 202 };
538   const int32_t kValues3[] = { 200, 201, 202, 203 };
539   GPBInt64Int32Dictionary *dict1 =
540       [[GPBInt64Int32Dictionary alloc] initWithValues:kValues1
541                                               forKeys:kKeys1
542                                                 count:GPBARRAYSIZE(kValues1)];
543   XCTAssertNotNil(dict1);
544   GPBInt64Int32Dictionary *dict1prime =
545       [[GPBInt64Int32Dictionary alloc] initWithValues:kValues1
546                                               forKeys:kKeys1
547                                                 count:GPBARRAYSIZE(kValues1)];
548   XCTAssertNotNil(dict1prime);
549   GPBInt64Int32Dictionary *dict2 =
550       [[GPBInt64Int32Dictionary alloc] initWithValues:kValues2
551                                               forKeys:kKeys1
552                                                 count:GPBARRAYSIZE(kValues2)];
553   XCTAssertNotNil(dict2);
554   GPBInt64Int32Dictionary *dict3 =
555       [[GPBInt64Int32Dictionary alloc] initWithValues:kValues1
556                                               forKeys:kKeys2
557                                                 count:GPBARRAYSIZE(kValues1)];
558   XCTAssertNotNil(dict3);
559   GPBInt64Int32Dictionary *dict4 =
560       [[GPBInt64Int32Dictionary alloc] initWithValues:kValues3
561                                               forKeys:kKeys1
562                                                 count:GPBARRAYSIZE(kValues3)];
563   XCTAssertNotNil(dict4);
565   // 1/1Prime should be different objects, but equal.
566   XCTAssertNotEqual(dict1, dict1prime);
567   XCTAssertEqualObjects(dict1, dict1prime);
568   // Equal, so they must have same hash.
569   XCTAssertEqual([dict1 hash], [dict1prime hash]);
571   // 2 is save keys, different values; not equal.
572   XCTAssertNotEqualObjects(dict1, dict2);
574   // 3 is different keys, samae values; not equal.
575   XCTAssertNotEqualObjects(dict1, dict3);
577   // 4 extra pair; not equal
578   XCTAssertNotEqualObjects(dict1, dict4);
580   [dict1 release];
581   [dict1prime release];
582   [dict2 release];
583   [dict3 release];
584   [dict4 release];
587 - (void)testCopy {
588   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
589   const int32_t kValues[] = { 200, 201, 202, 203 };
590   GPBInt64Int32Dictionary *dict =
591       [[GPBInt64Int32Dictionary alloc] initWithValues:kValues
592                                               forKeys:kKeys
593                                                 count:GPBARRAYSIZE(kValues)];
594   XCTAssertNotNil(dict);
596   GPBInt64Int32Dictionary *dict2 = [dict copy];
597   XCTAssertNotNil(dict2);
599   // Should be new object but equal.
600   XCTAssertNotEqual(dict, dict2);
601   XCTAssertEqualObjects(dict, dict2);
602   XCTAssertTrue([dict2 isKindOfClass:[GPBInt64Int32Dictionary class]]);
604   [dict2 release];
605   [dict release];
608 - (void)testDictionaryFromDictionary {
609   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
610   const int32_t kValues[] = { 200, 201, 202, 203 };
611   GPBInt64Int32Dictionary *dict =
612       [[GPBInt64Int32Dictionary alloc] initWithValues:kValues
613                                               forKeys:kKeys
614                                                 count:GPBARRAYSIZE(kValues)];
615   XCTAssertNotNil(dict);
617   GPBInt64Int32Dictionary *dict2 =
618       [GPBInt64Int32Dictionary dictionaryWithDictionary:dict];
619   XCTAssertNotNil(dict2);
621   // Should be new pointer, but equal objects.
622   XCTAssertNotEqual(dict, dict2);
623   XCTAssertEqualObjects(dict, dict2);
624   [dict release];
627 - (void)testAdds {
628   GPBInt64Int32Dictionary *dict = [GPBInt64Int32Dictionary dictionary];
629   XCTAssertNotNil(dict);
631   XCTAssertEqual(dict.count, 0U);
632   [dict setValue:200 forKey:21LL];
633   XCTAssertEqual(dict.count, 1U);
635   const int64_t kKeys[] = { 22LL, 23LL, 24LL };
636   const int32_t kValues[] = { 201, 202, 203 };
637   GPBInt64Int32Dictionary *dict2 =
638       [[GPBInt64Int32Dictionary alloc] initWithValues:kValues
639                                               forKeys:kKeys
640                                                 count:GPBARRAYSIZE(kValues)];
641   XCTAssertNotNil(dict2);
642   [dict addEntriesFromDictionary:dict2];
643   XCTAssertEqual(dict.count, 4U);
645   int32_t value;
646   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
647   XCTAssertTrue([dict valueForKey:21LL value:&value]);
648   XCTAssertEqual(value, 200);
649   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
650   XCTAssertTrue([dict valueForKey:22LL value:&value]);
651   XCTAssertEqual(value, 201);
652   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
653   XCTAssertTrue([dict valueForKey:23LL value:&value]);
654   XCTAssertEqual(value, 202);
655   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
656   XCTAssertTrue([dict valueForKey:24LL value:&value]);
657   XCTAssertEqual(value, 203);
658   [dict2 release];
661 - (void)testRemove {
662   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
663   const int32_t kValues[] = { 200, 201, 202, 203 };
664   GPBInt64Int32Dictionary *dict =
665       [[GPBInt64Int32Dictionary alloc] initWithValues:kValues
666                                        forKeys:kKeys
667                                          count:GPBARRAYSIZE(kValues)];
668   XCTAssertNotNil(dict);
669   XCTAssertEqual(dict.count, 4U);
671   [dict removeValueForKey:22LL];
672   XCTAssertEqual(dict.count, 3U);
673   int32_t value;
674   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
675   XCTAssertTrue([dict valueForKey:21LL value:&value]);
676   XCTAssertEqual(value, 200);
677   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
678   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
679   XCTAssertTrue([dict valueForKey:23LL value:&value]);
680   XCTAssertEqual(value, 202);
681   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
682   XCTAssertTrue([dict valueForKey:24LL value:&value]);
683   XCTAssertEqual(value, 203);
685   // Remove again does nothing.
686   [dict removeValueForKey:22LL];
687   XCTAssertEqual(dict.count, 3U);
688   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
689   XCTAssertTrue([dict valueForKey:21LL value:&value]);
690   XCTAssertEqual(value, 200);
691   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
692   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
693   XCTAssertTrue([dict valueForKey:23LL value:&value]);
694   XCTAssertEqual(value, 202);
695   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
696   XCTAssertTrue([dict valueForKey:24LL value:&value]);
697   XCTAssertEqual(value, 203);
699   [dict removeValueForKey:24LL];
700   XCTAssertEqual(dict.count, 2U);
701   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
702   XCTAssertTrue([dict valueForKey:21LL value:&value]);
703   XCTAssertEqual(value, 200);
704   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
705   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
706   XCTAssertTrue([dict valueForKey:23LL value:&value]);
707   XCTAssertEqual(value, 202);
708   XCTAssertFalse([dict valueForKey:24LL value:NULL]);
710   [dict removeAll];
711   XCTAssertEqual(dict.count, 0U);
712   XCTAssertFalse([dict valueForKey:21LL value:NULL]);
713   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
714   XCTAssertFalse([dict valueForKey:23LL value:NULL]);
715   XCTAssertFalse([dict valueForKey:24LL value:NULL]);
716   [dict release];
719 - (void)testInplaceMutation {
720   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
721   const int32_t kValues[] = { 200, 201, 202, 203 };
722   GPBInt64Int32Dictionary *dict =
723       [[GPBInt64Int32Dictionary alloc] initWithValues:kValues
724                                        forKeys:kKeys
725                                          count:GPBARRAYSIZE(kValues)];
726   XCTAssertNotNil(dict);
727   XCTAssertEqual(dict.count, 4U);
728   int32_t value;
729   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
730   XCTAssertTrue([dict valueForKey:21LL value:&value]);
731   XCTAssertEqual(value, 200);
732   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
733   XCTAssertTrue([dict valueForKey:22LL value:&value]);
734   XCTAssertEqual(value, 201);
735   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
736   XCTAssertTrue([dict valueForKey:23LL value:&value]);
737   XCTAssertEqual(value, 202);
738   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
739   XCTAssertTrue([dict valueForKey:24LL value:&value]);
740   XCTAssertEqual(value, 203);
742   [dict setValue:203 forKey:21LL];
743   XCTAssertEqual(dict.count, 4U);
744   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
745   XCTAssertTrue([dict valueForKey:21LL value:&value]);
746   XCTAssertEqual(value, 203);
747   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
748   XCTAssertTrue([dict valueForKey:22LL value:&value]);
749   XCTAssertEqual(value, 201);
750   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
751   XCTAssertTrue([dict valueForKey:23LL value:&value]);
752   XCTAssertEqual(value, 202);
753   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
754   XCTAssertTrue([dict valueForKey:24LL value:&value]);
755   XCTAssertEqual(value, 203);
757   [dict setValue:201 forKey:24LL];
758   XCTAssertEqual(dict.count, 4U);
759   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
760   XCTAssertTrue([dict valueForKey:21LL value:&value]);
761   XCTAssertEqual(value, 203);
762   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
763   XCTAssertTrue([dict valueForKey:22LL value:&value]);
764   XCTAssertEqual(value, 201);
765   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
766   XCTAssertTrue([dict valueForKey:23LL value:&value]);
767   XCTAssertEqual(value, 202);
768   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
769   XCTAssertTrue([dict valueForKey:24LL value:&value]);
770   XCTAssertEqual(value, 201);
772   const int64_t kKeys2[] = { 22LL, 23LL };
773   const int32_t kValues2[] = { 202, 200 };
774   GPBInt64Int32Dictionary *dict2 =
775       [[GPBInt64Int32Dictionary alloc] initWithValues:kValues2
776                                               forKeys:kKeys2
777                                                 count:GPBARRAYSIZE(kValues2)];
778   XCTAssertNotNil(dict2);
779   [dict addEntriesFromDictionary:dict2];
780   XCTAssertEqual(dict.count, 4U);
781   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
782   XCTAssertTrue([dict valueForKey:21LL value:&value]);
783   XCTAssertEqual(value, 203);
784   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
785   XCTAssertTrue([dict valueForKey:22LL value:&value]);
786   XCTAssertEqual(value, 202);
787   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
788   XCTAssertTrue([dict valueForKey:23LL value:&value]);
789   XCTAssertEqual(value, 200);
790   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
791   XCTAssertTrue([dict valueForKey:24LL value:&value]);
792   XCTAssertEqual(value, 201);
794   [dict2 release];
795   [dict release];
798 @end
800 #pragma mark - Int64 -> UInt64
802 @interface GPBInt64UInt64DictionaryTests : XCTestCase
803 @end
805 @implementation GPBInt64UInt64DictionaryTests
807 - (void)testEmpty {
808   GPBInt64UInt64Dictionary *dict = [[GPBInt64UInt64Dictionary alloc] init];
809   XCTAssertNotNil(dict);
810   XCTAssertEqual(dict.count, 0U);
811   XCTAssertFalse([dict valueForKey:21LL value:NULL]);
812   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, uint64_t aValue, BOOL *stop) {
813     #pragma unused(aKey, aValue, stop)
814     XCTFail(@"Shouldn't get here!");
815   }];
816   [dict release];
819 - (void)testOne {
820   GPBInt64UInt64Dictionary *dict = [GPBInt64UInt64Dictionary dictionaryWithValue:300U forKey:21LL];
821   XCTAssertNotNil(dict);
822   XCTAssertEqual(dict.count, 1U);
823   uint64_t value;
824   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
825   XCTAssertTrue([dict valueForKey:21LL value:&value]);
826   XCTAssertEqual(value, 300U);
827   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
828   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, uint64_t aValue, BOOL *stop) {
829     XCTAssertEqual(aKey, 21LL);
830     XCTAssertEqual(aValue, 300U);
831     XCTAssertNotEqual(stop, NULL);
832   }];
835 - (void)testBasics {
836   const int64_t kKeys[] = { 21LL, 22LL, 23LL };
837   const uint64_t kValues[] = { 300U, 301U, 302U };
838   GPBInt64UInt64Dictionary *dict =
839       [[GPBInt64UInt64Dictionary alloc] initWithValues:kValues
840                                                forKeys:kKeys
841                                                  count:GPBARRAYSIZE(kValues)];
842   XCTAssertNotNil(dict);
843   XCTAssertEqual(dict.count, 3U);
844   uint64_t value;
845   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
846   XCTAssertTrue([dict valueForKey:21LL value:&value]);
847   XCTAssertEqual(value, 300U);
848   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
849   XCTAssertTrue([dict valueForKey:22LL value:&value]);
850   XCTAssertEqual(value, 301U);
851   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
852   XCTAssertTrue([dict valueForKey:23LL value:&value]);
853   XCTAssertEqual(value, 302U);
854   XCTAssertFalse([dict valueForKey:24LL value:NULL]);
856   __block NSUInteger idx = 0;
857   int64_t *seenKeys = malloc(3 * sizeof(int64_t));
858   uint64_t *seenValues = malloc(3 * sizeof(uint64_t));
859   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, uint64_t aValue, BOOL *stop) {
860     XCTAssertLessThan(idx, 3U);
861     seenKeys[idx] = aKey;
862     seenValues[idx] = aValue;
863     XCTAssertNotEqual(stop, NULL);
864     ++idx;
865   }];
866   for (int i = 0; i < 3; ++i) {
867     BOOL foundKey = NO;
868     for (int j = 0; (j < 3) && !foundKey; ++j) {
869       if (kKeys[i] == seenKeys[j]) {
870         foundKey = YES;
871         XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
872       }
873     }
874     XCTAssertTrue(foundKey, @"i = %d", i);
875   }
876   free(seenKeys);
877   free(seenValues);
879   // Stopping the enumeration.
880   idx = 0;
881   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, uint64_t aValue, BOOL *stop) {
882     #pragma unused(aKey, aValue)
883     if (idx == 1) *stop = YES;
884     XCTAssertNotEqual(idx, 2U);
885     ++idx;
886   }];
887   [dict release];
890 - (void)testEquality {
891   const int64_t kKeys1[] = { 21LL, 22LL, 23LL, 24LL };
892   const int64_t kKeys2[] = { 22LL, 21LL, 24LL };
893   const uint64_t kValues1[] = { 300U, 301U, 302U };
894   const uint64_t kValues2[] = { 300U, 303U, 302U };
895   const uint64_t kValues3[] = { 300U, 301U, 302U, 303U };
896   GPBInt64UInt64Dictionary *dict1 =
897       [[GPBInt64UInt64Dictionary alloc] initWithValues:kValues1
898                                                forKeys:kKeys1
899                                                  count:GPBARRAYSIZE(kValues1)];
900   XCTAssertNotNil(dict1);
901   GPBInt64UInt64Dictionary *dict1prime =
902       [[GPBInt64UInt64Dictionary alloc] initWithValues:kValues1
903                                                forKeys:kKeys1
904                                                  count:GPBARRAYSIZE(kValues1)];
905   XCTAssertNotNil(dict1prime);
906   GPBInt64UInt64Dictionary *dict2 =
907       [[GPBInt64UInt64Dictionary alloc] initWithValues:kValues2
908                                                forKeys:kKeys1
909                                                  count:GPBARRAYSIZE(kValues2)];
910   XCTAssertNotNil(dict2);
911   GPBInt64UInt64Dictionary *dict3 =
912       [[GPBInt64UInt64Dictionary alloc] initWithValues:kValues1
913                                                forKeys:kKeys2
914                                                  count:GPBARRAYSIZE(kValues1)];
915   XCTAssertNotNil(dict3);
916   GPBInt64UInt64Dictionary *dict4 =
917       [[GPBInt64UInt64Dictionary alloc] initWithValues:kValues3
918                                                forKeys:kKeys1
919                                                  count:GPBARRAYSIZE(kValues3)];
920   XCTAssertNotNil(dict4);
922   // 1/1Prime should be different objects, but equal.
923   XCTAssertNotEqual(dict1, dict1prime);
924   XCTAssertEqualObjects(dict1, dict1prime);
925   // Equal, so they must have same hash.
926   XCTAssertEqual([dict1 hash], [dict1prime hash]);
928   // 2 is save keys, different values; not equal.
929   XCTAssertNotEqualObjects(dict1, dict2);
931   // 3 is different keys, samae values; not equal.
932   XCTAssertNotEqualObjects(dict1, dict3);
934   // 4 extra pair; not equal
935   XCTAssertNotEqualObjects(dict1, dict4);
937   [dict1 release];
938   [dict1prime release];
939   [dict2 release];
940   [dict3 release];
941   [dict4 release];
944 - (void)testCopy {
945   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
946   const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
947   GPBInt64UInt64Dictionary *dict =
948       [[GPBInt64UInt64Dictionary alloc] initWithValues:kValues
949                                                forKeys:kKeys
950                                                  count:GPBARRAYSIZE(kValues)];
951   XCTAssertNotNil(dict);
953   GPBInt64UInt64Dictionary *dict2 = [dict copy];
954   XCTAssertNotNil(dict2);
956   // Should be new object but equal.
957   XCTAssertNotEqual(dict, dict2);
958   XCTAssertEqualObjects(dict, dict2);
959   XCTAssertTrue([dict2 isKindOfClass:[GPBInt64UInt64Dictionary class]]);
961   [dict2 release];
962   [dict release];
965 - (void)testDictionaryFromDictionary {
966   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
967   const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
968   GPBInt64UInt64Dictionary *dict =
969       [[GPBInt64UInt64Dictionary alloc] initWithValues:kValues
970                                                forKeys:kKeys
971                                                  count:GPBARRAYSIZE(kValues)];
972   XCTAssertNotNil(dict);
974   GPBInt64UInt64Dictionary *dict2 =
975       [GPBInt64UInt64Dictionary dictionaryWithDictionary:dict];
976   XCTAssertNotNil(dict2);
978   // Should be new pointer, but equal objects.
979   XCTAssertNotEqual(dict, dict2);
980   XCTAssertEqualObjects(dict, dict2);
981   [dict release];
984 - (void)testAdds {
985   GPBInt64UInt64Dictionary *dict = [GPBInt64UInt64Dictionary dictionary];
986   XCTAssertNotNil(dict);
988   XCTAssertEqual(dict.count, 0U);
989   [dict setValue:300U forKey:21LL];
990   XCTAssertEqual(dict.count, 1U);
992   const int64_t kKeys[] = { 22LL, 23LL, 24LL };
993   const uint64_t kValues[] = { 301U, 302U, 303U };
994   GPBInt64UInt64Dictionary *dict2 =
995       [[GPBInt64UInt64Dictionary alloc] initWithValues:kValues
996                                                forKeys:kKeys
997                                                  count:GPBARRAYSIZE(kValues)];
998   XCTAssertNotNil(dict2);
999   [dict addEntriesFromDictionary:dict2];
1000   XCTAssertEqual(dict.count, 4U);
1002   uint64_t value;
1003   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
1004   XCTAssertTrue([dict valueForKey:21LL value:&value]);
1005   XCTAssertEqual(value, 300U);
1006   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
1007   XCTAssertTrue([dict valueForKey:22LL value:&value]);
1008   XCTAssertEqual(value, 301U);
1009   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
1010   XCTAssertTrue([dict valueForKey:23LL value:&value]);
1011   XCTAssertEqual(value, 302U);
1012   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
1013   XCTAssertTrue([dict valueForKey:24LL value:&value]);
1014   XCTAssertEqual(value, 303U);
1015   [dict2 release];
1018 - (void)testRemove {
1019   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
1020   const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
1021   GPBInt64UInt64Dictionary *dict =
1022       [[GPBInt64UInt64Dictionary alloc] initWithValues:kValues
1023                                         forKeys:kKeys
1024                                           count:GPBARRAYSIZE(kValues)];
1025   XCTAssertNotNil(dict);
1026   XCTAssertEqual(dict.count, 4U);
1028   [dict removeValueForKey:22LL];
1029   XCTAssertEqual(dict.count, 3U);
1030   uint64_t value;
1031   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
1032   XCTAssertTrue([dict valueForKey:21LL value:&value]);
1033   XCTAssertEqual(value, 300U);
1034   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
1035   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
1036   XCTAssertTrue([dict valueForKey:23LL value:&value]);
1037   XCTAssertEqual(value, 302U);
1038   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
1039   XCTAssertTrue([dict valueForKey:24LL value:&value]);
1040   XCTAssertEqual(value, 303U);
1042   // Remove again does nothing.
1043   [dict removeValueForKey:22LL];
1044   XCTAssertEqual(dict.count, 3U);
1045   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
1046   XCTAssertTrue([dict valueForKey:21LL value:&value]);
1047   XCTAssertEqual(value, 300U);
1048   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
1049   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
1050   XCTAssertTrue([dict valueForKey:23LL value:&value]);
1051   XCTAssertEqual(value, 302U);
1052   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
1053   XCTAssertTrue([dict valueForKey:24LL value:&value]);
1054   XCTAssertEqual(value, 303U);
1056   [dict removeValueForKey:24LL];
1057   XCTAssertEqual(dict.count, 2U);
1058   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
1059   XCTAssertTrue([dict valueForKey:21LL value:&value]);
1060   XCTAssertEqual(value, 300U);
1061   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
1062   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
1063   XCTAssertTrue([dict valueForKey:23LL value:&value]);
1064   XCTAssertEqual(value, 302U);
1065   XCTAssertFalse([dict valueForKey:24LL value:NULL]);
1067   [dict removeAll];
1068   XCTAssertEqual(dict.count, 0U);
1069   XCTAssertFalse([dict valueForKey:21LL value:NULL]);
1070   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
1071   XCTAssertFalse([dict valueForKey:23LL value:NULL]);
1072   XCTAssertFalse([dict valueForKey:24LL value:NULL]);
1073   [dict release];
1076 - (void)testInplaceMutation {
1077   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
1078   const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
1079   GPBInt64UInt64Dictionary *dict =
1080       [[GPBInt64UInt64Dictionary alloc] initWithValues:kValues
1081                                         forKeys:kKeys
1082                                           count:GPBARRAYSIZE(kValues)];
1083   XCTAssertNotNil(dict);
1084   XCTAssertEqual(dict.count, 4U);
1085   uint64_t value;
1086   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
1087   XCTAssertTrue([dict valueForKey:21LL value:&value]);
1088   XCTAssertEqual(value, 300U);
1089   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
1090   XCTAssertTrue([dict valueForKey:22LL value:&value]);
1091   XCTAssertEqual(value, 301U);
1092   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
1093   XCTAssertTrue([dict valueForKey:23LL value:&value]);
1094   XCTAssertEqual(value, 302U);
1095   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
1096   XCTAssertTrue([dict valueForKey:24LL value:&value]);
1097   XCTAssertEqual(value, 303U);
1099   [dict setValue:303U forKey:21LL];
1100   XCTAssertEqual(dict.count, 4U);
1101   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
1102   XCTAssertTrue([dict valueForKey:21LL value:&value]);
1103   XCTAssertEqual(value, 303U);
1104   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
1105   XCTAssertTrue([dict valueForKey:22LL value:&value]);
1106   XCTAssertEqual(value, 301U);
1107   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
1108   XCTAssertTrue([dict valueForKey:23LL value:&value]);
1109   XCTAssertEqual(value, 302U);
1110   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
1111   XCTAssertTrue([dict valueForKey:24LL value:&value]);
1112   XCTAssertEqual(value, 303U);
1114   [dict setValue:301U forKey:24LL];
1115   XCTAssertEqual(dict.count, 4U);
1116   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
1117   XCTAssertTrue([dict valueForKey:21LL value:&value]);
1118   XCTAssertEqual(value, 303U);
1119   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
1120   XCTAssertTrue([dict valueForKey:22LL value:&value]);
1121   XCTAssertEqual(value, 301U);
1122   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
1123   XCTAssertTrue([dict valueForKey:23LL value:&value]);
1124   XCTAssertEqual(value, 302U);
1125   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
1126   XCTAssertTrue([dict valueForKey:24LL value:&value]);
1127   XCTAssertEqual(value, 301U);
1129   const int64_t kKeys2[] = { 22LL, 23LL };
1130   const uint64_t kValues2[] = { 302U, 300U };
1131   GPBInt64UInt64Dictionary *dict2 =
1132       [[GPBInt64UInt64Dictionary alloc] initWithValues:kValues2
1133                                                forKeys:kKeys2
1134                                                  count:GPBARRAYSIZE(kValues2)];
1135   XCTAssertNotNil(dict2);
1136   [dict addEntriesFromDictionary:dict2];
1137   XCTAssertEqual(dict.count, 4U);
1138   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
1139   XCTAssertTrue([dict valueForKey:21LL value:&value]);
1140   XCTAssertEqual(value, 303U);
1141   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
1142   XCTAssertTrue([dict valueForKey:22LL value:&value]);
1143   XCTAssertEqual(value, 302U);
1144   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
1145   XCTAssertTrue([dict valueForKey:23LL value:&value]);
1146   XCTAssertEqual(value, 300U);
1147   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
1148   XCTAssertTrue([dict valueForKey:24LL value:&value]);
1149   XCTAssertEqual(value, 301U);
1151   [dict2 release];
1152   [dict release];
1155 @end
1157 #pragma mark - Int64 -> Int64
1159 @interface GPBInt64Int64DictionaryTests : XCTestCase
1160 @end
1162 @implementation GPBInt64Int64DictionaryTests
1164 - (void)testEmpty {
1165   GPBInt64Int64Dictionary *dict = [[GPBInt64Int64Dictionary alloc] init];
1166   XCTAssertNotNil(dict);
1167   XCTAssertEqual(dict.count, 0U);
1168   XCTAssertFalse([dict valueForKey:21LL value:NULL]);
1169   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, int64_t aValue, BOOL *stop) {
1170     #pragma unused(aKey, aValue, stop)
1171     XCTFail(@"Shouldn't get here!");
1172   }];
1173   [dict release];
1176 - (void)testOne {
1177   GPBInt64Int64Dictionary *dict = [GPBInt64Int64Dictionary dictionaryWithValue:400 forKey:21LL];
1178   XCTAssertNotNil(dict);
1179   XCTAssertEqual(dict.count, 1U);
1180   int64_t value;
1181   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
1182   XCTAssertTrue([dict valueForKey:21LL value:&value]);
1183   XCTAssertEqual(value, 400);
1184   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
1185   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, int64_t aValue, BOOL *stop) {
1186     XCTAssertEqual(aKey, 21LL);
1187     XCTAssertEqual(aValue, 400);
1188     XCTAssertNotEqual(stop, NULL);
1189   }];
1192 - (void)testBasics {
1193   const int64_t kKeys[] = { 21LL, 22LL, 23LL };
1194   const int64_t kValues[] = { 400, 401, 402 };
1195   GPBInt64Int64Dictionary *dict =
1196       [[GPBInt64Int64Dictionary alloc] initWithValues:kValues
1197                                               forKeys:kKeys
1198                                                 count:GPBARRAYSIZE(kValues)];
1199   XCTAssertNotNil(dict);
1200   XCTAssertEqual(dict.count, 3U);
1201   int64_t value;
1202   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
1203   XCTAssertTrue([dict valueForKey:21LL value:&value]);
1204   XCTAssertEqual(value, 400);
1205   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
1206   XCTAssertTrue([dict valueForKey:22LL value:&value]);
1207   XCTAssertEqual(value, 401);
1208   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
1209   XCTAssertTrue([dict valueForKey:23LL value:&value]);
1210   XCTAssertEqual(value, 402);
1211   XCTAssertFalse([dict valueForKey:24LL value:NULL]);
1213   __block NSUInteger idx = 0;
1214   int64_t *seenKeys = malloc(3 * sizeof(int64_t));
1215   int64_t *seenValues = malloc(3 * sizeof(int64_t));
1216   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, int64_t aValue, BOOL *stop) {
1217     XCTAssertLessThan(idx, 3U);
1218     seenKeys[idx] = aKey;
1219     seenValues[idx] = aValue;
1220     XCTAssertNotEqual(stop, NULL);
1221     ++idx;
1222   }];
1223   for (int i = 0; i < 3; ++i) {
1224     BOOL foundKey = NO;
1225     for (int j = 0; (j < 3) && !foundKey; ++j) {
1226       if (kKeys[i] == seenKeys[j]) {
1227         foundKey = YES;
1228         XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
1229       }
1230     }
1231     XCTAssertTrue(foundKey, @"i = %d", i);
1232   }
1233   free(seenKeys);
1234   free(seenValues);
1236   // Stopping the enumeration.
1237   idx = 0;
1238   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, int64_t aValue, BOOL *stop) {
1239     #pragma unused(aKey, aValue)
1240     if (idx == 1) *stop = YES;
1241     XCTAssertNotEqual(idx, 2U);
1242     ++idx;
1243   }];
1244   [dict release];
1247 - (void)testEquality {
1248   const int64_t kKeys1[] = { 21LL, 22LL, 23LL, 24LL };
1249   const int64_t kKeys2[] = { 22LL, 21LL, 24LL };
1250   const int64_t kValues1[] = { 400, 401, 402 };
1251   const int64_t kValues2[] = { 400, 403, 402 };
1252   const int64_t kValues3[] = { 400, 401, 402, 403 };
1253   GPBInt64Int64Dictionary *dict1 =
1254       [[GPBInt64Int64Dictionary alloc] initWithValues:kValues1
1255                                               forKeys:kKeys1
1256                                                 count:GPBARRAYSIZE(kValues1)];
1257   XCTAssertNotNil(dict1);
1258   GPBInt64Int64Dictionary *dict1prime =
1259       [[GPBInt64Int64Dictionary alloc] initWithValues:kValues1
1260                                               forKeys:kKeys1
1261                                                 count:GPBARRAYSIZE(kValues1)];
1262   XCTAssertNotNil(dict1prime);
1263   GPBInt64Int64Dictionary *dict2 =
1264       [[GPBInt64Int64Dictionary alloc] initWithValues:kValues2
1265                                               forKeys:kKeys1
1266                                                 count:GPBARRAYSIZE(kValues2)];
1267   XCTAssertNotNil(dict2);
1268   GPBInt64Int64Dictionary *dict3 =
1269       [[GPBInt64Int64Dictionary alloc] initWithValues:kValues1
1270                                               forKeys:kKeys2
1271                                                 count:GPBARRAYSIZE(kValues1)];
1272   XCTAssertNotNil(dict3);
1273   GPBInt64Int64Dictionary *dict4 =
1274       [[GPBInt64Int64Dictionary alloc] initWithValues:kValues3
1275                                               forKeys:kKeys1
1276                                                 count:GPBARRAYSIZE(kValues3)];
1277   XCTAssertNotNil(dict4);
1279   // 1/1Prime should be different objects, but equal.
1280   XCTAssertNotEqual(dict1, dict1prime);
1281   XCTAssertEqualObjects(dict1, dict1prime);
1282   // Equal, so they must have same hash.
1283   XCTAssertEqual([dict1 hash], [dict1prime hash]);
1285   // 2 is save keys, different values; not equal.
1286   XCTAssertNotEqualObjects(dict1, dict2);
1288   // 3 is different keys, samae values; not equal.
1289   XCTAssertNotEqualObjects(dict1, dict3);
1291   // 4 extra pair; not equal
1292   XCTAssertNotEqualObjects(dict1, dict4);
1294   [dict1 release];
1295   [dict1prime release];
1296   [dict2 release];
1297   [dict3 release];
1298   [dict4 release];
1301 - (void)testCopy {
1302   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
1303   const int64_t kValues[] = { 400, 401, 402, 403 };
1304   GPBInt64Int64Dictionary *dict =
1305       [[GPBInt64Int64Dictionary alloc] initWithValues:kValues
1306                                               forKeys:kKeys
1307                                                 count:GPBARRAYSIZE(kValues)];
1308   XCTAssertNotNil(dict);
1310   GPBInt64Int64Dictionary *dict2 = [dict copy];
1311   XCTAssertNotNil(dict2);
1313   // Should be new object but equal.
1314   XCTAssertNotEqual(dict, dict2);
1315   XCTAssertEqualObjects(dict, dict2);
1316   XCTAssertTrue([dict2 isKindOfClass:[GPBInt64Int64Dictionary class]]);
1318   [dict2 release];
1319   [dict release];
1322 - (void)testDictionaryFromDictionary {
1323   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
1324   const int64_t kValues[] = { 400, 401, 402, 403 };
1325   GPBInt64Int64Dictionary *dict =
1326       [[GPBInt64Int64Dictionary alloc] initWithValues:kValues
1327                                               forKeys:kKeys
1328                                                 count:GPBARRAYSIZE(kValues)];
1329   XCTAssertNotNil(dict);
1331   GPBInt64Int64Dictionary *dict2 =
1332       [GPBInt64Int64Dictionary dictionaryWithDictionary:dict];
1333   XCTAssertNotNil(dict2);
1335   // Should be new pointer, but equal objects.
1336   XCTAssertNotEqual(dict, dict2);
1337   XCTAssertEqualObjects(dict, dict2);
1338   [dict release];
1341 - (void)testAdds {
1342   GPBInt64Int64Dictionary *dict = [GPBInt64Int64Dictionary dictionary];
1343   XCTAssertNotNil(dict);
1345   XCTAssertEqual(dict.count, 0U);
1346   [dict setValue:400 forKey:21LL];
1347   XCTAssertEqual(dict.count, 1U);
1349   const int64_t kKeys[] = { 22LL, 23LL, 24LL };
1350   const int64_t kValues[] = { 401, 402, 403 };
1351   GPBInt64Int64Dictionary *dict2 =
1352       [[GPBInt64Int64Dictionary alloc] initWithValues:kValues
1353                                               forKeys:kKeys
1354                                                 count:GPBARRAYSIZE(kValues)];
1355   XCTAssertNotNil(dict2);
1356   [dict addEntriesFromDictionary:dict2];
1357   XCTAssertEqual(dict.count, 4U);
1359   int64_t value;
1360   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
1361   XCTAssertTrue([dict valueForKey:21LL value:&value]);
1362   XCTAssertEqual(value, 400);
1363   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
1364   XCTAssertTrue([dict valueForKey:22LL value:&value]);
1365   XCTAssertEqual(value, 401);
1366   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
1367   XCTAssertTrue([dict valueForKey:23LL value:&value]);
1368   XCTAssertEqual(value, 402);
1369   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
1370   XCTAssertTrue([dict valueForKey:24LL value:&value]);
1371   XCTAssertEqual(value, 403);
1372   [dict2 release];
1375 - (void)testRemove {
1376   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
1377   const int64_t kValues[] = { 400, 401, 402, 403 };
1378   GPBInt64Int64Dictionary *dict =
1379       [[GPBInt64Int64Dictionary alloc] initWithValues:kValues
1380                                        forKeys:kKeys
1381                                          count:GPBARRAYSIZE(kValues)];
1382   XCTAssertNotNil(dict);
1383   XCTAssertEqual(dict.count, 4U);
1385   [dict removeValueForKey:22LL];
1386   XCTAssertEqual(dict.count, 3U);
1387   int64_t value;
1388   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
1389   XCTAssertTrue([dict valueForKey:21LL value:&value]);
1390   XCTAssertEqual(value, 400);
1391   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
1392   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
1393   XCTAssertTrue([dict valueForKey:23LL value:&value]);
1394   XCTAssertEqual(value, 402);
1395   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
1396   XCTAssertTrue([dict valueForKey:24LL value:&value]);
1397   XCTAssertEqual(value, 403);
1399   // Remove again does nothing.
1400   [dict removeValueForKey:22LL];
1401   XCTAssertEqual(dict.count, 3U);
1402   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
1403   XCTAssertTrue([dict valueForKey:21LL value:&value]);
1404   XCTAssertEqual(value, 400);
1405   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
1406   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
1407   XCTAssertTrue([dict valueForKey:23LL value:&value]);
1408   XCTAssertEqual(value, 402);
1409   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
1410   XCTAssertTrue([dict valueForKey:24LL value:&value]);
1411   XCTAssertEqual(value, 403);
1413   [dict removeValueForKey:24LL];
1414   XCTAssertEqual(dict.count, 2U);
1415   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
1416   XCTAssertTrue([dict valueForKey:21LL value:&value]);
1417   XCTAssertEqual(value, 400);
1418   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
1419   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
1420   XCTAssertTrue([dict valueForKey:23LL value:&value]);
1421   XCTAssertEqual(value, 402);
1422   XCTAssertFalse([dict valueForKey:24LL value:NULL]);
1424   [dict removeAll];
1425   XCTAssertEqual(dict.count, 0U);
1426   XCTAssertFalse([dict valueForKey:21LL value:NULL]);
1427   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
1428   XCTAssertFalse([dict valueForKey:23LL value:NULL]);
1429   XCTAssertFalse([dict valueForKey:24LL value:NULL]);
1430   [dict release];
1433 - (void)testInplaceMutation {
1434   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
1435   const int64_t kValues[] = { 400, 401, 402, 403 };
1436   GPBInt64Int64Dictionary *dict =
1437       [[GPBInt64Int64Dictionary alloc] initWithValues:kValues
1438                                        forKeys:kKeys
1439                                          count:GPBARRAYSIZE(kValues)];
1440   XCTAssertNotNil(dict);
1441   XCTAssertEqual(dict.count, 4U);
1442   int64_t value;
1443   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
1444   XCTAssertTrue([dict valueForKey:21LL value:&value]);
1445   XCTAssertEqual(value, 400);
1446   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
1447   XCTAssertTrue([dict valueForKey:22LL value:&value]);
1448   XCTAssertEqual(value, 401);
1449   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
1450   XCTAssertTrue([dict valueForKey:23LL value:&value]);
1451   XCTAssertEqual(value, 402);
1452   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
1453   XCTAssertTrue([dict valueForKey:24LL value:&value]);
1454   XCTAssertEqual(value, 403);
1456   [dict setValue:403 forKey:21LL];
1457   XCTAssertEqual(dict.count, 4U);
1458   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
1459   XCTAssertTrue([dict valueForKey:21LL value:&value]);
1460   XCTAssertEqual(value, 403);
1461   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
1462   XCTAssertTrue([dict valueForKey:22LL value:&value]);
1463   XCTAssertEqual(value, 401);
1464   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
1465   XCTAssertTrue([dict valueForKey:23LL value:&value]);
1466   XCTAssertEqual(value, 402);
1467   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
1468   XCTAssertTrue([dict valueForKey:24LL value:&value]);
1469   XCTAssertEqual(value, 403);
1471   [dict setValue:401 forKey:24LL];
1472   XCTAssertEqual(dict.count, 4U);
1473   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
1474   XCTAssertTrue([dict valueForKey:21LL value:&value]);
1475   XCTAssertEqual(value, 403);
1476   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
1477   XCTAssertTrue([dict valueForKey:22LL value:&value]);
1478   XCTAssertEqual(value, 401);
1479   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
1480   XCTAssertTrue([dict valueForKey:23LL value:&value]);
1481   XCTAssertEqual(value, 402);
1482   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
1483   XCTAssertTrue([dict valueForKey:24LL value:&value]);
1484   XCTAssertEqual(value, 401);
1486   const int64_t kKeys2[] = { 22LL, 23LL };
1487   const int64_t kValues2[] = { 402, 400 };
1488   GPBInt64Int64Dictionary *dict2 =
1489       [[GPBInt64Int64Dictionary alloc] initWithValues:kValues2
1490                                               forKeys:kKeys2
1491                                                 count:GPBARRAYSIZE(kValues2)];
1492   XCTAssertNotNil(dict2);
1493   [dict addEntriesFromDictionary:dict2];
1494   XCTAssertEqual(dict.count, 4U);
1495   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
1496   XCTAssertTrue([dict valueForKey:21LL value:&value]);
1497   XCTAssertEqual(value, 403);
1498   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
1499   XCTAssertTrue([dict valueForKey:22LL value:&value]);
1500   XCTAssertEqual(value, 402);
1501   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
1502   XCTAssertTrue([dict valueForKey:23LL value:&value]);
1503   XCTAssertEqual(value, 400);
1504   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
1505   XCTAssertTrue([dict valueForKey:24LL value:&value]);
1506   XCTAssertEqual(value, 401);
1508   [dict2 release];
1509   [dict release];
1512 @end
1514 #pragma mark - Int64 -> Bool
1516 @interface GPBInt64BoolDictionaryTests : XCTestCase
1517 @end
1519 @implementation GPBInt64BoolDictionaryTests
1521 - (void)testEmpty {
1522   GPBInt64BoolDictionary *dict = [[GPBInt64BoolDictionary alloc] init];
1523   XCTAssertNotNil(dict);
1524   XCTAssertEqual(dict.count, 0U);
1525   XCTAssertFalse([dict valueForKey:21LL value:NULL]);
1526   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, BOOL aValue, BOOL *stop) {
1527     #pragma unused(aKey, aValue, stop)
1528     XCTFail(@"Shouldn't get here!");
1529   }];
1530   [dict release];
1533 - (void)testOne {
1534   GPBInt64BoolDictionary *dict = [GPBInt64BoolDictionary dictionaryWithValue:YES forKey:21LL];
1535   XCTAssertNotNil(dict);
1536   XCTAssertEqual(dict.count, 1U);
1537   BOOL value;
1538   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
1539   XCTAssertTrue([dict valueForKey:21LL value:&value]);
1540   XCTAssertEqual(value, YES);
1541   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
1542   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, BOOL aValue, BOOL *stop) {
1543     XCTAssertEqual(aKey, 21LL);
1544     XCTAssertEqual(aValue, YES);
1545     XCTAssertNotEqual(stop, NULL);
1546   }];
1549 - (void)testBasics {
1550   const int64_t kKeys[] = { 21LL, 22LL, 23LL };
1551   const BOOL kValues[] = { YES, YES, NO };
1552   GPBInt64BoolDictionary *dict =
1553       [[GPBInt64BoolDictionary alloc] initWithValues:kValues
1554                                              forKeys:kKeys
1555                                                count:GPBARRAYSIZE(kValues)];
1556   XCTAssertNotNil(dict);
1557   XCTAssertEqual(dict.count, 3U);
1558   BOOL value;
1559   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
1560   XCTAssertTrue([dict valueForKey:21LL value:&value]);
1561   XCTAssertEqual(value, YES);
1562   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
1563   XCTAssertTrue([dict valueForKey:22LL value:&value]);
1564   XCTAssertEqual(value, YES);
1565   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
1566   XCTAssertTrue([dict valueForKey:23LL value:&value]);
1567   XCTAssertEqual(value, NO);
1568   XCTAssertFalse([dict valueForKey:24LL value:NULL]);
1570   __block NSUInteger idx = 0;
1571   int64_t *seenKeys = malloc(3 * sizeof(int64_t));
1572   BOOL *seenValues = malloc(3 * sizeof(BOOL));
1573   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, BOOL aValue, BOOL *stop) {
1574     XCTAssertLessThan(idx, 3U);
1575     seenKeys[idx] = aKey;
1576     seenValues[idx] = aValue;
1577     XCTAssertNotEqual(stop, NULL);
1578     ++idx;
1579   }];
1580   for (int i = 0; i < 3; ++i) {
1581     BOOL foundKey = NO;
1582     for (int j = 0; (j < 3) && !foundKey; ++j) {
1583       if (kKeys[i] == seenKeys[j]) {
1584         foundKey = YES;
1585         XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
1586       }
1587     }
1588     XCTAssertTrue(foundKey, @"i = %d", i);
1589   }
1590   free(seenKeys);
1591   free(seenValues);
1593   // Stopping the enumeration.
1594   idx = 0;
1595   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, BOOL aValue, BOOL *stop) {
1596     #pragma unused(aKey, aValue)
1597     if (idx == 1) *stop = YES;
1598     XCTAssertNotEqual(idx, 2U);
1599     ++idx;
1600   }];
1601   [dict release];
1604 - (void)testEquality {
1605   const int64_t kKeys1[] = { 21LL, 22LL, 23LL, 24LL };
1606   const int64_t kKeys2[] = { 22LL, 21LL, 24LL };
1607   const BOOL kValues1[] = { YES, YES, NO };
1608   const BOOL kValues2[] = { YES, NO, NO };
1609   const BOOL kValues3[] = { YES, YES, NO, NO };
1610   GPBInt64BoolDictionary *dict1 =
1611       [[GPBInt64BoolDictionary alloc] initWithValues:kValues1
1612                                              forKeys:kKeys1
1613                                                count:GPBARRAYSIZE(kValues1)];
1614   XCTAssertNotNil(dict1);
1615   GPBInt64BoolDictionary *dict1prime =
1616       [[GPBInt64BoolDictionary alloc] initWithValues:kValues1
1617                                              forKeys:kKeys1
1618                                                count:GPBARRAYSIZE(kValues1)];
1619   XCTAssertNotNil(dict1prime);
1620   GPBInt64BoolDictionary *dict2 =
1621       [[GPBInt64BoolDictionary alloc] initWithValues:kValues2
1622                                              forKeys:kKeys1
1623                                                count:GPBARRAYSIZE(kValues2)];
1624   XCTAssertNotNil(dict2);
1625   GPBInt64BoolDictionary *dict3 =
1626       [[GPBInt64BoolDictionary alloc] initWithValues:kValues1
1627                                              forKeys:kKeys2
1628                                                count:GPBARRAYSIZE(kValues1)];
1629   XCTAssertNotNil(dict3);
1630   GPBInt64BoolDictionary *dict4 =
1631       [[GPBInt64BoolDictionary alloc] initWithValues:kValues3
1632                                              forKeys:kKeys1
1633                                                count:GPBARRAYSIZE(kValues3)];
1634   XCTAssertNotNil(dict4);
1636   // 1/1Prime should be different objects, but equal.
1637   XCTAssertNotEqual(dict1, dict1prime);
1638   XCTAssertEqualObjects(dict1, dict1prime);
1639   // Equal, so they must have same hash.
1640   XCTAssertEqual([dict1 hash], [dict1prime hash]);
1642   // 2 is save keys, different values; not equal.
1643   XCTAssertNotEqualObjects(dict1, dict2);
1645   // 3 is different keys, samae values; not equal.
1646   XCTAssertNotEqualObjects(dict1, dict3);
1648   // 4 extra pair; not equal
1649   XCTAssertNotEqualObjects(dict1, dict4);
1651   [dict1 release];
1652   [dict1prime release];
1653   [dict2 release];
1654   [dict3 release];
1655   [dict4 release];
1658 - (void)testCopy {
1659   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
1660   const BOOL kValues[] = { YES, YES, NO, NO };
1661   GPBInt64BoolDictionary *dict =
1662       [[GPBInt64BoolDictionary alloc] initWithValues:kValues
1663                                              forKeys:kKeys
1664                                                count:GPBARRAYSIZE(kValues)];
1665   XCTAssertNotNil(dict);
1667   GPBInt64BoolDictionary *dict2 = [dict copy];
1668   XCTAssertNotNil(dict2);
1670   // Should be new object but equal.
1671   XCTAssertNotEqual(dict, dict2);
1672   XCTAssertEqualObjects(dict, dict2);
1673   XCTAssertTrue([dict2 isKindOfClass:[GPBInt64BoolDictionary class]]);
1675   [dict2 release];
1676   [dict release];
1679 - (void)testDictionaryFromDictionary {
1680   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
1681   const BOOL kValues[] = { YES, YES, NO, NO };
1682   GPBInt64BoolDictionary *dict =
1683       [[GPBInt64BoolDictionary alloc] initWithValues:kValues
1684                                              forKeys:kKeys
1685                                                count:GPBARRAYSIZE(kValues)];
1686   XCTAssertNotNil(dict);
1688   GPBInt64BoolDictionary *dict2 =
1689       [GPBInt64BoolDictionary dictionaryWithDictionary:dict];
1690   XCTAssertNotNil(dict2);
1692   // Should be new pointer, but equal objects.
1693   XCTAssertNotEqual(dict, dict2);
1694   XCTAssertEqualObjects(dict, dict2);
1695   [dict release];
1698 - (void)testAdds {
1699   GPBInt64BoolDictionary *dict = [GPBInt64BoolDictionary dictionary];
1700   XCTAssertNotNil(dict);
1702   XCTAssertEqual(dict.count, 0U);
1703   [dict setValue:YES forKey:21LL];
1704   XCTAssertEqual(dict.count, 1U);
1706   const int64_t kKeys[] = { 22LL, 23LL, 24LL };
1707   const BOOL kValues[] = { YES, NO, NO };
1708   GPBInt64BoolDictionary *dict2 =
1709       [[GPBInt64BoolDictionary alloc] initWithValues:kValues
1710                                              forKeys:kKeys
1711                                                count:GPBARRAYSIZE(kValues)];
1712   XCTAssertNotNil(dict2);
1713   [dict addEntriesFromDictionary:dict2];
1714   XCTAssertEqual(dict.count, 4U);
1716   BOOL value;
1717   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
1718   XCTAssertTrue([dict valueForKey:21LL value:&value]);
1719   XCTAssertEqual(value, YES);
1720   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
1721   XCTAssertTrue([dict valueForKey:22LL value:&value]);
1722   XCTAssertEqual(value, YES);
1723   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
1724   XCTAssertTrue([dict valueForKey:23LL value:&value]);
1725   XCTAssertEqual(value, NO);
1726   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
1727   XCTAssertTrue([dict valueForKey:24LL value:&value]);
1728   XCTAssertEqual(value, NO);
1729   [dict2 release];
1732 - (void)testRemove {
1733   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
1734   const BOOL kValues[] = { YES, YES, NO, NO };
1735   GPBInt64BoolDictionary *dict =
1736       [[GPBInt64BoolDictionary alloc] initWithValues:kValues
1737                                       forKeys:kKeys
1738                                         count:GPBARRAYSIZE(kValues)];
1739   XCTAssertNotNil(dict);
1740   XCTAssertEqual(dict.count, 4U);
1742   [dict removeValueForKey:22LL];
1743   XCTAssertEqual(dict.count, 3U);
1744   BOOL value;
1745   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
1746   XCTAssertTrue([dict valueForKey:21LL value:&value]);
1747   XCTAssertEqual(value, YES);
1748   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
1749   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
1750   XCTAssertTrue([dict valueForKey:23LL value:&value]);
1751   XCTAssertEqual(value, NO);
1752   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
1753   XCTAssertTrue([dict valueForKey:24LL value:&value]);
1754   XCTAssertEqual(value, NO);
1756   // Remove again does nothing.
1757   [dict removeValueForKey:22LL];
1758   XCTAssertEqual(dict.count, 3U);
1759   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
1760   XCTAssertTrue([dict valueForKey:21LL value:&value]);
1761   XCTAssertEqual(value, YES);
1762   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
1763   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
1764   XCTAssertTrue([dict valueForKey:23LL value:&value]);
1765   XCTAssertEqual(value, NO);
1766   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
1767   XCTAssertTrue([dict valueForKey:24LL value:&value]);
1768   XCTAssertEqual(value, NO);
1770   [dict removeValueForKey:24LL];
1771   XCTAssertEqual(dict.count, 2U);
1772   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
1773   XCTAssertTrue([dict valueForKey:21LL value:&value]);
1774   XCTAssertEqual(value, YES);
1775   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
1776   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
1777   XCTAssertTrue([dict valueForKey:23LL value:&value]);
1778   XCTAssertEqual(value, NO);
1779   XCTAssertFalse([dict valueForKey:24LL value:NULL]);
1781   [dict removeAll];
1782   XCTAssertEqual(dict.count, 0U);
1783   XCTAssertFalse([dict valueForKey:21LL value:NULL]);
1784   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
1785   XCTAssertFalse([dict valueForKey:23LL value:NULL]);
1786   XCTAssertFalse([dict valueForKey:24LL value:NULL]);
1787   [dict release];
1790 - (void)testInplaceMutation {
1791   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
1792   const BOOL kValues[] = { YES, YES, NO, NO };
1793   GPBInt64BoolDictionary *dict =
1794       [[GPBInt64BoolDictionary alloc] initWithValues:kValues
1795                                       forKeys:kKeys
1796                                         count:GPBARRAYSIZE(kValues)];
1797   XCTAssertNotNil(dict);
1798   XCTAssertEqual(dict.count, 4U);
1799   BOOL value;
1800   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
1801   XCTAssertTrue([dict valueForKey:21LL value:&value]);
1802   XCTAssertEqual(value, YES);
1803   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
1804   XCTAssertTrue([dict valueForKey:22LL value:&value]);
1805   XCTAssertEqual(value, YES);
1806   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
1807   XCTAssertTrue([dict valueForKey:23LL value:&value]);
1808   XCTAssertEqual(value, NO);
1809   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
1810   XCTAssertTrue([dict valueForKey:24LL value:&value]);
1811   XCTAssertEqual(value, NO);
1813   [dict setValue:NO forKey:21LL];
1814   XCTAssertEqual(dict.count, 4U);
1815   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
1816   XCTAssertTrue([dict valueForKey:21LL value:&value]);
1817   XCTAssertEqual(value, NO);
1818   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
1819   XCTAssertTrue([dict valueForKey:22LL value:&value]);
1820   XCTAssertEqual(value, YES);
1821   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
1822   XCTAssertTrue([dict valueForKey:23LL value:&value]);
1823   XCTAssertEqual(value, NO);
1824   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
1825   XCTAssertTrue([dict valueForKey:24LL value:&value]);
1826   XCTAssertEqual(value, NO);
1828   [dict setValue:YES forKey:24LL];
1829   XCTAssertEqual(dict.count, 4U);
1830   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
1831   XCTAssertTrue([dict valueForKey:21LL value:&value]);
1832   XCTAssertEqual(value, NO);
1833   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
1834   XCTAssertTrue([dict valueForKey:22LL value:&value]);
1835   XCTAssertEqual(value, YES);
1836   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
1837   XCTAssertTrue([dict valueForKey:23LL value:&value]);
1838   XCTAssertEqual(value, NO);
1839   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
1840   XCTAssertTrue([dict valueForKey:24LL value:&value]);
1841   XCTAssertEqual(value, YES);
1843   const int64_t kKeys2[] = { 22LL, 23LL };
1844   const BOOL kValues2[] = { NO, YES };
1845   GPBInt64BoolDictionary *dict2 =
1846       [[GPBInt64BoolDictionary alloc] initWithValues:kValues2
1847                                              forKeys:kKeys2
1848                                                count:GPBARRAYSIZE(kValues2)];
1849   XCTAssertNotNil(dict2);
1850   [dict addEntriesFromDictionary:dict2];
1851   XCTAssertEqual(dict.count, 4U);
1852   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
1853   XCTAssertTrue([dict valueForKey:21LL value:&value]);
1854   XCTAssertEqual(value, NO);
1855   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
1856   XCTAssertTrue([dict valueForKey:22LL value:&value]);
1857   XCTAssertEqual(value, NO);
1858   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
1859   XCTAssertTrue([dict valueForKey:23LL value:&value]);
1860   XCTAssertEqual(value, YES);
1861   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
1862   XCTAssertTrue([dict valueForKey:24LL value:&value]);
1863   XCTAssertEqual(value, YES);
1865   [dict2 release];
1866   [dict release];
1869 @end
1871 #pragma mark - Int64 -> Float
1873 @interface GPBInt64FloatDictionaryTests : XCTestCase
1874 @end
1876 @implementation GPBInt64FloatDictionaryTests
1878 - (void)testEmpty {
1879   GPBInt64FloatDictionary *dict = [[GPBInt64FloatDictionary alloc] init];
1880   XCTAssertNotNil(dict);
1881   XCTAssertEqual(dict.count, 0U);
1882   XCTAssertFalse([dict valueForKey:21LL value:NULL]);
1883   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, float aValue, BOOL *stop) {
1884     #pragma unused(aKey, aValue, stop)
1885     XCTFail(@"Shouldn't get here!");
1886   }];
1887   [dict release];
1890 - (void)testOne {
1891   GPBInt64FloatDictionary *dict = [GPBInt64FloatDictionary dictionaryWithValue:500.f forKey:21LL];
1892   XCTAssertNotNil(dict);
1893   XCTAssertEqual(dict.count, 1U);
1894   float value;
1895   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
1896   XCTAssertTrue([dict valueForKey:21LL value:&value]);
1897   XCTAssertEqual(value, 500.f);
1898   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
1899   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, float aValue, BOOL *stop) {
1900     XCTAssertEqual(aKey, 21LL);
1901     XCTAssertEqual(aValue, 500.f);
1902     XCTAssertNotEqual(stop, NULL);
1903   }];
1906 - (void)testBasics {
1907   const int64_t kKeys[] = { 21LL, 22LL, 23LL };
1908   const float kValues[] = { 500.f, 501.f, 502.f };
1909   GPBInt64FloatDictionary *dict =
1910       [[GPBInt64FloatDictionary alloc] initWithValues:kValues
1911                                               forKeys:kKeys
1912                                                 count:GPBARRAYSIZE(kValues)];
1913   XCTAssertNotNil(dict);
1914   XCTAssertEqual(dict.count, 3U);
1915   float value;
1916   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
1917   XCTAssertTrue([dict valueForKey:21LL value:&value]);
1918   XCTAssertEqual(value, 500.f);
1919   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
1920   XCTAssertTrue([dict valueForKey:22LL value:&value]);
1921   XCTAssertEqual(value, 501.f);
1922   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
1923   XCTAssertTrue([dict valueForKey:23LL value:&value]);
1924   XCTAssertEqual(value, 502.f);
1925   XCTAssertFalse([dict valueForKey:24LL value:NULL]);
1927   __block NSUInteger idx = 0;
1928   int64_t *seenKeys = malloc(3 * sizeof(int64_t));
1929   float *seenValues = malloc(3 * sizeof(float));
1930   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, float aValue, BOOL *stop) {
1931     XCTAssertLessThan(idx, 3U);
1932     seenKeys[idx] = aKey;
1933     seenValues[idx] = aValue;
1934     XCTAssertNotEqual(stop, NULL);
1935     ++idx;
1936   }];
1937   for (int i = 0; i < 3; ++i) {
1938     BOOL foundKey = NO;
1939     for (int j = 0; (j < 3) && !foundKey; ++j) {
1940       if (kKeys[i] == seenKeys[j]) {
1941         foundKey = YES;
1942         XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
1943       }
1944     }
1945     XCTAssertTrue(foundKey, @"i = %d", i);
1946   }
1947   free(seenKeys);
1948   free(seenValues);
1950   // Stopping the enumeration.
1951   idx = 0;
1952   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, float aValue, BOOL *stop) {
1953     #pragma unused(aKey, aValue)
1954     if (idx == 1) *stop = YES;
1955     XCTAssertNotEqual(idx, 2U);
1956     ++idx;
1957   }];
1958   [dict release];
1961 - (void)testEquality {
1962   const int64_t kKeys1[] = { 21LL, 22LL, 23LL, 24LL };
1963   const int64_t kKeys2[] = { 22LL, 21LL, 24LL };
1964   const float kValues1[] = { 500.f, 501.f, 502.f };
1965   const float kValues2[] = { 500.f, 503.f, 502.f };
1966   const float kValues3[] = { 500.f, 501.f, 502.f, 503.f };
1967   GPBInt64FloatDictionary *dict1 =
1968       [[GPBInt64FloatDictionary alloc] initWithValues:kValues1
1969                                               forKeys:kKeys1
1970                                                 count:GPBARRAYSIZE(kValues1)];
1971   XCTAssertNotNil(dict1);
1972   GPBInt64FloatDictionary *dict1prime =
1973       [[GPBInt64FloatDictionary alloc] initWithValues:kValues1
1974                                               forKeys:kKeys1
1975                                                 count:GPBARRAYSIZE(kValues1)];
1976   XCTAssertNotNil(dict1prime);
1977   GPBInt64FloatDictionary *dict2 =
1978       [[GPBInt64FloatDictionary alloc] initWithValues:kValues2
1979                                               forKeys:kKeys1
1980                                                 count:GPBARRAYSIZE(kValues2)];
1981   XCTAssertNotNil(dict2);
1982   GPBInt64FloatDictionary *dict3 =
1983       [[GPBInt64FloatDictionary alloc] initWithValues:kValues1
1984                                               forKeys:kKeys2
1985                                                 count:GPBARRAYSIZE(kValues1)];
1986   XCTAssertNotNil(dict3);
1987   GPBInt64FloatDictionary *dict4 =
1988       [[GPBInt64FloatDictionary alloc] initWithValues:kValues3
1989                                               forKeys:kKeys1
1990                                                 count:GPBARRAYSIZE(kValues3)];
1991   XCTAssertNotNil(dict4);
1993   // 1/1Prime should be different objects, but equal.
1994   XCTAssertNotEqual(dict1, dict1prime);
1995   XCTAssertEqualObjects(dict1, dict1prime);
1996   // Equal, so they must have same hash.
1997   XCTAssertEqual([dict1 hash], [dict1prime hash]);
1999   // 2 is save keys, different values; not equal.
2000   XCTAssertNotEqualObjects(dict1, dict2);
2002   // 3 is different keys, samae values; not equal.
2003   XCTAssertNotEqualObjects(dict1, dict3);
2005   // 4 extra pair; not equal
2006   XCTAssertNotEqualObjects(dict1, dict4);
2008   [dict1 release];
2009   [dict1prime release];
2010   [dict2 release];
2011   [dict3 release];
2012   [dict4 release];
2015 - (void)testCopy {
2016   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
2017   const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
2018   GPBInt64FloatDictionary *dict =
2019       [[GPBInt64FloatDictionary alloc] initWithValues:kValues
2020                                               forKeys:kKeys
2021                                                 count:GPBARRAYSIZE(kValues)];
2022   XCTAssertNotNil(dict);
2024   GPBInt64FloatDictionary *dict2 = [dict copy];
2025   XCTAssertNotNil(dict2);
2027   // Should be new object but equal.
2028   XCTAssertNotEqual(dict, dict2);
2029   XCTAssertEqualObjects(dict, dict2);
2030   XCTAssertTrue([dict2 isKindOfClass:[GPBInt64FloatDictionary class]]);
2032   [dict2 release];
2033   [dict release];
2036 - (void)testDictionaryFromDictionary {
2037   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
2038   const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
2039   GPBInt64FloatDictionary *dict =
2040       [[GPBInt64FloatDictionary alloc] initWithValues:kValues
2041                                               forKeys:kKeys
2042                                                 count:GPBARRAYSIZE(kValues)];
2043   XCTAssertNotNil(dict);
2045   GPBInt64FloatDictionary *dict2 =
2046       [GPBInt64FloatDictionary dictionaryWithDictionary:dict];
2047   XCTAssertNotNil(dict2);
2049   // Should be new pointer, but equal objects.
2050   XCTAssertNotEqual(dict, dict2);
2051   XCTAssertEqualObjects(dict, dict2);
2052   [dict release];
2055 - (void)testAdds {
2056   GPBInt64FloatDictionary *dict = [GPBInt64FloatDictionary dictionary];
2057   XCTAssertNotNil(dict);
2059   XCTAssertEqual(dict.count, 0U);
2060   [dict setValue:500.f forKey:21LL];
2061   XCTAssertEqual(dict.count, 1U);
2063   const int64_t kKeys[] = { 22LL, 23LL, 24LL };
2064   const float kValues[] = { 501.f, 502.f, 503.f };
2065   GPBInt64FloatDictionary *dict2 =
2066       [[GPBInt64FloatDictionary alloc] initWithValues:kValues
2067                                               forKeys:kKeys
2068                                                 count:GPBARRAYSIZE(kValues)];
2069   XCTAssertNotNil(dict2);
2070   [dict addEntriesFromDictionary:dict2];
2071   XCTAssertEqual(dict.count, 4U);
2073   float value;
2074   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
2075   XCTAssertTrue([dict valueForKey:21LL value:&value]);
2076   XCTAssertEqual(value, 500.f);
2077   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
2078   XCTAssertTrue([dict valueForKey:22LL value:&value]);
2079   XCTAssertEqual(value, 501.f);
2080   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
2081   XCTAssertTrue([dict valueForKey:23LL value:&value]);
2082   XCTAssertEqual(value, 502.f);
2083   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
2084   XCTAssertTrue([dict valueForKey:24LL value:&value]);
2085   XCTAssertEqual(value, 503.f);
2086   [dict2 release];
2089 - (void)testRemove {
2090   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
2091   const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
2092   GPBInt64FloatDictionary *dict =
2093       [[GPBInt64FloatDictionary alloc] initWithValues:kValues
2094                                        forKeys:kKeys
2095                                          count:GPBARRAYSIZE(kValues)];
2096   XCTAssertNotNil(dict);
2097   XCTAssertEqual(dict.count, 4U);
2099   [dict removeValueForKey:22LL];
2100   XCTAssertEqual(dict.count, 3U);
2101   float value;
2102   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
2103   XCTAssertTrue([dict valueForKey:21LL value:&value]);
2104   XCTAssertEqual(value, 500.f);
2105   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
2106   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
2107   XCTAssertTrue([dict valueForKey:23LL value:&value]);
2108   XCTAssertEqual(value, 502.f);
2109   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
2110   XCTAssertTrue([dict valueForKey:24LL value:&value]);
2111   XCTAssertEqual(value, 503.f);
2113   // Remove again does nothing.
2114   [dict removeValueForKey:22LL];
2115   XCTAssertEqual(dict.count, 3U);
2116   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
2117   XCTAssertTrue([dict valueForKey:21LL value:&value]);
2118   XCTAssertEqual(value, 500.f);
2119   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
2120   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
2121   XCTAssertTrue([dict valueForKey:23LL value:&value]);
2122   XCTAssertEqual(value, 502.f);
2123   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
2124   XCTAssertTrue([dict valueForKey:24LL value:&value]);
2125   XCTAssertEqual(value, 503.f);
2127   [dict removeValueForKey:24LL];
2128   XCTAssertEqual(dict.count, 2U);
2129   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
2130   XCTAssertTrue([dict valueForKey:21LL value:&value]);
2131   XCTAssertEqual(value, 500.f);
2132   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
2133   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
2134   XCTAssertTrue([dict valueForKey:23LL value:&value]);
2135   XCTAssertEqual(value, 502.f);
2136   XCTAssertFalse([dict valueForKey:24LL value:NULL]);
2138   [dict removeAll];
2139   XCTAssertEqual(dict.count, 0U);
2140   XCTAssertFalse([dict valueForKey:21LL value:NULL]);
2141   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
2142   XCTAssertFalse([dict valueForKey:23LL value:NULL]);
2143   XCTAssertFalse([dict valueForKey:24LL value:NULL]);
2144   [dict release];
2147 - (void)testInplaceMutation {
2148   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
2149   const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
2150   GPBInt64FloatDictionary *dict =
2151       [[GPBInt64FloatDictionary alloc] initWithValues:kValues
2152                                        forKeys:kKeys
2153                                          count:GPBARRAYSIZE(kValues)];
2154   XCTAssertNotNil(dict);
2155   XCTAssertEqual(dict.count, 4U);
2156   float value;
2157   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
2158   XCTAssertTrue([dict valueForKey:21LL value:&value]);
2159   XCTAssertEqual(value, 500.f);
2160   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
2161   XCTAssertTrue([dict valueForKey:22LL value:&value]);
2162   XCTAssertEqual(value, 501.f);
2163   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
2164   XCTAssertTrue([dict valueForKey:23LL value:&value]);
2165   XCTAssertEqual(value, 502.f);
2166   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
2167   XCTAssertTrue([dict valueForKey:24LL value:&value]);
2168   XCTAssertEqual(value, 503.f);
2170   [dict setValue:503.f forKey:21LL];
2171   XCTAssertEqual(dict.count, 4U);
2172   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
2173   XCTAssertTrue([dict valueForKey:21LL value:&value]);
2174   XCTAssertEqual(value, 503.f);
2175   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
2176   XCTAssertTrue([dict valueForKey:22LL value:&value]);
2177   XCTAssertEqual(value, 501.f);
2178   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
2179   XCTAssertTrue([dict valueForKey:23LL value:&value]);
2180   XCTAssertEqual(value, 502.f);
2181   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
2182   XCTAssertTrue([dict valueForKey:24LL value:&value]);
2183   XCTAssertEqual(value, 503.f);
2185   [dict setValue:501.f forKey:24LL];
2186   XCTAssertEqual(dict.count, 4U);
2187   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
2188   XCTAssertTrue([dict valueForKey:21LL value:&value]);
2189   XCTAssertEqual(value, 503.f);
2190   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
2191   XCTAssertTrue([dict valueForKey:22LL value:&value]);
2192   XCTAssertEqual(value, 501.f);
2193   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
2194   XCTAssertTrue([dict valueForKey:23LL value:&value]);
2195   XCTAssertEqual(value, 502.f);
2196   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
2197   XCTAssertTrue([dict valueForKey:24LL value:&value]);
2198   XCTAssertEqual(value, 501.f);
2200   const int64_t kKeys2[] = { 22LL, 23LL };
2201   const float kValues2[] = { 502.f, 500.f };
2202   GPBInt64FloatDictionary *dict2 =
2203       [[GPBInt64FloatDictionary alloc] initWithValues:kValues2
2204                                               forKeys:kKeys2
2205                                                 count:GPBARRAYSIZE(kValues2)];
2206   XCTAssertNotNil(dict2);
2207   [dict addEntriesFromDictionary:dict2];
2208   XCTAssertEqual(dict.count, 4U);
2209   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
2210   XCTAssertTrue([dict valueForKey:21LL value:&value]);
2211   XCTAssertEqual(value, 503.f);
2212   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
2213   XCTAssertTrue([dict valueForKey:22LL value:&value]);
2214   XCTAssertEqual(value, 502.f);
2215   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
2216   XCTAssertTrue([dict valueForKey:23LL value:&value]);
2217   XCTAssertEqual(value, 500.f);
2218   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
2219   XCTAssertTrue([dict valueForKey:24LL value:&value]);
2220   XCTAssertEqual(value, 501.f);
2222   [dict2 release];
2223   [dict release];
2226 @end
2228 #pragma mark - Int64 -> Double
2230 @interface GPBInt64DoubleDictionaryTests : XCTestCase
2231 @end
2233 @implementation GPBInt64DoubleDictionaryTests
2235 - (void)testEmpty {
2236   GPBInt64DoubleDictionary *dict = [[GPBInt64DoubleDictionary alloc] init];
2237   XCTAssertNotNil(dict);
2238   XCTAssertEqual(dict.count, 0U);
2239   XCTAssertFalse([dict valueForKey:21LL value:NULL]);
2240   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, double aValue, BOOL *stop) {
2241     #pragma unused(aKey, aValue, stop)
2242     XCTFail(@"Shouldn't get here!");
2243   }];
2244   [dict release];
2247 - (void)testOne {
2248   GPBInt64DoubleDictionary *dict = [GPBInt64DoubleDictionary dictionaryWithValue:600. forKey:21LL];
2249   XCTAssertNotNil(dict);
2250   XCTAssertEqual(dict.count, 1U);
2251   double value;
2252   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
2253   XCTAssertTrue([dict valueForKey:21LL value:&value]);
2254   XCTAssertEqual(value, 600.);
2255   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
2256   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, double aValue, BOOL *stop) {
2257     XCTAssertEqual(aKey, 21LL);
2258     XCTAssertEqual(aValue, 600.);
2259     XCTAssertNotEqual(stop, NULL);
2260   }];
2263 - (void)testBasics {
2264   const int64_t kKeys[] = { 21LL, 22LL, 23LL };
2265   const double kValues[] = { 600., 601., 602. };
2266   GPBInt64DoubleDictionary *dict =
2267       [[GPBInt64DoubleDictionary alloc] initWithValues:kValues
2268                                                forKeys:kKeys
2269                                                  count:GPBARRAYSIZE(kValues)];
2270   XCTAssertNotNil(dict);
2271   XCTAssertEqual(dict.count, 3U);
2272   double value;
2273   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
2274   XCTAssertTrue([dict valueForKey:21LL value:&value]);
2275   XCTAssertEqual(value, 600.);
2276   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
2277   XCTAssertTrue([dict valueForKey:22LL value:&value]);
2278   XCTAssertEqual(value, 601.);
2279   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
2280   XCTAssertTrue([dict valueForKey:23LL value:&value]);
2281   XCTAssertEqual(value, 602.);
2282   XCTAssertFalse([dict valueForKey:24LL value:NULL]);
2284   __block NSUInteger idx = 0;
2285   int64_t *seenKeys = malloc(3 * sizeof(int64_t));
2286   double *seenValues = malloc(3 * sizeof(double));
2287   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, double aValue, BOOL *stop) {
2288     XCTAssertLessThan(idx, 3U);
2289     seenKeys[idx] = aKey;
2290     seenValues[idx] = aValue;
2291     XCTAssertNotEqual(stop, NULL);
2292     ++idx;
2293   }];
2294   for (int i = 0; i < 3; ++i) {
2295     BOOL foundKey = NO;
2296     for (int j = 0; (j < 3) && !foundKey; ++j) {
2297       if (kKeys[i] == seenKeys[j]) {
2298         foundKey = YES;
2299         XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
2300       }
2301     }
2302     XCTAssertTrue(foundKey, @"i = %d", i);
2303   }
2304   free(seenKeys);
2305   free(seenValues);
2307   // Stopping the enumeration.
2308   idx = 0;
2309   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, double aValue, BOOL *stop) {
2310     #pragma unused(aKey, aValue)
2311     if (idx == 1) *stop = YES;
2312     XCTAssertNotEqual(idx, 2U);
2313     ++idx;
2314   }];
2315   [dict release];
2318 - (void)testEquality {
2319   const int64_t kKeys1[] = { 21LL, 22LL, 23LL, 24LL };
2320   const int64_t kKeys2[] = { 22LL, 21LL, 24LL };
2321   const double kValues1[] = { 600., 601., 602. };
2322   const double kValues2[] = { 600., 603., 602. };
2323   const double kValues3[] = { 600., 601., 602., 603. };
2324   GPBInt64DoubleDictionary *dict1 =
2325       [[GPBInt64DoubleDictionary alloc] initWithValues:kValues1
2326                                                forKeys:kKeys1
2327                                                  count:GPBARRAYSIZE(kValues1)];
2328   XCTAssertNotNil(dict1);
2329   GPBInt64DoubleDictionary *dict1prime =
2330       [[GPBInt64DoubleDictionary alloc] initWithValues:kValues1
2331                                                forKeys:kKeys1
2332                                                  count:GPBARRAYSIZE(kValues1)];
2333   XCTAssertNotNil(dict1prime);
2334   GPBInt64DoubleDictionary *dict2 =
2335       [[GPBInt64DoubleDictionary alloc] initWithValues:kValues2
2336                                                forKeys:kKeys1
2337                                                  count:GPBARRAYSIZE(kValues2)];
2338   XCTAssertNotNil(dict2);
2339   GPBInt64DoubleDictionary *dict3 =
2340       [[GPBInt64DoubleDictionary alloc] initWithValues:kValues1
2341                                                forKeys:kKeys2
2342                                                  count:GPBARRAYSIZE(kValues1)];
2343   XCTAssertNotNil(dict3);
2344   GPBInt64DoubleDictionary *dict4 =
2345       [[GPBInt64DoubleDictionary alloc] initWithValues:kValues3
2346                                                forKeys:kKeys1
2347                                                  count:GPBARRAYSIZE(kValues3)];
2348   XCTAssertNotNil(dict4);
2350   // 1/1Prime should be different objects, but equal.
2351   XCTAssertNotEqual(dict1, dict1prime);
2352   XCTAssertEqualObjects(dict1, dict1prime);
2353   // Equal, so they must have same hash.
2354   XCTAssertEqual([dict1 hash], [dict1prime hash]);
2356   // 2 is save keys, different values; not equal.
2357   XCTAssertNotEqualObjects(dict1, dict2);
2359   // 3 is different keys, samae values; not equal.
2360   XCTAssertNotEqualObjects(dict1, dict3);
2362   // 4 extra pair; not equal
2363   XCTAssertNotEqualObjects(dict1, dict4);
2365   [dict1 release];
2366   [dict1prime release];
2367   [dict2 release];
2368   [dict3 release];
2369   [dict4 release];
2372 - (void)testCopy {
2373   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
2374   const double kValues[] = { 600., 601., 602., 603. };
2375   GPBInt64DoubleDictionary *dict =
2376       [[GPBInt64DoubleDictionary alloc] initWithValues:kValues
2377                                                forKeys:kKeys
2378                                                  count:GPBARRAYSIZE(kValues)];
2379   XCTAssertNotNil(dict);
2381   GPBInt64DoubleDictionary *dict2 = [dict copy];
2382   XCTAssertNotNil(dict2);
2384   // Should be new object but equal.
2385   XCTAssertNotEqual(dict, dict2);
2386   XCTAssertEqualObjects(dict, dict2);
2387   XCTAssertTrue([dict2 isKindOfClass:[GPBInt64DoubleDictionary class]]);
2389   [dict2 release];
2390   [dict release];
2393 - (void)testDictionaryFromDictionary {
2394   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
2395   const double kValues[] = { 600., 601., 602., 603. };
2396   GPBInt64DoubleDictionary *dict =
2397       [[GPBInt64DoubleDictionary alloc] initWithValues:kValues
2398                                                forKeys:kKeys
2399                                                  count:GPBARRAYSIZE(kValues)];
2400   XCTAssertNotNil(dict);
2402   GPBInt64DoubleDictionary *dict2 =
2403       [GPBInt64DoubleDictionary dictionaryWithDictionary:dict];
2404   XCTAssertNotNil(dict2);
2406   // Should be new pointer, but equal objects.
2407   XCTAssertNotEqual(dict, dict2);
2408   XCTAssertEqualObjects(dict, dict2);
2409   [dict release];
2412 - (void)testAdds {
2413   GPBInt64DoubleDictionary *dict = [GPBInt64DoubleDictionary dictionary];
2414   XCTAssertNotNil(dict);
2416   XCTAssertEqual(dict.count, 0U);
2417   [dict setValue:600. forKey:21LL];
2418   XCTAssertEqual(dict.count, 1U);
2420   const int64_t kKeys[] = { 22LL, 23LL, 24LL };
2421   const double kValues[] = { 601., 602., 603. };
2422   GPBInt64DoubleDictionary *dict2 =
2423       [[GPBInt64DoubleDictionary alloc] initWithValues:kValues
2424                                                forKeys:kKeys
2425                                                  count:GPBARRAYSIZE(kValues)];
2426   XCTAssertNotNil(dict2);
2427   [dict addEntriesFromDictionary:dict2];
2428   XCTAssertEqual(dict.count, 4U);
2430   double value;
2431   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
2432   XCTAssertTrue([dict valueForKey:21LL value:&value]);
2433   XCTAssertEqual(value, 600.);
2434   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
2435   XCTAssertTrue([dict valueForKey:22LL value:&value]);
2436   XCTAssertEqual(value, 601.);
2437   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
2438   XCTAssertTrue([dict valueForKey:23LL value:&value]);
2439   XCTAssertEqual(value, 602.);
2440   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
2441   XCTAssertTrue([dict valueForKey:24LL value:&value]);
2442   XCTAssertEqual(value, 603.);
2443   [dict2 release];
2446 - (void)testRemove {
2447   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
2448   const double kValues[] = { 600., 601., 602., 603. };
2449   GPBInt64DoubleDictionary *dict =
2450       [[GPBInt64DoubleDictionary alloc] initWithValues:kValues
2451                                         forKeys:kKeys
2452                                           count:GPBARRAYSIZE(kValues)];
2453   XCTAssertNotNil(dict);
2454   XCTAssertEqual(dict.count, 4U);
2456   [dict removeValueForKey:22LL];
2457   XCTAssertEqual(dict.count, 3U);
2458   double value;
2459   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
2460   XCTAssertTrue([dict valueForKey:21LL value:&value]);
2461   XCTAssertEqual(value, 600.);
2462   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
2463   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
2464   XCTAssertTrue([dict valueForKey:23LL value:&value]);
2465   XCTAssertEqual(value, 602.);
2466   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
2467   XCTAssertTrue([dict valueForKey:24LL value:&value]);
2468   XCTAssertEqual(value, 603.);
2470   // Remove again does nothing.
2471   [dict removeValueForKey:22LL];
2472   XCTAssertEqual(dict.count, 3U);
2473   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
2474   XCTAssertTrue([dict valueForKey:21LL value:&value]);
2475   XCTAssertEqual(value, 600.);
2476   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
2477   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
2478   XCTAssertTrue([dict valueForKey:23LL value:&value]);
2479   XCTAssertEqual(value, 602.);
2480   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
2481   XCTAssertTrue([dict valueForKey:24LL value:&value]);
2482   XCTAssertEqual(value, 603.);
2484   [dict removeValueForKey:24LL];
2485   XCTAssertEqual(dict.count, 2U);
2486   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
2487   XCTAssertTrue([dict valueForKey:21LL value:&value]);
2488   XCTAssertEqual(value, 600.);
2489   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
2490   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
2491   XCTAssertTrue([dict valueForKey:23LL value:&value]);
2492   XCTAssertEqual(value, 602.);
2493   XCTAssertFalse([dict valueForKey:24LL value:NULL]);
2495   [dict removeAll];
2496   XCTAssertEqual(dict.count, 0U);
2497   XCTAssertFalse([dict valueForKey:21LL value:NULL]);
2498   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
2499   XCTAssertFalse([dict valueForKey:23LL value:NULL]);
2500   XCTAssertFalse([dict valueForKey:24LL value:NULL]);
2501   [dict release];
2504 - (void)testInplaceMutation {
2505   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
2506   const double kValues[] = { 600., 601., 602., 603. };
2507   GPBInt64DoubleDictionary *dict =
2508       [[GPBInt64DoubleDictionary alloc] initWithValues:kValues
2509                                         forKeys:kKeys
2510                                           count:GPBARRAYSIZE(kValues)];
2511   XCTAssertNotNil(dict);
2512   XCTAssertEqual(dict.count, 4U);
2513   double value;
2514   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
2515   XCTAssertTrue([dict valueForKey:21LL value:&value]);
2516   XCTAssertEqual(value, 600.);
2517   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
2518   XCTAssertTrue([dict valueForKey:22LL value:&value]);
2519   XCTAssertEqual(value, 601.);
2520   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
2521   XCTAssertTrue([dict valueForKey:23LL value:&value]);
2522   XCTAssertEqual(value, 602.);
2523   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
2524   XCTAssertTrue([dict valueForKey:24LL value:&value]);
2525   XCTAssertEqual(value, 603.);
2527   [dict setValue:603. forKey:21LL];
2528   XCTAssertEqual(dict.count, 4U);
2529   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
2530   XCTAssertTrue([dict valueForKey:21LL value:&value]);
2531   XCTAssertEqual(value, 603.);
2532   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
2533   XCTAssertTrue([dict valueForKey:22LL value:&value]);
2534   XCTAssertEqual(value, 601.);
2535   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
2536   XCTAssertTrue([dict valueForKey:23LL value:&value]);
2537   XCTAssertEqual(value, 602.);
2538   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
2539   XCTAssertTrue([dict valueForKey:24LL value:&value]);
2540   XCTAssertEqual(value, 603.);
2542   [dict setValue:601. forKey:24LL];
2543   XCTAssertEqual(dict.count, 4U);
2544   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
2545   XCTAssertTrue([dict valueForKey:21LL value:&value]);
2546   XCTAssertEqual(value, 603.);
2547   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
2548   XCTAssertTrue([dict valueForKey:22LL value:&value]);
2549   XCTAssertEqual(value, 601.);
2550   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
2551   XCTAssertTrue([dict valueForKey:23LL value:&value]);
2552   XCTAssertEqual(value, 602.);
2553   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
2554   XCTAssertTrue([dict valueForKey:24LL value:&value]);
2555   XCTAssertEqual(value, 601.);
2557   const int64_t kKeys2[] = { 22LL, 23LL };
2558   const double kValues2[] = { 602., 600. };
2559   GPBInt64DoubleDictionary *dict2 =
2560       [[GPBInt64DoubleDictionary alloc] initWithValues:kValues2
2561                                                forKeys:kKeys2
2562                                                  count:GPBARRAYSIZE(kValues2)];
2563   XCTAssertNotNil(dict2);
2564   [dict addEntriesFromDictionary:dict2];
2565   XCTAssertEqual(dict.count, 4U);
2566   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
2567   XCTAssertTrue([dict valueForKey:21LL value:&value]);
2568   XCTAssertEqual(value, 603.);
2569   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
2570   XCTAssertTrue([dict valueForKey:22LL value:&value]);
2571   XCTAssertEqual(value, 602.);
2572   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
2573   XCTAssertTrue([dict valueForKey:23LL value:&value]);
2574   XCTAssertEqual(value, 600.);
2575   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
2576   XCTAssertTrue([dict valueForKey:24LL value:&value]);
2577   XCTAssertEqual(value, 601.);
2579   [dict2 release];
2580   [dict release];
2583 @end
2585 #pragma mark - Int64 -> Enum
2587 @interface GPBInt64EnumDictionaryTests : XCTestCase
2588 @end
2590 @implementation GPBInt64EnumDictionaryTests
2592 - (void)testEmpty {
2593   GPBInt64EnumDictionary *dict = [[GPBInt64EnumDictionary alloc] init];
2594   XCTAssertNotNil(dict);
2595   XCTAssertEqual(dict.count, 0U);
2596   XCTAssertFalse([dict valueForKey:21LL value:NULL]);
2597   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
2598     #pragma unused(aKey, aValue, stop)
2599     XCTFail(@"Shouldn't get here!");
2600   }];
2601   [dict release];
2604 - (void)testOne {
2605   GPBInt64EnumDictionary *dict = [GPBInt64EnumDictionary dictionaryWithValue:700 forKey:21LL];
2606   XCTAssertNotNil(dict);
2607   XCTAssertEqual(dict.count, 1U);
2608   int32_t value;
2609   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
2610   XCTAssertTrue([dict valueForKey:21LL value:&value]);
2611   XCTAssertEqual(value, 700);
2612   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
2613   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
2614     XCTAssertEqual(aKey, 21LL);
2615     XCTAssertEqual(aValue, 700);
2616     XCTAssertNotEqual(stop, NULL);
2617   }];
2620 - (void)testBasics {
2621   const int64_t kKeys[] = { 21LL, 22LL, 23LL };
2622   const int32_t kValues[] = { 700, 701, 702 };
2623   GPBInt64EnumDictionary *dict =
2624       [[GPBInt64EnumDictionary alloc] initWithValues:kValues
2625                                              forKeys:kKeys
2626                                                count:GPBARRAYSIZE(kValues)];
2627   XCTAssertNotNil(dict);
2628   XCTAssertEqual(dict.count, 3U);
2629   int32_t value;
2630   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
2631   XCTAssertTrue([dict valueForKey:21LL value:&value]);
2632   XCTAssertEqual(value, 700);
2633   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
2634   XCTAssertTrue([dict valueForKey:22LL value:&value]);
2635   XCTAssertEqual(value, 701);
2636   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
2637   XCTAssertTrue([dict valueForKey:23LL value:&value]);
2638   XCTAssertEqual(value, 702);
2639   XCTAssertFalse([dict valueForKey:24LL value:NULL]);
2641   __block NSUInteger idx = 0;
2642   int64_t *seenKeys = malloc(3 * sizeof(int64_t));
2643   int32_t *seenValues = malloc(3 * sizeof(int32_t));
2644   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
2645     XCTAssertLessThan(idx, 3U);
2646     seenKeys[idx] = aKey;
2647     seenValues[idx] = aValue;
2648     XCTAssertNotEqual(stop, NULL);
2649     ++idx;
2650   }];
2651   for (int i = 0; i < 3; ++i) {
2652     BOOL foundKey = NO;
2653     for (int j = 0; (j < 3) && !foundKey; ++j) {
2654       if (kKeys[i] == seenKeys[j]) {
2655         foundKey = YES;
2656         XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
2657       }
2658     }
2659     XCTAssertTrue(foundKey, @"i = %d", i);
2660   }
2661   free(seenKeys);
2662   free(seenValues);
2664   // Stopping the enumeration.
2665   idx = 0;
2666   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
2667     #pragma unused(aKey, aValue)
2668     if (idx == 1) *stop = YES;
2669     XCTAssertNotEqual(idx, 2U);
2670     ++idx;
2671   }];
2672   [dict release];
2675 - (void)testEquality {
2676   const int64_t kKeys1[] = { 21LL, 22LL, 23LL, 24LL };
2677   const int64_t kKeys2[] = { 22LL, 21LL, 24LL };
2678   const int32_t kValues1[] = { 700, 701, 702 };
2679   const int32_t kValues2[] = { 700, 703, 702 };
2680   const int32_t kValues3[] = { 700, 701, 702, 703 };
2681   GPBInt64EnumDictionary *dict1 =
2682       [[GPBInt64EnumDictionary alloc] initWithValues:kValues1
2683                                              forKeys:kKeys1
2684                                                count:GPBARRAYSIZE(kValues1)];
2685   XCTAssertNotNil(dict1);
2686   GPBInt64EnumDictionary *dict1prime =
2687       [[GPBInt64EnumDictionary alloc] initWithValues:kValues1
2688                                              forKeys:kKeys1
2689                                                count:GPBARRAYSIZE(kValues1)];
2690   XCTAssertNotNil(dict1prime);
2691   GPBInt64EnumDictionary *dict2 =
2692       [[GPBInt64EnumDictionary alloc] initWithValues:kValues2
2693                                              forKeys:kKeys1
2694                                                count:GPBARRAYSIZE(kValues2)];
2695   XCTAssertNotNil(dict2);
2696   GPBInt64EnumDictionary *dict3 =
2697       [[GPBInt64EnumDictionary alloc] initWithValues:kValues1
2698                                              forKeys:kKeys2
2699                                                count:GPBARRAYSIZE(kValues1)];
2700   XCTAssertNotNil(dict3);
2701   GPBInt64EnumDictionary *dict4 =
2702       [[GPBInt64EnumDictionary alloc] initWithValues:kValues3
2703                                              forKeys:kKeys1
2704                                                count:GPBARRAYSIZE(kValues3)];
2705   XCTAssertNotNil(dict4);
2707   // 1/1Prime should be different objects, but equal.
2708   XCTAssertNotEqual(dict1, dict1prime);
2709   XCTAssertEqualObjects(dict1, dict1prime);
2710   // Equal, so they must have same hash.
2711   XCTAssertEqual([dict1 hash], [dict1prime hash]);
2713   // 2 is save keys, different values; not equal.
2714   XCTAssertNotEqualObjects(dict1, dict2);
2716   // 3 is different keys, samae values; not equal.
2717   XCTAssertNotEqualObjects(dict1, dict3);
2719   // 4 extra pair; not equal
2720   XCTAssertNotEqualObjects(dict1, dict4);
2722   [dict1 release];
2723   [dict1prime release];
2724   [dict2 release];
2725   [dict3 release];
2726   [dict4 release];
2729 - (void)testCopy {
2730   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
2731   const int32_t kValues[] = { 700, 701, 702, 703 };
2732   GPBInt64EnumDictionary *dict =
2733       [[GPBInt64EnumDictionary alloc] initWithValues:kValues
2734                                              forKeys:kKeys
2735                                                count:GPBARRAYSIZE(kValues)];
2736   XCTAssertNotNil(dict);
2738   GPBInt64EnumDictionary *dict2 = [dict copy];
2739   XCTAssertNotNil(dict2);
2741   // Should be new object but equal.
2742   XCTAssertNotEqual(dict, dict2);
2743   XCTAssertEqualObjects(dict, dict2);
2744   XCTAssertTrue([dict2 isKindOfClass:[GPBInt64EnumDictionary class]]);
2746   [dict2 release];
2747   [dict release];
2750 - (void)testDictionaryFromDictionary {
2751   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
2752   const int32_t kValues[] = { 700, 701, 702, 703 };
2753   GPBInt64EnumDictionary *dict =
2754       [[GPBInt64EnumDictionary alloc] initWithValues:kValues
2755                                              forKeys:kKeys
2756                                                count:GPBARRAYSIZE(kValues)];
2757   XCTAssertNotNil(dict);
2759   GPBInt64EnumDictionary *dict2 =
2760       [GPBInt64EnumDictionary dictionaryWithDictionary:dict];
2761   XCTAssertNotNil(dict2);
2763   // Should be new pointer, but equal objects.
2764   XCTAssertNotEqual(dict, dict2);
2765   XCTAssertEqualObjects(dict, dict2);
2766   [dict release];
2769 - (void)testAdds {
2770   GPBInt64EnumDictionary *dict = [GPBInt64EnumDictionary dictionary];
2771   XCTAssertNotNil(dict);
2773   XCTAssertEqual(dict.count, 0U);
2774   [dict setValue:700 forKey:21LL];
2775   XCTAssertEqual(dict.count, 1U);
2777   const int64_t kKeys[] = { 22LL, 23LL, 24LL };
2778   const int32_t kValues[] = { 701, 702, 703 };
2779   GPBInt64EnumDictionary *dict2 =
2780       [[GPBInt64EnumDictionary alloc] initWithValues:kValues
2781                                              forKeys:kKeys
2782                                                count:GPBARRAYSIZE(kValues)];
2783   XCTAssertNotNil(dict2);
2784   [dict addRawEntriesFromDictionary:dict2];
2785   XCTAssertEqual(dict.count, 4U);
2787   int32_t value;
2788   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
2789   XCTAssertTrue([dict valueForKey:21LL value:&value]);
2790   XCTAssertEqual(value, 700);
2791   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
2792   XCTAssertTrue([dict valueForKey:22LL value:&value]);
2793   XCTAssertEqual(value, 701);
2794   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
2795   XCTAssertTrue([dict valueForKey:23LL value:&value]);
2796   XCTAssertEqual(value, 702);
2797   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
2798   XCTAssertTrue([dict valueForKey:24LL value:&value]);
2799   XCTAssertEqual(value, 703);
2800   [dict2 release];
2803 - (void)testRemove {
2804   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
2805   const int32_t kValues[] = { 700, 701, 702, 703 };
2806   GPBInt64EnumDictionary *dict =
2807       [[GPBInt64EnumDictionary alloc] initWithValues:kValues
2808                                       forKeys:kKeys
2809                                         count:GPBARRAYSIZE(kValues)];
2810   XCTAssertNotNil(dict);
2811   XCTAssertEqual(dict.count, 4U);
2813   [dict removeValueForKey:22LL];
2814   XCTAssertEqual(dict.count, 3U);
2815   int32_t value;
2816   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
2817   XCTAssertTrue([dict valueForKey:21LL value:&value]);
2818   XCTAssertEqual(value, 700);
2819   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
2820   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
2821   XCTAssertTrue([dict valueForKey:23LL value:&value]);
2822   XCTAssertEqual(value, 702);
2823   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
2824   XCTAssertTrue([dict valueForKey:24LL value:&value]);
2825   XCTAssertEqual(value, 703);
2827   // Remove again does nothing.
2828   [dict removeValueForKey:22LL];
2829   XCTAssertEqual(dict.count, 3U);
2830   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
2831   XCTAssertTrue([dict valueForKey:21LL value:&value]);
2832   XCTAssertEqual(value, 700);
2833   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
2834   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
2835   XCTAssertTrue([dict valueForKey:23LL value:&value]);
2836   XCTAssertEqual(value, 702);
2837   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
2838   XCTAssertTrue([dict valueForKey:24LL value:&value]);
2839   XCTAssertEqual(value, 703);
2841   [dict removeValueForKey:24LL];
2842   XCTAssertEqual(dict.count, 2U);
2843   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
2844   XCTAssertTrue([dict valueForKey:21LL value:&value]);
2845   XCTAssertEqual(value, 700);
2846   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
2847   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
2848   XCTAssertTrue([dict valueForKey:23LL value:&value]);
2849   XCTAssertEqual(value, 702);
2850   XCTAssertFalse([dict valueForKey:24LL value:NULL]);
2852   [dict removeAll];
2853   XCTAssertEqual(dict.count, 0U);
2854   XCTAssertFalse([dict valueForKey:21LL value:NULL]);
2855   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
2856   XCTAssertFalse([dict valueForKey:23LL value:NULL]);
2857   XCTAssertFalse([dict valueForKey:24LL value:NULL]);
2858   [dict release];
2861 - (void)testInplaceMutation {
2862   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
2863   const int32_t kValues[] = { 700, 701, 702, 703 };
2864   GPBInt64EnumDictionary *dict =
2865       [[GPBInt64EnumDictionary alloc] initWithValues:kValues
2866                                       forKeys:kKeys
2867                                         count:GPBARRAYSIZE(kValues)];
2868   XCTAssertNotNil(dict);
2869   XCTAssertEqual(dict.count, 4U);
2870   int32_t value;
2871   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
2872   XCTAssertTrue([dict valueForKey:21LL value:&value]);
2873   XCTAssertEqual(value, 700);
2874   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
2875   XCTAssertTrue([dict valueForKey:22LL value:&value]);
2876   XCTAssertEqual(value, 701);
2877   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
2878   XCTAssertTrue([dict valueForKey:23LL value:&value]);
2879   XCTAssertEqual(value, 702);
2880   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
2881   XCTAssertTrue([dict valueForKey:24LL value:&value]);
2882   XCTAssertEqual(value, 703);
2884   [dict setValue:703 forKey:21LL];
2885   XCTAssertEqual(dict.count, 4U);
2886   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
2887   XCTAssertTrue([dict valueForKey:21LL value:&value]);
2888   XCTAssertEqual(value, 703);
2889   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
2890   XCTAssertTrue([dict valueForKey:22LL value:&value]);
2891   XCTAssertEqual(value, 701);
2892   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
2893   XCTAssertTrue([dict valueForKey:23LL value:&value]);
2894   XCTAssertEqual(value, 702);
2895   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
2896   XCTAssertTrue([dict valueForKey:24LL value:&value]);
2897   XCTAssertEqual(value, 703);
2899   [dict setValue:701 forKey:24LL];
2900   XCTAssertEqual(dict.count, 4U);
2901   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
2902   XCTAssertTrue([dict valueForKey:21LL value:&value]);
2903   XCTAssertEqual(value, 703);
2904   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
2905   XCTAssertTrue([dict valueForKey:22LL value:&value]);
2906   XCTAssertEqual(value, 701);
2907   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
2908   XCTAssertTrue([dict valueForKey:23LL value:&value]);
2909   XCTAssertEqual(value, 702);
2910   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
2911   XCTAssertTrue([dict valueForKey:24LL value:&value]);
2912   XCTAssertEqual(value, 701);
2914   const int64_t kKeys2[] = { 22LL, 23LL };
2915   const int32_t kValues2[] = { 702, 700 };
2916   GPBInt64EnumDictionary *dict2 =
2917       [[GPBInt64EnumDictionary alloc] initWithValues:kValues2
2918                                              forKeys:kKeys2
2919                                                count:GPBARRAYSIZE(kValues2)];
2920   XCTAssertNotNil(dict2);
2921   [dict addRawEntriesFromDictionary:dict2];
2922   XCTAssertEqual(dict.count, 4U);
2923   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
2924   XCTAssertTrue([dict valueForKey:21LL value:&value]);
2925   XCTAssertEqual(value, 703);
2926   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
2927   XCTAssertTrue([dict valueForKey:22LL value:&value]);
2928   XCTAssertEqual(value, 702);
2929   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
2930   XCTAssertTrue([dict valueForKey:23LL value:&value]);
2931   XCTAssertEqual(value, 700);
2932   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
2933   XCTAssertTrue([dict valueForKey:24LL value:&value]);
2934   XCTAssertEqual(value, 701);
2936   [dict2 release];
2937   [dict release];
2940 @end
2942 #pragma mark - Int64 -> Enum (Unknown Enums)
2944 @interface GPBInt64EnumDictionaryUnknownEnumTests : XCTestCase
2945 @end
2947 @implementation GPBInt64EnumDictionaryUnknownEnumTests
2949 - (void)testRawBasics {
2950   const int64_t kKeys[] = { 21LL, 22LL, 23LL };
2951   const int32_t kValues[] = { 700, 801, 702 };
2952   GPBInt64EnumDictionary *dict =
2953       [[GPBInt64EnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
2954                                                        rawValues:kValues
2955                                                          forKeys:kKeys
2956                                                            count:GPBARRAYSIZE(kValues)];
2957   XCTAssertNotNil(dict);
2958   XCTAssertEqual(dict.count, 3U);
2959   XCTAssertTrue(dict.validationFunc == TestingEnum_IsValidValue);  // Pointer comparison
2960   int32_t value;
2961   XCTAssertTrue([dict valueForKey:21LL rawValue:NULL]);
2962   XCTAssertTrue([dict valueForKey:21LL rawValue:&value]);
2963   XCTAssertEqual(value, 700);
2964   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
2965   XCTAssertTrue([dict valueForKey:22LL value:&value]);
2966   XCTAssertEqual(value, kGPBUnrecognizedEnumeratorValue);
2967   XCTAssertTrue([dict valueForKey:22LL rawValue:NULL]);
2968   XCTAssertTrue([dict valueForKey:22LL rawValue:&value]);
2969   XCTAssertEqual(value, 801);
2970   XCTAssertTrue([dict valueForKey:23LL rawValue:NULL]);
2971   XCTAssertTrue([dict valueForKey:23LL rawValue:&value]);
2972   XCTAssertEqual(value, 702);
2973   XCTAssertFalse([dict valueForKey:24LL rawValue:NULL]);
2975   __block NSUInteger idx = 0;
2976   int64_t *seenKeys = malloc(3 * sizeof(int64_t));
2977   int32_t *seenValues = malloc(3 * sizeof(int32_t));
2978   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
2979     XCTAssertLessThan(idx, 3U);
2980     seenKeys[idx] = aKey;
2981     seenValues[idx] = aValue;
2982     XCTAssertNotEqual(stop, NULL);
2983     ++idx;
2984   }];
2985   for (int i = 0; i < 3; ++i) {
2986     BOOL foundKey = NO;
2987     for (int j = 0; (j < 3) && !foundKey; ++j) {
2988       if (kKeys[i] == seenKeys[j]) {
2989         foundKey = YES;
2990         if (i == 1) {
2991           XCTAssertEqual(kGPBUnrecognizedEnumeratorValue, seenValues[j], @"i = %d, j = %d", i, j);
2992         } else {
2993           XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
2994         }
2995       }
2996     }
2997     XCTAssertTrue(foundKey, @"i = %d", i);
2998   }
2999   idx = 0;
3000   [dict enumerateKeysAndRawValuesUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
3001     XCTAssertLessThan(idx, 3U);
3002     seenKeys[idx] = aKey;
3003     seenValues[idx] = aValue;
3004     XCTAssertNotEqual(stop, NULL);
3005     ++idx;
3006   }];
3007   for (int i = 0; i < 3; ++i) {
3008     BOOL foundKey = NO;
3009     for (int j = 0; (j < 3) && !foundKey; ++j) {
3010       if (kKeys[i] == seenKeys[j]) {
3011         foundKey = YES;
3012         XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
3013       }
3014     }
3015     XCTAssertTrue(foundKey, @"i = %d", i);
3016   }
3017   free(seenKeys);
3018   free(seenValues);
3020   // Stopping the enumeration.
3021   idx = 0;
3022   [dict enumerateKeysAndRawValuesUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
3023     #pragma unused(aKey, aValue)
3024     if (idx == 1) *stop = YES;
3025     XCTAssertNotEqual(idx, 2U);
3026     ++idx;
3027   }];
3028   [dict release];
3031 - (void)testEqualityWithUnknowns {
3032   const int64_t kKeys1[] = { 21LL, 22LL, 23LL, 24LL };
3033   const int64_t kKeys2[] = { 22LL, 21LL, 24LL };
3034   const int32_t kValues1[] = { 700, 801, 702 };  // Unknown
3035   const int32_t kValues2[] = { 700, 803, 702 };  // Unknown
3036   const int32_t kValues3[] = { 700, 801, 702, 803 };  // Unknowns
3037   GPBInt64EnumDictionary *dict1 =
3038       [[GPBInt64EnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3039                                                        rawValues:kValues1
3040                                                          forKeys:kKeys1
3041                                                            count:GPBARRAYSIZE(kValues1)];
3042   XCTAssertNotNil(dict1);
3043   GPBInt64EnumDictionary *dict1prime =
3044       [[GPBInt64EnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3045                                                        rawValues:kValues1
3046                                                          forKeys:kKeys1
3047                                                            count:GPBARRAYSIZE(kValues1)];
3048   XCTAssertNotNil(dict1prime);
3049   GPBInt64EnumDictionary *dict2 =
3050       [[GPBInt64EnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3051                                                        rawValues:kValues2
3052                                                          forKeys:kKeys1
3053                                                            count:GPBARRAYSIZE(kValues2)];
3054   XCTAssertNotNil(dict2);
3055   GPBInt64EnumDictionary *dict3 =
3056       [[GPBInt64EnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3057                                                        rawValues:kValues1
3058                                                          forKeys:kKeys2
3059                                                            count:GPBARRAYSIZE(kValues1)];
3060   XCTAssertNotNil(dict3);
3061   GPBInt64EnumDictionary *dict4 =
3062       [[GPBInt64EnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3063                                                        rawValues:kValues3
3064                                                          forKeys:kKeys1
3065                                                            count:GPBARRAYSIZE(kValues3)];
3066   XCTAssertNotNil(dict4);
3068   // 1/1Prime should be different objects, but equal.
3069   XCTAssertNotEqual(dict1, dict1prime);
3070   XCTAssertEqualObjects(dict1, dict1prime);
3071   // Equal, so they must have same hash.
3072   XCTAssertEqual([dict1 hash], [dict1prime hash]);
3074   // 2 is save keys, different values; not equal.
3075   XCTAssertNotEqualObjects(dict1, dict2);
3077   // 3 is different keys, samae values; not equal.
3078   XCTAssertNotEqualObjects(dict1, dict3);
3080   // 4 extra pair; not equal
3081   XCTAssertNotEqualObjects(dict1, dict4);
3083   [dict1 release];
3084   [dict1prime release];
3085   [dict2 release];
3086   [dict3 release];
3087   [dict4 release];
3090 - (void)testCopyWithUnknowns {
3091   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
3092   const int32_t kValues[] = { 700, 801, 702, 803 };  // Unknown
3093   GPBInt64EnumDictionary *dict =
3094       [[GPBInt64EnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3095                                                        rawValues:kValues
3096                                                          forKeys:kKeys
3097                                                            count:GPBARRAYSIZE(kValues)];
3098   XCTAssertNotNil(dict);
3100   GPBInt64EnumDictionary *dict2 = [dict copy];
3101   XCTAssertNotNil(dict2);
3103   // Should be new pointer, but equal objects.
3104   XCTAssertNotEqual(dict, dict2);
3105   XCTAssertEqual(dict.validationFunc, dict2.validationFunc);  // Pointer comparison
3106   XCTAssertEqualObjects(dict, dict2);
3108   [dict2 release];
3109   [dict release];
3112 - (void)testDictionaryFromDictionary {
3113   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
3114   const int32_t kValues[] = { 700, 801, 702, 803 };  // Unknowns
3115   GPBInt64EnumDictionary *dict =
3116       [[GPBInt64EnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3117                                                        rawValues:kValues
3118                                                          forKeys:kKeys
3119                                                            count:GPBARRAYSIZE(kValues)];
3120   XCTAssertNotNil(dict);
3122   GPBInt64EnumDictionary *dict2 =
3123       [GPBInt64EnumDictionary dictionaryWithDictionary:dict];
3124   XCTAssertNotNil(dict2);
3126   // Should be new pointer, but equal objects.
3127   XCTAssertNotEqual(dict, dict2);
3128   XCTAssertEqualObjects(dict, dict2);
3129   XCTAssertEqual(dict.validationFunc, dict2.validationFunc);  // Pointer comparison
3130   [dict release];
3133 - (void)testUnknownAdds {
3134   GPBInt64EnumDictionary *dict =
3135     [GPBInt64EnumDictionary dictionaryWithValidationFunction:TestingEnum_IsValidValue];
3136   XCTAssertNotNil(dict);
3138   XCTAssertEqual(dict.count, 0U);
3139   XCTAssertThrowsSpecificNamed([dict setValue:801 forKey:22LL],  // Unknown
3140                                NSException, NSInvalidArgumentException);
3141   XCTAssertEqual(dict.count, 0U);
3142   [dict setRawValue:801 forKey:22LL];  // Unknown
3143   XCTAssertEqual(dict.count, 1U);
3145   const int64_t kKeys[] = { 21LL, 23LL, 24LL };
3146   const int32_t kValues[] = { 700, 702, 803 };  // Unknown
3147   GPBInt64EnumDictionary *dict2 =
3148       [[GPBInt64EnumDictionary alloc] initWithValues:kValues
3149                                              forKeys:kKeys
3150                                                count:GPBARRAYSIZE(kValues)];
3151   XCTAssertNotNil(dict2);
3152   [dict addRawEntriesFromDictionary:dict2];
3153   XCTAssertEqual(dict.count, 4U);
3155   int32_t value;
3156   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
3157   XCTAssertTrue([dict valueForKey:21LL value:&value]);
3158   XCTAssertEqual(value, 700);
3159   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
3160   XCTAssertTrue([dict valueForKey:22LL value:&value]);
3161   XCTAssertEqual(value, kGPBUnrecognizedEnumeratorValue);
3162   XCTAssertTrue([dict valueForKey:22LL rawValue:NULL]);
3163   XCTAssertTrue([dict valueForKey:22LL rawValue:&value]);
3164   XCTAssertEqual(value, 801);
3165   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
3166   XCTAssertTrue([dict valueForKey:23LL value:&value]);
3167   XCTAssertEqual(value, 702);
3168   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
3169   XCTAssertTrue([dict valueForKey:24LL value:&value]);
3170   XCTAssertEqual(value, kGPBUnrecognizedEnumeratorValue);
3171   XCTAssertTrue([dict valueForKey:24LL rawValue:NULL]);
3172   XCTAssertTrue([dict valueForKey:24LL rawValue:&value]);
3173   XCTAssertEqual(value, 803);
3174   [dict2 release];
3177 - (void)testUnknownRemove {
3178   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
3179   const int32_t kValues[] = { 700, 801, 702, 803 };  // Unknowns
3180   GPBInt64EnumDictionary *dict =
3181       [[GPBInt64EnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3182                                                        rawValues:kValues
3183                                                          forKeys:kKeys
3184                                                            count:GPBARRAYSIZE(kValues)];
3185   XCTAssertNotNil(dict);
3186   XCTAssertEqual(dict.count, 4U);
3188   [dict removeValueForKey:22LL];
3189   XCTAssertEqual(dict.count, 3U);
3190   int32_t value;
3191   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
3192   XCTAssertTrue([dict valueForKey:21LL value:&value]);
3193   XCTAssertEqual(value, 700);
3194   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
3195   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
3196   XCTAssertTrue([dict valueForKey:23LL value:&value]);
3197   XCTAssertEqual(value, 702);
3198   XCTAssertTrue([dict valueForKey:24LL rawValue:NULL]);
3199   XCTAssertTrue([dict valueForKey:24LL rawValue:&value]);
3200   XCTAssertEqual(value, 803);
3202   // Remove again does nothing.
3203   [dict removeValueForKey:22LL];
3204   XCTAssertEqual(dict.count, 3U);
3205   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
3206   XCTAssertTrue([dict valueForKey:21LL value:&value]);
3207   XCTAssertEqual(value, 700);
3208   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
3209   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
3210   XCTAssertTrue([dict valueForKey:23LL value:&value]);
3211   XCTAssertEqual(value, 702);
3212   XCTAssertTrue([dict valueForKey:24LL rawValue:NULL]);
3213   XCTAssertTrue([dict valueForKey:24LL rawValue:&value]);
3214   XCTAssertEqual(value, 803);
3216   [dict removeValueForKey:24LL];
3217   XCTAssertEqual(dict.count, 2U);
3218   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
3219   XCTAssertTrue([dict valueForKey:21LL value:&value]);
3220   XCTAssertEqual(value, 700);
3221   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
3222   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
3223   XCTAssertTrue([dict valueForKey:23LL value:&value]);
3224   XCTAssertEqual(value, 702);
3225   XCTAssertFalse([dict valueForKey:24LL value:NULL]);
3227   [dict removeAll];
3228   XCTAssertEqual(dict.count, 0U);
3229   XCTAssertFalse([dict valueForKey:21LL value:NULL]);
3230   XCTAssertFalse([dict valueForKey:22LL value:NULL]);
3231   XCTAssertFalse([dict valueForKey:23LL value:NULL]);
3232   XCTAssertFalse([dict valueForKey:24LL value:NULL]);
3233   [dict release];
3236 - (void)testInplaceMutationUnknowns {
3237   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
3238   const int32_t kValues[] = { 700, 801, 702, 803 };  // Unknowns
3239   GPBInt64EnumDictionary *dict =
3240       [[GPBInt64EnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3241                                                        rawValues:kValues
3242                                                          forKeys:kKeys
3243                                                            count:GPBARRAYSIZE(kValues)];
3244   XCTAssertNotNil(dict);
3245   XCTAssertEqual(dict.count, 4U);
3246   int32_t value;
3247   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
3248   XCTAssertTrue([dict valueForKey:21LL value:&value]);
3249   XCTAssertEqual(value, 700);
3250   XCTAssertTrue([dict valueForKey:22LL rawValue:NULL]);
3251   XCTAssertTrue([dict valueForKey:22LL rawValue:&value]);
3252   XCTAssertEqual(value, 801);
3253   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
3254   XCTAssertTrue([dict valueForKey:23LL value:&value]);
3255   XCTAssertEqual(value, 702);
3256   XCTAssertTrue([dict valueForKey:24LL rawValue:NULL]);
3257   XCTAssertTrue([dict valueForKey:24LL rawValue:&value]);
3258   XCTAssertEqual(value, 803);
3260   XCTAssertThrowsSpecificNamed([dict setValue:803 forKey:21LL],  // Unknown
3261                                NSException, NSInvalidArgumentException);
3262   XCTAssertEqual(dict.count, 4U);
3263   XCTAssertTrue([dict valueForKey:21LL value:NULL]);
3264   XCTAssertTrue([dict valueForKey:21LL value:&value]);
3265   XCTAssertEqual(value, 700);
3266   XCTAssertTrue([dict valueForKey:22LL rawValue:NULL]);
3267   XCTAssertTrue([dict valueForKey:22LL rawValue:&value]);
3268   XCTAssertEqual(value, 801);
3269   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
3270   XCTAssertTrue([dict valueForKey:23LL value:&value]);
3271   XCTAssertEqual(value, 702);
3272   XCTAssertTrue([dict valueForKey:24LL rawValue:NULL]);
3273   XCTAssertTrue([dict valueForKey:24LL rawValue:&value]);
3274   XCTAssertEqual(value, 803);
3276   [dict setRawValue:803 forKey:21LL];  // Unknown
3277   XCTAssertEqual(dict.count, 4U);
3278   XCTAssertTrue([dict valueForKey:21LL rawValue:NULL]);
3279   XCTAssertTrue([dict valueForKey:21LL rawValue:&value]);
3280   XCTAssertEqual(value, 803);
3281   XCTAssertTrue([dict valueForKey:22LL rawValue:NULL]);
3282   XCTAssertTrue([dict valueForKey:22LL rawValue:&value]);
3283   XCTAssertEqual(value, 801);
3284   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
3285   XCTAssertTrue([dict valueForKey:23LL value:&value]);
3286   XCTAssertEqual(value, 702);
3287   XCTAssertTrue([dict valueForKey:24LL rawValue:NULL]);
3288   XCTAssertTrue([dict valueForKey:24LL rawValue:&value]);
3289   XCTAssertEqual(value, 803);
3291   [dict setRawValue:700 forKey:24LL];
3292   XCTAssertEqual(dict.count, 4U);
3293   XCTAssertTrue([dict valueForKey:21LL rawValue:NULL]);
3294   XCTAssertTrue([dict valueForKey:21LL rawValue:&value]);
3295   XCTAssertEqual(value, 803);
3296   XCTAssertTrue([dict valueForKey:22LL rawValue:NULL]);
3297   XCTAssertTrue([dict valueForKey:22LL rawValue:&value]);
3298   XCTAssertEqual(value, 801);
3299   XCTAssertTrue([dict valueForKey:23LL value:NULL]);
3300   XCTAssertTrue([dict valueForKey:23LL value:&value]);
3301   XCTAssertEqual(value, 702);
3302   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
3303   XCTAssertTrue([dict valueForKey:24LL value:&value]);
3304   XCTAssertEqual(value, 700);
3306   const int64_t kKeys2[] = { 22LL, 23LL };
3307   const int32_t kValues2[] = { 702, 801 };  // Unknown
3308   GPBInt64EnumDictionary *dict2 =
3309       [[GPBInt64EnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3310                                                        rawValues:kValues2
3311                                                          forKeys:kKeys2
3312                                                            count:GPBARRAYSIZE(kValues2)];
3313   XCTAssertNotNil(dict2);
3314   [dict addRawEntriesFromDictionary:dict2];
3315   XCTAssertEqual(dict.count, 4U);
3316   XCTAssertTrue([dict valueForKey:21LL rawValue:NULL]);
3317   XCTAssertTrue([dict valueForKey:21LL rawValue:&value]);
3318   XCTAssertEqual(value, 803);
3319   XCTAssertTrue([dict valueForKey:22LL value:NULL]);
3320   XCTAssertTrue([dict valueForKey:22LL value:&value]);
3321   XCTAssertEqual(value, 702);
3322   XCTAssertTrue([dict valueForKey:23LL rawValue:NULL]);
3323   XCTAssertTrue([dict valueForKey:23LL rawValue:&value]);
3324   XCTAssertEqual(value, 801);
3325   XCTAssertTrue([dict valueForKey:24LL value:NULL]);
3326   XCTAssertTrue([dict valueForKey:24LL value:&value]);
3327   XCTAssertEqual(value, 700);
3329   [dict2 release];
3330   [dict release];
3333 - (void)testCopyUnknowns {
3334   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
3335   const int32_t kValues[] = { 700, 801, 702, 803 };
3336   GPBInt64EnumDictionary *dict =
3337       [[GPBInt64EnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3338                                                        rawValues:kValues
3339                                                          forKeys:kKeys
3340                                                            count:GPBARRAYSIZE(kValues)];
3341   XCTAssertNotNil(dict);
3343   GPBInt64EnumDictionary *dict2 = [dict copy];
3344   XCTAssertNotNil(dict2);
3346   // Should be new pointer, but equal objects.
3347   XCTAssertNotEqual(dict, dict2);
3348   XCTAssertEqualObjects(dict, dict2);
3349   XCTAssertEqual(dict.validationFunc, dict2.validationFunc);  // Pointer comparison
3350   XCTAssertTrue([dict2 isKindOfClass:[GPBInt64EnumDictionary class]]);
3352   [dict2 release];
3353   [dict release];
3356 @end
3358 #pragma mark - Int64 -> Object
3360 @interface GPBInt64ObjectDictionaryTests : XCTestCase
3361 @end
3363 @implementation GPBInt64ObjectDictionaryTests
3365 - (void)testEmpty {
3366   GPBInt64ObjectDictionary *dict = [[GPBInt64ObjectDictionary alloc] init];
3367   XCTAssertNotNil(dict);
3368   XCTAssertEqual(dict.count, 0U);
3369   XCTAssertNil([dict valueForKey:21LL]);
3370   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, id aValue, BOOL *stop) {
3371     #pragma unused(aKey, aValue, stop)
3372     XCTFail(@"Shouldn't get here!");
3373   }];
3374   [dict release];
3377 - (void)testOne {
3378   GPBInt64ObjectDictionary *dict = [GPBInt64ObjectDictionary dictionaryWithValue:@"abc" forKey:21LL];
3379   XCTAssertNotNil(dict);
3380   XCTAssertEqual(dict.count, 1U);
3381   XCTAssertEqualObjects([dict valueForKey:21LL], @"abc");
3382   XCTAssertNil([dict valueForKey:22LL]);
3383   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, id aValue, BOOL *stop) {
3384     XCTAssertEqual(aKey, 21LL);
3385     XCTAssertEqualObjects(aValue, @"abc");
3386     XCTAssertNotEqual(stop, NULL);
3387   }];
3390 - (void)testBasics {
3391   const int64_t kKeys[] = { 21LL, 22LL, 23LL };
3392   const id kValues[] = { @"abc", @"def", @"ghi" };
3393   GPBInt64ObjectDictionary *dict =
3394       [[GPBInt64ObjectDictionary alloc] initWithValues:kValues
3395                                                forKeys:kKeys
3396                                                  count:GPBARRAYSIZE(kValues)];
3397   XCTAssertNotNil(dict);
3398   XCTAssertEqual(dict.count, 3U);
3399   XCTAssertEqualObjects([dict valueForKey:21LL], @"abc");
3400   XCTAssertEqualObjects([dict valueForKey:22LL], @"def");
3401   XCTAssertEqualObjects([dict valueForKey:23LL], @"ghi");
3402   XCTAssertNil([dict valueForKey:24LL]);
3404   __block NSUInteger idx = 0;
3405   int64_t *seenKeys = malloc(3 * sizeof(int64_t));
3406   id *seenValues = malloc(3 * sizeof(id));
3407   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, id aValue, BOOL *stop) {
3408     XCTAssertLessThan(idx, 3U);
3409     seenKeys[idx] = aKey;
3410     seenValues[idx] = aValue;
3411     XCTAssertNotEqual(stop, NULL);
3412     ++idx;
3413   }];
3414   for (int i = 0; i < 3; ++i) {
3415     BOOL foundKey = NO;
3416     for (int j = 0; (j < 3) && !foundKey; ++j) {
3417       if (kKeys[i] == seenKeys[j]) {
3418         foundKey = YES;
3419         XCTAssertEqualObjects(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
3420       }
3421     }
3422     XCTAssertTrue(foundKey, @"i = %d", i);
3423   }
3424   free(seenKeys);
3425   free(seenValues);
3427   // Stopping the enumeration.
3428   idx = 0;
3429   [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, id aValue, BOOL *stop) {
3430     #pragma unused(aKey, aValue)
3431     if (idx == 1) *stop = YES;
3432     XCTAssertNotEqual(idx, 2U);
3433     ++idx;
3434   }];
3435   [dict release];
3438 - (void)testEquality {
3439   const int64_t kKeys1[] = { 21LL, 22LL, 23LL, 24LL };
3440   const int64_t kKeys2[] = { 22LL, 21LL, 24LL };
3441   const id kValues1[] = { @"abc", @"def", @"ghi" };
3442   const id kValues2[] = { @"abc", @"jkl", @"ghi" };
3443   const id kValues3[] = { @"abc", @"def", @"ghi", @"jkl" };
3444   GPBInt64ObjectDictionary *dict1 =
3445       [[GPBInt64ObjectDictionary alloc] initWithValues:kValues1
3446                                                forKeys:kKeys1
3447                                                  count:GPBARRAYSIZE(kValues1)];
3448   XCTAssertNotNil(dict1);
3449   GPBInt64ObjectDictionary *dict1prime =
3450       [[GPBInt64ObjectDictionary alloc] initWithValues:kValues1
3451                                                forKeys:kKeys1
3452                                                  count:GPBARRAYSIZE(kValues1)];
3453   XCTAssertNotNil(dict1prime);
3454   GPBInt64ObjectDictionary *dict2 =
3455       [[GPBInt64ObjectDictionary alloc] initWithValues:kValues2
3456                                                forKeys:kKeys1
3457                                                  count:GPBARRAYSIZE(kValues2)];
3458   XCTAssertNotNil(dict2);
3459   GPBInt64ObjectDictionary *dict3 =
3460       [[GPBInt64ObjectDictionary alloc] initWithValues:kValues1
3461                                                forKeys:kKeys2
3462                                                  count:GPBARRAYSIZE(kValues1)];
3463   XCTAssertNotNil(dict3);
3464   GPBInt64ObjectDictionary *dict4 =
3465       [[GPBInt64ObjectDictionary alloc] initWithValues:kValues3
3466                                                forKeys:kKeys1
3467                                                  count:GPBARRAYSIZE(kValues3)];
3468   XCTAssertNotNil(dict4);
3470   // 1/1Prime should be different objects, but equal.
3471   XCTAssertNotEqual(dict1, dict1prime);
3472   XCTAssertEqualObjects(dict1, dict1prime);
3473   // Equal, so they must have same hash.
3474   XCTAssertEqual([dict1 hash], [dict1prime hash]);
3476   // 2 is save keys, different values; not equal.
3477   XCTAssertNotEqualObjects(dict1, dict2);
3479   // 3 is different keys, samae values; not equal.
3480   XCTAssertNotEqualObjects(dict1, dict3);
3482   // 4 extra pair; not equal
3483   XCTAssertNotEqualObjects(dict1, dict4);
3485   [dict1 release];
3486   [dict1prime release];
3487   [dict2 release];
3488   [dict3 release];
3489   [dict4 release];
3492 - (void)testCopy {
3493   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
3494   const id kValues[] = { @"abc", @"def", @"ghi", @"jkl" };
3495   GPBInt64ObjectDictionary *dict =
3496       [[GPBInt64ObjectDictionary alloc] initWithValues:kValues
3497                                                forKeys:kKeys
3498                                                  count:GPBARRAYSIZE(kValues)];
3499   XCTAssertNotNil(dict);
3501   GPBInt64ObjectDictionary *dict2 = [dict copy];
3502   XCTAssertNotNil(dict2);
3504   // Should be new object but equal.
3505   XCTAssertNotEqual(dict, dict2);
3506   XCTAssertEqualObjects(dict, dict2);
3507   XCTAssertTrue([dict2 isKindOfClass:[GPBInt64ObjectDictionary class]]);
3509   [dict2 release];
3510   [dict release];
3513 - (void)testDictionaryFromDictionary {
3514   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
3515   const id kValues[] = { @"abc", @"def", @"ghi", @"jkl" };
3516   GPBInt64ObjectDictionary *dict =
3517       [[GPBInt64ObjectDictionary alloc] initWithValues:kValues
3518                                                forKeys:kKeys
3519                                                  count:GPBARRAYSIZE(kValues)];
3520   XCTAssertNotNil(dict);
3522   GPBInt64ObjectDictionary *dict2 =
3523       [GPBInt64ObjectDictionary dictionaryWithDictionary:dict];
3524   XCTAssertNotNil(dict2);
3526   // Should be new pointer, but equal objects.
3527   XCTAssertNotEqual(dict, dict2);
3528   XCTAssertEqualObjects(dict, dict2);
3529   [dict release];
3532 - (void)testAdds {
3533   GPBInt64ObjectDictionary *dict = [GPBInt64ObjectDictionary dictionary];
3534   XCTAssertNotNil(dict);
3536   XCTAssertEqual(dict.count, 0U);
3537   [dict setValue:@"abc" forKey:21LL];
3538   XCTAssertEqual(dict.count, 1U);
3540   const int64_t kKeys[] = { 22LL, 23LL, 24LL };
3541   const id kValues[] = { @"def", @"ghi", @"jkl" };
3542   GPBInt64ObjectDictionary *dict2 =
3543       [[GPBInt64ObjectDictionary alloc] initWithValues:kValues
3544                                                forKeys:kKeys
3545                                                  count:GPBARRAYSIZE(kValues)];
3546   XCTAssertNotNil(dict2);
3547   [dict addEntriesFromDictionary:dict2];
3548   XCTAssertEqual(dict.count, 4U);
3550   XCTAssertEqualObjects([dict valueForKey:21LL], @"abc");
3551   XCTAssertEqualObjects([dict valueForKey:22LL], @"def");
3552   XCTAssertEqualObjects([dict valueForKey:23LL], @"ghi");
3553   XCTAssertEqualObjects([dict valueForKey:24LL], @"jkl");
3554   [dict2 release];
3557 - (void)testRemove {
3558   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
3559   const id kValues[] = { @"abc", @"def", @"ghi", @"jkl" };
3560   GPBInt64ObjectDictionary *dict =
3561       [[GPBInt64ObjectDictionary alloc] initWithValues:kValues
3562                                         forKeys:kKeys
3563                                           count:GPBARRAYSIZE(kValues)];
3564   XCTAssertNotNil(dict);
3565   XCTAssertEqual(dict.count, 4U);
3567   [dict removeValueForKey:22LL];
3568   XCTAssertEqual(dict.count, 3U);
3569   XCTAssertEqualObjects([dict valueForKey:21LL], @"abc");
3570   XCTAssertNil([dict valueForKey:22LL]);
3571   XCTAssertEqualObjects([dict valueForKey:23LL], @"ghi");
3572   XCTAssertEqualObjects([dict valueForKey:24LL], @"jkl");
3574   // Remove again does nothing.
3575   [dict removeValueForKey:22LL];
3576   XCTAssertEqual(dict.count, 3U);
3577   XCTAssertEqualObjects([dict valueForKey:21LL], @"abc");
3578   XCTAssertNil([dict valueForKey:22LL]);
3579   XCTAssertEqualObjects([dict valueForKey:23LL], @"ghi");
3580   XCTAssertEqualObjects([dict valueForKey:24LL], @"jkl");
3582   [dict removeValueForKey:24LL];
3583   XCTAssertEqual(dict.count, 2U);
3584   XCTAssertEqualObjects([dict valueForKey:21LL], @"abc");
3585   XCTAssertNil([dict valueForKey:22LL]);
3586   XCTAssertEqualObjects([dict valueForKey:23LL], @"ghi");
3587   XCTAssertNil([dict valueForKey:24LL]);
3589   [dict removeAll];
3590   XCTAssertEqual(dict.count, 0U);
3591   XCTAssertNil([dict valueForKey:21LL]);
3592   XCTAssertNil([dict valueForKey:22LL]);
3593   XCTAssertNil([dict valueForKey:23LL]);
3594   XCTAssertNil([dict valueForKey:24LL]);
3595   [dict release];
3598 - (void)testInplaceMutation {
3599   const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
3600   const id kValues[] = { @"abc", @"def", @"ghi", @"jkl" };
3601   GPBInt64ObjectDictionary *dict =
3602       [[GPBInt64ObjectDictionary alloc] initWithValues:kValues
3603                                         forKeys:kKeys
3604                                           count:GPBARRAYSIZE(kValues)];
3605   XCTAssertNotNil(dict);
3606   XCTAssertEqual(dict.count, 4U);
3607   XCTAssertEqualObjects([dict valueForKey:21LL], @"abc");
3608   XCTAssertEqualObjects([dict valueForKey:22LL], @"def");
3609   XCTAssertEqualObjects([dict valueForKey:23LL], @"ghi");
3610   XCTAssertEqualObjects([dict valueForKey:24LL], @"jkl");
3612   [dict setValue:@"jkl" forKey:21LL];
3613   XCTAssertEqual(dict.count, 4U);
3614   XCTAssertEqualObjects([dict valueForKey:21LL], @"jkl");
3615   XCTAssertEqualObjects([dict valueForKey:22LL], @"def");
3616   XCTAssertEqualObjects([dict valueForKey:23LL], @"ghi");
3617   XCTAssertEqualObjects([dict valueForKey:24LL], @"jkl");
3619   [dict setValue:@"def" forKey:24LL];
3620   XCTAssertEqual(dict.count, 4U);
3621   XCTAssertEqualObjects([dict valueForKey:21LL], @"jkl");
3622   XCTAssertEqualObjects([dict valueForKey:22LL], @"def");
3623   XCTAssertEqualObjects([dict valueForKey:23LL], @"ghi");
3624   XCTAssertEqualObjects([dict valueForKey:24LL], @"def");
3626   const int64_t kKeys2[] = { 22LL, 23LL };
3627   const id kValues2[] = { @"ghi", @"abc" };
3628   GPBInt64ObjectDictionary *dict2 =
3629       [[GPBInt64ObjectDictionary alloc] initWithValues:kValues2
3630                                                forKeys:kKeys2
3631                                                  count:GPBARRAYSIZE(kValues2)];
3632   XCTAssertNotNil(dict2);
3633   [dict addEntriesFromDictionary:dict2];
3634   XCTAssertEqual(dict.count, 4U);
3635   XCTAssertEqualObjects([dict valueForKey:21LL], @"jkl");
3636   XCTAssertEqualObjects([dict valueForKey:22LL], @"ghi");
3637   XCTAssertEqualObjects([dict valueForKey:23LL], @"abc");
3638   XCTAssertEqualObjects([dict valueForKey:24LL], @"def");
3640   [dict2 release];
3641   [dict release];
3644 @end
3646 //%PDDM-EXPAND-END TEST_FOR_POD_KEY(Int64, int64_t, 21LL, 22LL, 23LL, 24LL)