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