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.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31#import <Foundation/Foundation.h>
32#import <XCTest/XCTest.h>
33
34#import "GPBDictionary.h"
35
36#import "GPBTestUtilities.h"
37#import "google/protobuf/UnittestRuntimeProto2.pbobjc.h"
38
39// Pull in the macros (using an external file because expanding all tests
40// in a single file makes a file that is failing to work with within Xcode.
41//%PDDM-IMPORT-DEFINES GPBDictionaryTests.pddm
42
43//%PDDM-EXPAND TEST_FOR_POD_KEY(Int64, int64_t, 21LL, 22LL, 23LL, 24LL)
44// This block of code is generated, do not edit it directly.
45
46// To let the testing macros work, add some extra methods to simplify things.
47@interface 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
53
54static BOOL TestingEnum_IsValidValue(int32_t value) {
55  switch (value) {
56    case 700:
57    case 701:
58    case 702:
59    case 703:
60      return YES;
61    default:
62      return NO;
63  }
64}
65
66@implementation 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];
74}
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];
82}
83@end
84
85
86#pragma mark - Int64 -> UInt32
87
88@interface GPBInt64UInt32DictionaryTests : XCTestCase
89@end
90
91@implementation GPBInt64UInt32DictionaryTests
92
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];
103}
104
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  }];
119}
120
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]);
141
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);
164
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];
174}
175
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);
207
208  // 1/1Prime should be different objects, but equal.
209  XCTAssertNotEqual(dict1, dict1prime);
210  XCTAssertEqualObjects(dict1, dict1prime);
211  // Equal, so they must have same hash.
212  XCTAssertEqual([dict1 hash], [dict1prime hash]);
213
214  // 2 is same keys, different values; not equal.
215  XCTAssertNotEqualObjects(dict1, dict2);
216
217  // 3 is different keys, same values; not equal.
218  XCTAssertNotEqualObjects(dict1, dict3);
219
220  // 4 extra pair; not equal
221  XCTAssertNotEqualObjects(dict1, dict4);
222
223  [dict1 release];
224  [dict1prime release];
225  [dict2 release];
226  [dict3 release];
227  [dict4 release];
228}
229
230- (void)testCopy {
231  const 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);
238
239  GPBInt64UInt32Dictionary *dict2 = [dict copy];
240  XCTAssertNotNil(dict2);
241
242  // Should be new object but equal.
243  XCTAssertNotEqual(dict, dict2);
244  XCTAssertEqualObjects(dict, dict2);
245  XCTAssertTrue([dict2 isKindOfClass:[GPBInt64UInt32Dictionary class]]);
246
247  [dict2 release];
248  [dict release];
249}
250
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);
259
260  GPBInt64UInt32Dictionary *dict2 =
261      [GPBInt64UInt32Dictionary dictionaryWithDictionary:dict];
262  XCTAssertNotNil(dict2);
263
264  // Should be new pointer, but equal objects.
265  XCTAssertNotEqual(dict, dict2);
266  XCTAssertEqualObjects(dict, dict2);
267  [dict release];
268}
269
270- (void)testAdds {
271  GPBInt64UInt32Dictionary *dict = [GPBInt64UInt32Dictionary dictionary];
272  XCTAssertNotNil(dict);
273
274  XCTAssertEqual(dict.count, 0U);
275  [dict setValue:100U forKey:21LL];
276  XCTAssertEqual(dict.count, 1U);
277
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);
287
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];
302}
303
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);
313
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);
327
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);
341
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]);
352
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];
360}
361
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);
384
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);
399
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);
414
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);
436
437  [dict2 release];
438  [dict release];
439}
440
441@end
442
443#pragma mark - Int64 -> Int32
444
445@interface GPBInt64Int32DictionaryTests : XCTestCase
446@end
447
448@implementation GPBInt64Int32DictionaryTests
449
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];
460}
461
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  }];
476}
477
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]);
498
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);
521
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];
531}
532
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);
564
565  // 1/1Prime should be different objects, but equal.
566  XCTAssertNotEqual(dict1, dict1prime);
567  XCTAssertEqualObjects(dict1, dict1prime);
568  // Equal, so they must have same hash.
569  XCTAssertEqual([dict1 hash], [dict1prime hash]);
570
571  // 2 is same keys, different values; not equal.
572  XCTAssertNotEqualObjects(dict1, dict2);
573
574  // 3 is different keys, same values; not equal.
575  XCTAssertNotEqualObjects(dict1, dict3);
576
577  // 4 extra pair; not equal
578  XCTAssertNotEqualObjects(dict1, dict4);
579
580  [dict1 release];
581  [dict1prime release];
582  [dict2 release];
583  [dict3 release];
584  [dict4 release];
585}
586
587- (void)testCopy {
588  const 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);
595
596  GPBInt64Int32Dictionary *dict2 = [dict copy];
597  XCTAssertNotNil(dict2);
598
599  // Should be new object but equal.
600  XCTAssertNotEqual(dict, dict2);
601  XCTAssertEqualObjects(dict, dict2);
602  XCTAssertTrue([dict2 isKindOfClass:[GPBInt64Int32Dictionary class]]);
603
604  [dict2 release];
605  [dict release];
606}
607
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);
616
617  GPBInt64Int32Dictionary *dict2 =
618      [GPBInt64Int32Dictionary dictionaryWithDictionary:dict];
619  XCTAssertNotNil(dict2);
620
621  // Should be new pointer, but equal objects.
622  XCTAssertNotEqual(dict, dict2);
623  XCTAssertEqualObjects(dict, dict2);
624  [dict release];
625}
626
627- (void)testAdds {
628  GPBInt64Int32Dictionary *dict = [GPBInt64Int32Dictionary dictionary];
629  XCTAssertNotNil(dict);
630
631  XCTAssertEqual(dict.count, 0U);
632  [dict setValue:200 forKey:21LL];
633  XCTAssertEqual(dict.count, 1U);
634
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);
644
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];
659}
660
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);
670
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);
684
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);
698
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]);
709
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];
717}
718
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);
741
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);
756
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);
771
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);
793
794  [dict2 release];
795  [dict release];
796}
797
798@end
799
800#pragma mark - Int64 -> UInt64
801
802@interface GPBInt64UInt64DictionaryTests : XCTestCase
803@end
804
805@implementation GPBInt64UInt64DictionaryTests
806
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];
817}
818
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  }];
833}
834
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]);
855
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);
878
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];
888}
889
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);
921
922  // 1/1Prime should be different objects, but equal.
923  XCTAssertNotEqual(dict1, dict1prime);
924  XCTAssertEqualObjects(dict1, dict1prime);
925  // Equal, so they must have same hash.
926  XCTAssertEqual([dict1 hash], [dict1prime hash]);
927
928  // 2 is same keys, different values; not equal.
929  XCTAssertNotEqualObjects(dict1, dict2);
930
931  // 3 is different keys, same values; not equal.
932  XCTAssertNotEqualObjects(dict1, dict3);
933
934  // 4 extra pair; not equal
935  XCTAssertNotEqualObjects(dict1, dict4);
936
937  [dict1 release];
938  [dict1prime release];
939  [dict2 release];
940  [dict3 release];
941  [dict4 release];
942}
943
944- (void)testCopy {
945  const 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);
952
953  GPBInt64UInt64Dictionary *dict2 = [dict copy];
954  XCTAssertNotNil(dict2);
955
956  // Should be new object but equal.
957  XCTAssertNotEqual(dict, dict2);
958  XCTAssertEqualObjects(dict, dict2);
959  XCTAssertTrue([dict2 isKindOfClass:[GPBInt64UInt64Dictionary class]]);
960
961  [dict2 release];
962  [dict release];
963}
964
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);
973
974  GPBInt64UInt64Dictionary *dict2 =
975      [GPBInt64UInt64Dictionary dictionaryWithDictionary:dict];
976  XCTAssertNotNil(dict2);
977
978  // Should be new pointer, but equal objects.
979  XCTAssertNotEqual(dict, dict2);
980  XCTAssertEqualObjects(dict, dict2);
981  [dict release];
982}
983
984- (void)testAdds {
985  GPBInt64UInt64Dictionary *dict = [GPBInt64UInt64Dictionary dictionary];
986  XCTAssertNotNil(dict);
987
988  XCTAssertEqual(dict.count, 0U);
989  [dict setValue:300U forKey:21LL];
990  XCTAssertEqual(dict.count, 1U);
991
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);
1001
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];
1016}
1017
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);
1027
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);
1041
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);
1055
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]);
1066
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];
1074}
1075
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);
1098
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);
1113
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);
1128
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);
1150
1151  [dict2 release];
1152  [dict release];
1153}
1154
1155@end
1156
1157#pragma mark - Int64 -> Int64
1158
1159@interface GPBInt64Int64DictionaryTests : XCTestCase
1160@end
1161
1162@implementation GPBInt64Int64DictionaryTests
1163
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];
1174}
1175
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  }];
1190}
1191
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]);
1212
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);
1235
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];
1245}
1246
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);
1278
1279  // 1/1Prime should be different objects, but equal.
1280  XCTAssertNotEqual(dict1, dict1prime);
1281  XCTAssertEqualObjects(dict1, dict1prime);
1282  // Equal, so they must have same hash.
1283  XCTAssertEqual([dict1 hash], [dict1prime hash]);
1284
1285  // 2 is same keys, different values; not equal.
1286  XCTAssertNotEqualObjects(dict1, dict2);
1287
1288  // 3 is different keys, same values; not equal.
1289  XCTAssertNotEqualObjects(dict1, dict3);
1290
1291  // 4 extra pair; not equal
1292  XCTAssertNotEqualObjects(dict1, dict4);
1293
1294  [dict1 release];
1295  [dict1prime release];
1296  [dict2 release];
1297  [dict3 release];
1298  [dict4 release];
1299}
1300
1301- (void)testCopy {
1302  const 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);
1309
1310  GPBInt64Int64Dictionary *dict2 = [dict copy];
1311  XCTAssertNotNil(dict2);
1312
1313  // Should be new object but equal.
1314  XCTAssertNotEqual(dict, dict2);
1315  XCTAssertEqualObjects(dict, dict2);
1316  XCTAssertTrue([dict2 isKindOfClass:[GPBInt64Int64Dictionary class]]);
1317
1318  [dict2 release];
1319  [dict release];
1320}
1321
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);
1330
1331  GPBInt64Int64Dictionary *dict2 =
1332      [GPBInt64Int64Dictionary dictionaryWithDictionary:dict];
1333  XCTAssertNotNil(dict2);
1334
1335  // Should be new pointer, but equal objects.
1336  XCTAssertNotEqual(dict, dict2);
1337  XCTAssertEqualObjects(dict, dict2);
1338  [dict release];
1339}
1340
1341- (void)testAdds {
1342  GPBInt64Int64Dictionary *dict = [GPBInt64Int64Dictionary dictionary];
1343  XCTAssertNotNil(dict);
1344
1345  XCTAssertEqual(dict.count, 0U);
1346  [dict setValue:400 forKey:21LL];
1347  XCTAssertEqual(dict.count, 1U);
1348
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);
1358
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];
1373}
1374
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);
1384
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);
1398
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);
1412
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]);
1423
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];
1431}
1432
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);
1455
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);
1470
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);
1485
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);
1507
1508  [dict2 release];
1509  [dict release];
1510}
1511
1512@end
1513
1514#pragma mark - Int64 -> Bool
1515
1516@interface GPBInt64BoolDictionaryTests : XCTestCase
1517@end
1518
1519@implementation GPBInt64BoolDictionaryTests
1520
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];
1531}
1532
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  }];
1547}
1548
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]);
1569
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);
1592
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];
1602}
1603
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);
1635
1636  // 1/1Prime should be different objects, but equal.
1637  XCTAssertNotEqual(dict1, dict1prime);
1638  XCTAssertEqualObjects(dict1, dict1prime);
1639  // Equal, so they must have same hash.
1640  XCTAssertEqual([dict1 hash], [dict1prime hash]);
1641
1642  // 2 is same keys, different values; not equal.
1643  XCTAssertNotEqualObjects(dict1, dict2);
1644
1645  // 3 is different keys, same values; not equal.
1646  XCTAssertNotEqualObjects(dict1, dict3);
1647
1648  // 4 extra pair; not equal
1649  XCTAssertNotEqualObjects(dict1, dict4);
1650
1651  [dict1 release];
1652  [dict1prime release];
1653  [dict2 release];
1654  [dict3 release];
1655  [dict4 release];
1656}
1657
1658- (void)testCopy {
1659  const 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);
1666
1667  GPBInt64BoolDictionary *dict2 = [dict copy];
1668  XCTAssertNotNil(dict2);
1669
1670  // Should be new object but equal.
1671  XCTAssertNotEqual(dict, dict2);
1672  XCTAssertEqualObjects(dict, dict2);
1673  XCTAssertTrue([dict2 isKindOfClass:[GPBInt64BoolDictionary class]]);
1674
1675  [dict2 release];
1676  [dict release];
1677}
1678
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);
1687
1688  GPBInt64BoolDictionary *dict2 =
1689      [GPBInt64BoolDictionary dictionaryWithDictionary:dict];
1690  XCTAssertNotNil(dict2);
1691
1692  // Should be new pointer, but equal objects.
1693  XCTAssertNotEqual(dict, dict2);
1694  XCTAssertEqualObjects(dict, dict2);
1695  [dict release];
1696}
1697
1698- (void)testAdds {
1699  GPBInt64BoolDictionary *dict = [GPBInt64BoolDictionary dictionary];
1700  XCTAssertNotNil(dict);
1701
1702  XCTAssertEqual(dict.count, 0U);
1703  [dict setValue:YES forKey:21LL];
1704  XCTAssertEqual(dict.count, 1U);
1705
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);
1715
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];
1730}
1731
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);
1741
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);
1755
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);
1769
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]);
1780
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];
1788}
1789
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);
1812
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);
1827
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);
1842
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);
1864
1865  [dict2 release];
1866  [dict release];
1867}
1868
1869@end
1870
1871#pragma mark - Int64 -> Float
1872
1873@interface GPBInt64FloatDictionaryTests : XCTestCase
1874@end
1875
1876@implementation GPBInt64FloatDictionaryTests
1877
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];
1888}
1889
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  }];
1904}
1905
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]);
1926
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);
1949
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];
1959}
1960
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);
1992
1993  // 1/1Prime should be different objects, but equal.
1994  XCTAssertNotEqual(dict1, dict1prime);
1995  XCTAssertEqualObjects(dict1, dict1prime);
1996  // Equal, so they must have same hash.
1997  XCTAssertEqual([dict1 hash], [dict1prime hash]);
1998
1999  // 2 is same keys, different values; not equal.
2000  XCTAssertNotEqualObjects(dict1, dict2);
2001
2002  // 3 is different keys, same values; not equal.
2003  XCTAssertNotEqualObjects(dict1, dict3);
2004
2005  // 4 extra pair; not equal
2006  XCTAssertNotEqualObjects(dict1, dict4);
2007
2008  [dict1 release];
2009  [dict1prime release];
2010  [dict2 release];
2011  [dict3 release];
2012  [dict4 release];
2013}
2014
2015- (void)testCopy {
2016  const 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);
2023
2024  GPBInt64FloatDictionary *dict2 = [dict copy];
2025  XCTAssertNotNil(dict2);
2026
2027  // Should be new object but equal.
2028  XCTAssertNotEqual(dict, dict2);
2029  XCTAssertEqualObjects(dict, dict2);
2030  XCTAssertTrue([dict2 isKindOfClass:[GPBInt64FloatDictionary class]]);
2031
2032  [dict2 release];
2033  [dict release];
2034}
2035
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);
2044
2045  GPBInt64FloatDictionary *dict2 =
2046      [GPBInt64FloatDictionary dictionaryWithDictionary:dict];
2047  XCTAssertNotNil(dict2);
2048
2049  // Should be new pointer, but equal objects.
2050  XCTAssertNotEqual(dict, dict2);
2051  XCTAssertEqualObjects(dict, dict2);
2052  [dict release];
2053}
2054
2055- (void)testAdds {
2056  GPBInt64FloatDictionary *dict = [GPBInt64FloatDictionary dictionary];
2057  XCTAssertNotNil(dict);
2058
2059  XCTAssertEqual(dict.count, 0U);
2060  [dict setValue:500.f forKey:21LL];
2061  XCTAssertEqual(dict.count, 1U);
2062
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);
2072
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];
2087}
2088
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);
2098
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);
2112
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);
2126
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]);
2137
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];
2145}
2146
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);
2169
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);
2184
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);
2199
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);
2221
2222  [dict2 release];
2223  [dict release];
2224}
2225
2226@end
2227
2228#pragma mark - Int64 -> Double
2229
2230@interface GPBInt64DoubleDictionaryTests : XCTestCase
2231@end
2232
2233@implementation GPBInt64DoubleDictionaryTests
2234
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];
2245}
2246
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  }];
2261}
2262
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]);
2283
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);
2306
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];
2316}
2317
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);
2349
2350  // 1/1Prime should be different objects, but equal.
2351  XCTAssertNotEqual(dict1, dict1prime);
2352  XCTAssertEqualObjects(dict1, dict1prime);
2353  // Equal, so they must have same hash.
2354  XCTAssertEqual([dict1 hash], [dict1prime hash]);
2355
2356  // 2 is same keys, different values; not equal.
2357  XCTAssertNotEqualObjects(dict1, dict2);
2358
2359  // 3 is different keys, same values; not equal.
2360  XCTAssertNotEqualObjects(dict1, dict3);
2361
2362  // 4 extra pair; not equal
2363  XCTAssertNotEqualObjects(dict1, dict4);
2364
2365  [dict1 release];
2366  [dict1prime release];
2367  [dict2 release];
2368  [dict3 release];
2369  [dict4 release];
2370}
2371
2372- (void)testCopy {
2373  const 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);
2380
2381  GPBInt64DoubleDictionary *dict2 = [dict copy];
2382  XCTAssertNotNil(dict2);
2383
2384  // Should be new object but equal.
2385  XCTAssertNotEqual(dict, dict2);
2386  XCTAssertEqualObjects(dict, dict2);
2387  XCTAssertTrue([dict2 isKindOfClass:[GPBInt64DoubleDictionary class]]);
2388
2389  [dict2 release];
2390  [dict release];
2391}
2392
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);
2401
2402  GPBInt64DoubleDictionary *dict2 =
2403      [GPBInt64DoubleDictionary dictionaryWithDictionary:dict];
2404  XCTAssertNotNil(dict2);
2405
2406  // Should be new pointer, but equal objects.
2407  XCTAssertNotEqual(dict, dict2);
2408  XCTAssertEqualObjects(dict, dict2);
2409  [dict release];
2410}
2411
2412- (void)testAdds {
2413  GPBInt64DoubleDictionary *dict = [GPBInt64DoubleDictionary dictionary];
2414  XCTAssertNotNil(dict);
2415
2416  XCTAssertEqual(dict.count, 0U);
2417  [dict setValue:600. forKey:21LL];
2418  XCTAssertEqual(dict.count, 1U);
2419
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);
2429
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];
2444}
2445
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);
2455
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.);
2469
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.);
2483
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]);
2494
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];
2502}
2503
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.);
2526
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.);
2541
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.);
2556
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.);
2578
2579  [dict2 release];
2580  [dict release];
2581}
2582
2583@end
2584
2585#pragma mark - Int64 -> Enum
2586
2587@interface GPBInt64EnumDictionaryTests : XCTestCase
2588@end
2589
2590@implementation GPBInt64EnumDictionaryTests
2591
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];
2602}
2603
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  }];
2618}
2619
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]);
2640
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);
2663
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];
2673}
2674
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);
2706
2707  // 1/1Prime should be different objects, but equal.
2708  XCTAssertNotEqual(dict1, dict1prime);
2709  XCTAssertEqualObjects(dict1, dict1prime);
2710  // Equal, so they must have same hash.
2711  XCTAssertEqual([dict1 hash], [dict1prime hash]);
2712
2713  // 2 is same keys, different values; not equal.
2714  XCTAssertNotEqualObjects(dict1, dict2);
2715
2716  // 3 is different keys, same values; not equal.
2717  XCTAssertNotEqualObjects(dict1, dict3);
2718
2719  // 4 extra pair; not equal
2720  XCTAssertNotEqualObjects(dict1, dict4);
2721
2722  [dict1 release];
2723  [dict1prime release];
2724  [dict2 release];
2725  [dict3 release];
2726  [dict4 release];
2727}
2728
2729- (void)testCopy {
2730  const 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);
2737
2738  GPBInt64EnumDictionary *dict2 = [dict copy];
2739  XCTAssertNotNil(dict2);
2740
2741  // Should be new object but equal.
2742  XCTAssertNotEqual(dict, dict2);
2743  XCTAssertEqualObjects(dict, dict2);
2744  XCTAssertTrue([dict2 isKindOfClass:[GPBInt64EnumDictionary class]]);
2745
2746  [dict2 release];
2747  [dict release];
2748}
2749
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);
2758
2759  GPBInt64EnumDictionary *dict2 =
2760      [GPBInt64EnumDictionary dictionaryWithDictionary:dict];
2761  XCTAssertNotNil(dict2);
2762
2763  // Should be new pointer, but equal objects.
2764  XCTAssertNotEqual(dict, dict2);
2765  XCTAssertEqualObjects(dict, dict2);
2766  [dict release];
2767}
2768
2769- (void)testAdds {
2770  GPBInt64EnumDictionary *dict = [GPBInt64EnumDictionary dictionary];
2771  XCTAssertNotNil(dict);
2772
2773  XCTAssertEqual(dict.count, 0U);
2774  [dict setValue:700 forKey:21LL];
2775  XCTAssertEqual(dict.count, 1U);
2776
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);
2786
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];
2801}
2802
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);
2812
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);
2826
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);
2840
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]);
2851
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];
2859}
2860
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);
2883
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);
2898
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);
2913
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);
2935
2936  [dict2 release];
2937  [dict release];
2938}
2939
2940@end
2941
2942#pragma mark - Int64 -> Enum (Unknown Enums)
2943
2944@interface GPBInt64EnumDictionaryUnknownEnumTests : XCTestCase
2945@end
2946
2947@implementation GPBInt64EnumDictionaryUnknownEnumTests
2948
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]);
2974
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);
3019
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];
3029}
3030
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);
3067
3068  // 1/1Prime should be different objects, but equal.
3069  XCTAssertNotEqual(dict1, dict1prime);
3070  XCTAssertEqualObjects(dict1, dict1prime);
3071  // Equal, so they must have same hash.
3072  XCTAssertEqual([dict1 hash], [dict1prime hash]);
3073
3074  // 2 is same keys, different values; not equal.
3075  XCTAssertNotEqualObjects(dict1, dict2);
3076
3077  // 3 is different keys, same values; not equal.
3078  XCTAssertNotEqualObjects(dict1, dict3);
3079
3080  // 4 extra pair; not equal
3081  XCTAssertNotEqualObjects(dict1, dict4);
3082
3083  [dict1 release];
3084  [dict1prime release];
3085  [dict2 release];
3086  [dict3 release];
3087  [dict4 release];
3088}
3089
3090- (void)testCopyWithUnknowns {
3091  const 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);
3099
3100  GPBInt64EnumDictionary *dict2 = [dict copy];
3101  XCTAssertNotNil(dict2);
3102
3103  // Should be new pointer, but equal objects.
3104  XCTAssertNotEqual(dict, dict2);
3105  XCTAssertEqual(dict.validationFunc, dict2.validationFunc);  // Pointer comparison
3106  XCTAssertEqualObjects(dict, dict2);
3107
3108  [dict2 release];
3109  [dict release];
3110}
3111
3112- (void)testDictionaryFromDictionary {
3113  const 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);
3121
3122  GPBInt64EnumDictionary *dict2 =
3123      [GPBInt64EnumDictionary dictionaryWithDictionary:dict];
3124  XCTAssertNotNil(dict2);
3125
3126  // Should be new pointer, but equal objects.
3127  XCTAssertNotEqual(dict, dict2);
3128  XCTAssertEqualObjects(dict, dict2);
3129  XCTAssertEqual(dict.validationFunc, dict2.validationFunc);  // Pointer comparison
3130  [dict release];
3131}
3132
3133- (void)testUnknownAdds {
3134  GPBInt64EnumDictionary *dict =
3135    [GPBInt64EnumDictionary dictionaryWithValidationFunction:TestingEnum_IsValidValue];
3136  XCTAssertNotNil(dict);
3137
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);
3144
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);
3154
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];
3175}
3176
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);
3187
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);
3201
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);
3215
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]);
3226
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];
3234}
3235
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);
3259
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);
3275
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);
3290
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);
3305
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);
3328
3329  [dict2 release];
3330  [dict release];
3331}
3332
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);
3342
3343  GPBInt64EnumDictionary *dict2 = [dict copy];
3344  XCTAssertNotNil(dict2);
3345
3346  // Should be new pointer, but equal objects.
3347  XCTAssertNotEqual(dict, dict2);
3348  XCTAssertEqualObjects(dict, dict2);
3349  XCTAssertEqual(dict.validationFunc, dict2.validationFunc);  // Pointer comparison
3350  XCTAssertTrue([dict2 isKindOfClass:[GPBInt64EnumDictionary class]]);
3351
3352  [dict2 release];
3353  [dict release];
3354}
3355
3356@end
3357
3358#pragma mark - Int64 -> Object
3359
3360@interface GPBInt64ObjectDictionaryTests : XCTestCase
3361@end
3362
3363@implementation GPBInt64ObjectDictionaryTests
3364
3365- (void)testEmpty {
3366  GPBInt64ObjectDictionary<NSString*> *dict = [[GPBInt64ObjectDictionary alloc] init];
3367  XCTAssertNotNil(dict);
3368  XCTAssertEqual(dict.count, 0U);
3369  XCTAssertNil([dict objectForKey:21LL]);
3370  [dict enumerateKeysAndObjectsUsingBlock:^(int64_t aKey, NSString* aObject, BOOL *stop) {
3371    #pragma unused(aKey, aObject, stop)
3372    XCTFail(@"Shouldn't get here!");
3373  }];
3374  [dict release];
3375}
3376
3377- (void)testOne {
3378  GPBInt64ObjectDictionary<NSString*> *dict = [GPBInt64ObjectDictionary dictionaryWithObject:@"abc" forKey:21LL];
3379  XCTAssertNotNil(dict);
3380  XCTAssertEqual(dict.count, 1U);
3381  XCTAssertEqualObjects([dict objectForKey:21LL], @"abc");
3382  XCTAssertNil([dict objectForKey:22LL]);
3383  [dict enumerateKeysAndObjectsUsingBlock:^(int64_t aKey, NSString* aObject, BOOL *stop) {
3384    XCTAssertEqual(aKey, 21LL);
3385    XCTAssertEqualObjects(aObject, @"abc");
3386    XCTAssertNotEqual(stop, NULL);
3387  }];
3388}
3389
3390- (void)testBasics {
3391  const int64_t kKeys[] = { 21LL, 22LL, 23LL };
3392  const NSString* kObjects[] = { @"abc", @"def", @"ghi" };
3393  GPBInt64ObjectDictionary<NSString*> *dict =
3394      [[GPBInt64ObjectDictionary alloc] initWithObjects:kObjects
3395                                                forKeys:kKeys
3396                                                  count:GPBARRAYSIZE(kObjects)];
3397  XCTAssertNotNil(dict);
3398  XCTAssertEqual(dict.count, 3U);
3399  XCTAssertEqualObjects([dict objectForKey:21LL], @"abc");
3400  XCTAssertEqualObjects([dict objectForKey:22LL], @"def");
3401  XCTAssertEqualObjects([dict objectForKey:23LL], @"ghi");
3402  XCTAssertNil([dict objectForKey:24LL]);
3403
3404  __block NSUInteger idx = 0;
3405  int64_t *seenKeys = malloc(3 * sizeof(int64_t));
3406  NSString* *seenObjects = malloc(3 * sizeof(NSString*));
3407  [dict enumerateKeysAndObjectsUsingBlock:^(int64_t aKey, NSString* aObject, BOOL *stop) {
3408    XCTAssertLessThan(idx, 3U);
3409    seenKeys[idx] = aKey;
3410    seenObjects[idx] = aObject;
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(kObjects[i], seenObjects[j], @"i = %d, j = %d", i, j);
3420      }
3421    }
3422    XCTAssertTrue(foundKey, @"i = %d", i);
3423  }
3424  free(seenKeys);
3425  free(seenObjects);
3426
3427  // Stopping the enumeration.
3428  idx = 0;
3429  [dict enumerateKeysAndObjectsUsingBlock:^(int64_t aKey, NSString* aObject, BOOL *stop) {
3430    #pragma unused(aKey, aObject)
3431    if (idx == 1) *stop = YES;
3432    XCTAssertNotEqual(idx, 2U);
3433    ++idx;
3434  }];
3435  [dict release];
3436}
3437
3438- (void)testEquality {
3439  const int64_t kKeys1[] = { 21LL, 22LL, 23LL, 24LL };
3440  const int64_t kKeys2[] = { 22LL, 21LL, 24LL };
3441  const NSString* kObjects1[] = { @"abc", @"def", @"ghi" };
3442  const NSString* kObjects2[] = { @"abc", @"jkl", @"ghi" };
3443  const NSString* kObjects3[] = { @"abc", @"def", @"ghi", @"jkl" };
3444  GPBInt64ObjectDictionary<NSString*> *dict1 =
3445      [[GPBInt64ObjectDictionary alloc] initWithObjects:kObjects1
3446                                                forKeys:kKeys1
3447                                                  count:GPBARRAYSIZE(kObjects1)];
3448  XCTAssertNotNil(dict1);
3449  GPBInt64ObjectDictionary<NSString*> *dict1prime =
3450      [[GPBInt64ObjectDictionary alloc] initWithObjects:kObjects1
3451                                                forKeys:kKeys1
3452                                                  count:GPBARRAYSIZE(kObjects1)];
3453  XCTAssertNotNil(dict1prime);
3454  GPBInt64ObjectDictionary<NSString*> *dict2 =
3455      [[GPBInt64ObjectDictionary alloc] initWithObjects:kObjects2
3456                                                forKeys:kKeys1
3457                                                  count:GPBARRAYSIZE(kObjects2)];
3458  XCTAssertNotNil(dict2);
3459  GPBInt64ObjectDictionary<NSString*> *dict3 =
3460      [[GPBInt64ObjectDictionary alloc] initWithObjects:kObjects1
3461                                                forKeys:kKeys2
3462                                                  count:GPBARRAYSIZE(kObjects1)];
3463  XCTAssertNotNil(dict3);
3464  GPBInt64ObjectDictionary<NSString*> *dict4 =
3465      [[GPBInt64ObjectDictionary alloc] initWithObjects:kObjects3
3466                                                forKeys:kKeys1
3467                                                  count:GPBARRAYSIZE(kObjects3)];
3468  XCTAssertNotNil(dict4);
3469
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]);
3475
3476  // 2 is same keys, different objects; not equal.
3477  XCTAssertNotEqualObjects(dict1, dict2);
3478
3479  // 3 is different keys, same objects; not equal.
3480  XCTAssertNotEqualObjects(dict1, dict3);
3481
3482  // 4 extra pair; not equal
3483  XCTAssertNotEqualObjects(dict1, dict4);
3484
3485  [dict1 release];
3486  [dict1prime release];
3487  [dict2 release];
3488  [dict3 release];
3489  [dict4 release];
3490}
3491
3492- (void)testCopy {
3493  const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
3494  const NSString* kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
3495  GPBInt64ObjectDictionary<NSString*> *dict =
3496      [[GPBInt64ObjectDictionary alloc] initWithObjects:kObjects
3497                                                forKeys:kKeys
3498                                                  count:GPBARRAYSIZE(kObjects)];
3499  XCTAssertNotNil(dict);
3500
3501  GPBInt64ObjectDictionary<NSString*> *dict2 = [dict copy];
3502  XCTAssertNotNil(dict2);
3503
3504  // Should be new object but equal.
3505  XCTAssertNotEqual(dict, dict2);
3506  XCTAssertEqualObjects(dict, dict2);
3507  XCTAssertTrue([dict2 isKindOfClass:[GPBInt64ObjectDictionary class]]);
3508
3509  [dict2 release];
3510  [dict release];
3511}
3512
3513- (void)testDictionaryFromDictionary {
3514  const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
3515  const NSString* kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
3516  GPBInt64ObjectDictionary<NSString*> *dict =
3517      [[GPBInt64ObjectDictionary alloc] initWithObjects:kObjects
3518                                                forKeys:kKeys
3519                                                  count:GPBARRAYSIZE(kObjects)];
3520  XCTAssertNotNil(dict);
3521
3522  GPBInt64ObjectDictionary<NSString*> *dict2 =
3523      [GPBInt64ObjectDictionary dictionaryWithDictionary:dict];
3524  XCTAssertNotNil(dict2);
3525
3526  // Should be new pointer, but equal objects.
3527  XCTAssertNotEqual(dict, dict2);
3528  XCTAssertEqualObjects(dict, dict2);
3529  [dict release];
3530}
3531
3532- (void)testAdds {
3533  GPBInt64ObjectDictionary<NSString*> *dict = [GPBInt64ObjectDictionary dictionary];
3534  XCTAssertNotNil(dict);
3535
3536  XCTAssertEqual(dict.count, 0U);
3537  [dict setObject:@"abc" forKey:21LL];
3538  XCTAssertEqual(dict.count, 1U);
3539
3540  const int64_t kKeys[] = { 22LL, 23LL, 24LL };
3541  const NSString* kObjects[] = { @"def", @"ghi", @"jkl" };
3542  GPBInt64ObjectDictionary<NSString*> *dict2 =
3543      [[GPBInt64ObjectDictionary alloc] initWithObjects:kObjects
3544                                                forKeys:kKeys
3545                                                  count:GPBARRAYSIZE(kObjects)];
3546  XCTAssertNotNil(dict2);
3547  [dict addEntriesFromDictionary:dict2];
3548  XCTAssertEqual(dict.count, 4U);
3549
3550  XCTAssertEqualObjects([dict objectForKey:21LL], @"abc");
3551  XCTAssertEqualObjects([dict objectForKey:22LL], @"def");
3552  XCTAssertEqualObjects([dict objectForKey:23LL], @"ghi");
3553  XCTAssertEqualObjects([dict objectForKey:24LL], @"jkl");
3554  [dict2 release];
3555}
3556
3557- (void)testRemove {
3558  const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
3559  const NSString* kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
3560  GPBInt64ObjectDictionary<NSString*> *dict =
3561      [[GPBInt64ObjectDictionary alloc] initWithObjects:kObjects
3562                                         forKeys:kKeys
3563                                           count:GPBARRAYSIZE(kObjects)];
3564  XCTAssertNotNil(dict);
3565  XCTAssertEqual(dict.count, 4U);
3566
3567  [dict removeObjectForKey:22LL];
3568  XCTAssertEqual(dict.count, 3U);
3569  XCTAssertEqualObjects([dict objectForKey:21LL], @"abc");
3570  XCTAssertNil([dict objectForKey:22LL]);
3571  XCTAssertEqualObjects([dict objectForKey:23LL], @"ghi");
3572  XCTAssertEqualObjects([dict objectForKey:24LL], @"jkl");
3573
3574  // Remove again does nothing.
3575  [dict removeObjectForKey:22LL];
3576  XCTAssertEqual(dict.count, 3U);
3577  XCTAssertEqualObjects([dict objectForKey:21LL], @"abc");
3578  XCTAssertNil([dict objectForKey:22LL]);
3579  XCTAssertEqualObjects([dict objectForKey:23LL], @"ghi");
3580  XCTAssertEqualObjects([dict objectForKey:24LL], @"jkl");
3581
3582  [dict removeObjectForKey:24LL];
3583  XCTAssertEqual(dict.count, 2U);
3584  XCTAssertEqualObjects([dict objectForKey:21LL], @"abc");
3585  XCTAssertNil([dict objectForKey:22LL]);
3586  XCTAssertEqualObjects([dict objectForKey:23LL], @"ghi");
3587  XCTAssertNil([dict objectForKey:24LL]);
3588
3589  [dict removeAll];
3590  XCTAssertEqual(dict.count, 0U);
3591  XCTAssertNil([dict objectForKey:21LL]);
3592  XCTAssertNil([dict objectForKey:22LL]);
3593  XCTAssertNil([dict objectForKey:23LL]);
3594  XCTAssertNil([dict objectForKey:24LL]);
3595  [dict release];
3596}
3597
3598- (void)testInplaceMutation {
3599  const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
3600  const NSString* kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
3601  GPBInt64ObjectDictionary<NSString*> *dict =
3602      [[GPBInt64ObjectDictionary alloc] initWithObjects:kObjects
3603                                         forKeys:kKeys
3604                                           count:GPBARRAYSIZE(kObjects)];
3605  XCTAssertNotNil(dict);
3606  XCTAssertEqual(dict.count, 4U);
3607  XCTAssertEqualObjects([dict objectForKey:21LL], @"abc");
3608  XCTAssertEqualObjects([dict objectForKey:22LL], @"def");
3609  XCTAssertEqualObjects([dict objectForKey:23LL], @"ghi");
3610  XCTAssertEqualObjects([dict objectForKey:24LL], @"jkl");
3611
3612  [dict setObject:@"jkl" forKey:21LL];
3613  XCTAssertEqual(dict.count, 4U);
3614  XCTAssertEqualObjects([dict objectForKey:21LL], @"jkl");
3615  XCTAssertEqualObjects([dict objectForKey:22LL], @"def");
3616  XCTAssertEqualObjects([dict objectForKey:23LL], @"ghi");
3617  XCTAssertEqualObjects([dict objectForKey:24LL], @"jkl");
3618
3619  [dict setObject:@"def" forKey:24LL];
3620  XCTAssertEqual(dict.count, 4U);
3621  XCTAssertEqualObjects([dict objectForKey:21LL], @"jkl");
3622  XCTAssertEqualObjects([dict objectForKey:22LL], @"def");
3623  XCTAssertEqualObjects([dict objectForKey:23LL], @"ghi");
3624  XCTAssertEqualObjects([dict objectForKey:24LL], @"def");
3625
3626  const int64_t kKeys2[] = { 22LL, 23LL };
3627  const NSString* kObjects2[] = { @"ghi", @"abc" };
3628  GPBInt64ObjectDictionary<NSString*> *dict2 =
3629      [[GPBInt64ObjectDictionary alloc] initWithObjects:kObjects2
3630                                                forKeys:kKeys2
3631                                                  count:GPBARRAYSIZE(kObjects2)];
3632  XCTAssertNotNil(dict2);
3633  [dict addEntriesFromDictionary:dict2];
3634  XCTAssertEqual(dict.count, 4U);
3635  XCTAssertEqualObjects([dict objectForKey:21LL], @"jkl");
3636  XCTAssertEqualObjects([dict objectForKey:22LL], @"ghi");
3637  XCTAssertEqualObjects([dict objectForKey:23LL], @"abc");
3638  XCTAssertEqualObjects([dict objectForKey:24LL], @"def");
3639
3640  [dict2 release];
3641  [dict release];
3642}
3643
3644@end
3645
3646//%PDDM-EXPAND-END TEST_FOR_POD_KEY(Int64, int64_t, 21LL, 22LL, 23LL, 24LL)
3647
3648