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