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