GPBDictionaryTests+Bool.m 82.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
// Protocol Buffers - Google's data interchange format
// Copyright 2015 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#import <Foundation/Foundation.h>
#import <XCTest/XCTest.h>

#import "GPBDictionary.h"

36
#import "GPBTestUtilities.h"
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
#import "google/protobuf/UnittestRuntimeProto2.pbobjc.h"

// Pull in the macros (using an external file because expanding all tests
// in a single file makes a file that is failing to work with within Xcode.
//%PDDM-IMPORT-DEFINES GPBDictionaryTests.pddm

//%PDDM-EXPAND BOOL_TESTS_FOR_POD_VALUE(UInt32, uint32_t, 100U, 101U)
// This block of code is generated, do not edit it directly.

#pragma mark - Bool -> UInt32

@interface GPBBoolUInt32DictionaryTests : XCTestCase
@end

@implementation GPBBoolUInt32DictionaryTests

- (void)testEmpty {
  GPBBoolUInt32Dictionary *dict = [[GPBBoolUInt32Dictionary alloc] init];
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 0U);
57 58
  XCTAssertFalse([dict getUInt32:NULL forKey:YES]);
  [dict enumerateKeysAndUInt32sUsingBlock:^(BOOL aKey, uint32_t aValue, BOOL *stop) {
59 60 61 62 63 64 65
    #pragma unused(aKey, aValue, stop)
    XCTFail(@"Shouldn't get here!");
  }];
  [dict release];
}

- (void)testOne {
66 67
  GPBBoolUInt32Dictionary *dict = [[GPBBoolUInt32Dictionary alloc] init];
  [dict setUInt32:100U forKey:YES];
68 69 70
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 1U);
  uint32_t value;
71 72
  XCTAssertTrue([dict getUInt32:NULL forKey:YES]);
  XCTAssertTrue([dict getUInt32:&value forKey:YES]);
73
  XCTAssertEqual(value, 100U);
74 75
  XCTAssertFalse([dict getUInt32:NULL forKey:NO]);
  [dict enumerateKeysAndUInt32sUsingBlock:^(BOOL aKey, uint32_t aValue, BOOL *stop) {
76 77 78 79
    XCTAssertEqual(aKey, YES);
    XCTAssertEqual(aValue, 100U);
    XCTAssertNotEqual(stop, NULL);
  }];
80
  [dict release];
81 82 83 84 85 86
}

- (void)testBasics {
  const BOOL kKeys[] = { YES, NO };
  const uint32_t kValues[] = { 100U, 101U };
  GPBBoolUInt32Dictionary *dict =
87 88 89
      [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kValues)];
90 91 92
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);
  uint32_t value;
93 94
  XCTAssertTrue([dict getUInt32:NULL forKey:YES]);
  XCTAssertTrue([dict getUInt32:&value forKey:YES]);
95
  XCTAssertEqual(value, 100U);
96 97
  XCTAssertTrue([dict getUInt32:NULL forKey:NO]);
  XCTAssertTrue([dict getUInt32:&value forKey:NO]);
98 99 100 101 102
  XCTAssertEqual(value, 101U);

  __block NSUInteger idx = 0;
  BOOL *seenKeys = malloc(2 * sizeof(BOOL));
  uint32_t *seenValues = malloc(2 * sizeof(uint32_t));
103
  [dict enumerateKeysAndUInt32sUsingBlock:^(BOOL aKey, uint32_t aValue, BOOL *stop) {
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
    XCTAssertLessThan(idx, 2U);
    seenKeys[idx] = aKey;
    seenValues[idx] = aValue;
    XCTAssertNotEqual(stop, NULL);
    ++idx;
  }];
  for (int i = 0; i < 2; ++i) {
    BOOL foundKey = NO;
    for (int j = 0; (j < 2) && !foundKey; ++j) {
      if (kKeys[i] == seenKeys[j]) {
        foundKey = YES;
        XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
      }
    }
    XCTAssertTrue(foundKey, @"i = %d", i);
  }
  free(seenKeys);
  free(seenValues);

  // Stopping the enumeration.
  idx = 0;
125
  [dict enumerateKeysAndUInt32sUsingBlock:^(BOOL aKey, uint32_t aValue, BOOL *stop) {
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
    #pragma unused(aKey, aValue)
    if (idx == 0) *stop = YES;
    XCTAssertNotEqual(idx, 2U);
    ++idx;
  }];
  [dict release];
}

- (void)testEquality {
  const BOOL kKeys1[] = { YES, NO };
  const BOOL kKeys2[] = { NO, YES };
  const uint32_t kValues1[] = { 100U, 101U };
  const uint32_t kValues2[] = { 101U, 100U };
  const uint32_t kValues3[] = { 101U };
  GPBBoolUInt32Dictionary *dict1 =
141 142 143
      [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues1
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kValues1)];
144 145
  XCTAssertNotNil(dict1);
  GPBBoolUInt32Dictionary *dict1prime =
146 147 148
      [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues1
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kValues1)];
149 150
  XCTAssertNotNil(dict1prime);
  GPBBoolUInt32Dictionary *dict2 =
151 152 153
      [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues2
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kValues2)];
154 155
  XCTAssertNotNil(dict2);
  GPBBoolUInt32Dictionary *dict3 =
156 157 158
      [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues1
                                               forKeys:kKeys2
                                                 count:GPBARRAYSIZE(kValues1)];
159 160
  XCTAssertNotNil(dict3);
  GPBBoolUInt32Dictionary *dict4 =
161 162 163
      [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues3
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kValues3)];
164 165 166 167 168 169 170 171
  XCTAssertNotNil(dict4);

  // 1/1Prime should be different objects, but equal.
  XCTAssertNotEqual(dict1, dict1prime);
  XCTAssertEqualObjects(dict1, dict1prime);
  // Equal, so they must have same hash.
  XCTAssertEqual([dict1 hash], [dict1prime hash]);

172
  // 2 is same keys, different values; not equal.
173 174
  XCTAssertNotEqualObjects(dict1, dict2);

175
  // 3 is different keys, same values; not equal.
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
  XCTAssertNotEqualObjects(dict1, dict3);

  // 4 Fewer pairs; not equal
  XCTAssertNotEqualObjects(dict1, dict4);

  [dict1 release];
  [dict1prime release];
  [dict2 release];
  [dict3 release];
  [dict4 release];
}

- (void)testCopy {
  const BOOL kKeys[] = { YES, NO };
  const uint32_t kValues[] = { 100U, 101U };
  GPBBoolUInt32Dictionary *dict =
192 193 194
      [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kValues)];
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
  XCTAssertNotNil(dict);

  GPBBoolUInt32Dictionary *dict2 = [dict copy];
  XCTAssertNotNil(dict2);

  // Should be new object but equal.
  XCTAssertNotEqual(dict, dict2);
  XCTAssertEqualObjects(dict, dict2);
  XCTAssertTrue([dict2 isKindOfClass:[GPBBoolUInt32Dictionary class]]);

  [dict2 release];
  [dict release];
}

- (void)testDictionaryFromDictionary {
  const BOOL kKeys[] = { YES, NO };
  const uint32_t kValues[] = { 100U, 101U };
  GPBBoolUInt32Dictionary *dict =
213 214 215
      [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kValues)];
216 217 218
  XCTAssertNotNil(dict);

  GPBBoolUInt32Dictionary *dict2 =
219
      [[GPBBoolUInt32Dictionary alloc] initWithDictionary:dict];
220 221 222 223 224
  XCTAssertNotNil(dict2);

  // Should be new pointer, but equal objects.
  XCTAssertNotEqual(dict, dict2);
  XCTAssertEqualObjects(dict, dict2);
225
  [dict2 release];
226 227 228 229
  [dict release];
}

- (void)testAdds {
230
  GPBBoolUInt32Dictionary *dict = [[GPBBoolUInt32Dictionary alloc] init];
231 232 233
  XCTAssertNotNil(dict);

  XCTAssertEqual(dict.count, 0U);
234
  [dict setUInt32:100U forKey:YES];
235 236 237 238 239
  XCTAssertEqual(dict.count, 1U);

  const BOOL kKeys[] = { NO };
  const uint32_t kValues[] = { 101U };
  GPBBoolUInt32Dictionary *dict2 =
240 241 242
      [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kValues)];
243 244 245 246 247
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);

  uint32_t value;
248 249
  XCTAssertTrue([dict getUInt32:NULL forKey:YES]);
  XCTAssertTrue([dict getUInt32:&value forKey:YES]);
250
  XCTAssertEqual(value, 100U);
251 252
  XCTAssertTrue([dict getUInt32:NULL forKey:NO]);
  XCTAssertTrue([dict getUInt32:&value forKey:NO]);
253 254
  XCTAssertEqual(value, 101U);
  [dict2 release];
255
  [dict release];
256 257 258 259 260 261
}

- (void)testRemove {
  const BOOL kKeys[] = { YES, NO};
  const uint32_t kValues[] = { 100U, 101U };
  GPBBoolUInt32Dictionary *dict =
262 263 264
      [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues
                                        forKeys:kKeys
                                          count:GPBARRAYSIZE(kValues)];
265 266 267
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);

268
  [dict removeUInt32ForKey:NO];
269 270
  XCTAssertEqual(dict.count, 1U);
  uint32_t value;
271 272
  XCTAssertTrue([dict getUInt32:NULL forKey:YES]);
  XCTAssertTrue([dict getUInt32:&value forKey:YES]);
273
  XCTAssertEqual(value, 100U);
274
  XCTAssertFalse([dict getUInt32:NULL forKey:NO]);
275 276

  // Remove again does nothing.
277
  [dict removeUInt32ForKey:NO];
278
  XCTAssertEqual(dict.count, 1U);
279 280
  XCTAssertTrue([dict getUInt32:NULL forKey:YES]);
  XCTAssertTrue([dict getUInt32:&value forKey:YES]);
281
  XCTAssertEqual(value, 100U);
282
  XCTAssertFalse([dict getUInt32:NULL forKey:NO]);
283 284 285

  [dict removeAll];
  XCTAssertEqual(dict.count, 0U);
286 287
  XCTAssertFalse([dict getUInt32:NULL forKey:YES]);
  XCTAssertFalse([dict getUInt32:NULL forKey:NO]);
288 289 290 291 292 293 294
  [dict release];
}

- (void)testInplaceMutation {
  const BOOL kKeys[] = { YES, NO };
  const uint32_t kValues[] = { 100U, 101U };
  GPBBoolUInt32Dictionary *dict =
295 296 297
      [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kValues)];
298 299 300
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);
  uint32_t value;
301 302
  XCTAssertTrue([dict getUInt32:NULL forKey:YES]);
  XCTAssertTrue([dict getUInt32:&value forKey:YES]);
303
  XCTAssertEqual(value, 100U);
304 305
  XCTAssertTrue([dict getUInt32:NULL forKey:NO]);
  XCTAssertTrue([dict getUInt32:&value forKey:NO]);
306 307
  XCTAssertEqual(value, 101U);

308
  [dict setUInt32:101U forKey:YES];
309
  XCTAssertEqual(dict.count, 2U);
310 311
  XCTAssertTrue([dict getUInt32:NULL forKey:YES]);
  XCTAssertTrue([dict getUInt32:&value forKey:YES]);
312
  XCTAssertEqual(value, 101U);
313 314
  XCTAssertTrue([dict getUInt32:NULL forKey:NO]);
  XCTAssertTrue([dict getUInt32:&value forKey:NO]);
315 316
  XCTAssertEqual(value, 101U);

317
  [dict setUInt32:100U forKey:NO];
318
  XCTAssertEqual(dict.count, 2U);
319 320
  XCTAssertTrue([dict getUInt32:NULL forKey:YES]);
  XCTAssertTrue([dict getUInt32:&value forKey:YES]);
321
  XCTAssertEqual(value, 101U);
322 323
  XCTAssertTrue([dict getUInt32:NULL forKey:NO]);
  XCTAssertTrue([dict getUInt32:&value forKey:NO]);
324 325 326 327 328
  XCTAssertEqual(value, 100U);

  const BOOL kKeys2[] = { NO, YES };
  const uint32_t kValues2[] = { 101U, 100U };
  GPBBoolUInt32Dictionary *dict2 =
329 330 331
      [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues2
                                               forKeys:kKeys2
                                                 count:GPBARRAYSIZE(kValues2)];
332 333 334
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);
335 336
  XCTAssertTrue([dict getUInt32:NULL forKey:YES]);
  XCTAssertTrue([dict getUInt32:&value forKey:YES]);
337
  XCTAssertEqual(value, 100U);
338 339
  XCTAssertTrue([dict getUInt32:NULL forKey:NO]);
  XCTAssertTrue([dict getUInt32:&value forKey:NO]);
340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361
  XCTAssertEqual(value, 101U);

  [dict2 release];
  [dict release];
}

@end

//%PDDM-EXPAND BOOL_TESTS_FOR_POD_VALUE(Int32, int32_t, 200, 201)
// This block of code is generated, do not edit it directly.

#pragma mark - Bool -> Int32

@interface GPBBoolInt32DictionaryTests : XCTestCase
@end

@implementation GPBBoolInt32DictionaryTests

- (void)testEmpty {
  GPBBoolInt32Dictionary *dict = [[GPBBoolInt32Dictionary alloc] init];
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 0U);
362 363
  XCTAssertFalse([dict getInt32:NULL forKey:YES]);
  [dict enumerateKeysAndInt32sUsingBlock:^(BOOL aKey, int32_t aValue, BOOL *stop) {
364 365 366 367 368 369 370
    #pragma unused(aKey, aValue, stop)
    XCTFail(@"Shouldn't get here!");
  }];
  [dict release];
}

- (void)testOne {
371 372
  GPBBoolInt32Dictionary *dict = [[GPBBoolInt32Dictionary alloc] init];
  [dict setInt32:200 forKey:YES];
373 374 375
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 1U);
  int32_t value;
376 377
  XCTAssertTrue([dict getInt32:NULL forKey:YES]);
  XCTAssertTrue([dict getInt32:&value forKey:YES]);
378
  XCTAssertEqual(value, 200);
379 380
  XCTAssertFalse([dict getInt32:NULL forKey:NO]);
  [dict enumerateKeysAndInt32sUsingBlock:^(BOOL aKey, int32_t aValue, BOOL *stop) {
381 382 383 384
    XCTAssertEqual(aKey, YES);
    XCTAssertEqual(aValue, 200);
    XCTAssertNotEqual(stop, NULL);
  }];
385
  [dict release];
386 387 388 389 390 391
}

- (void)testBasics {
  const BOOL kKeys[] = { YES, NO };
  const int32_t kValues[] = { 200, 201 };
  GPBBoolInt32Dictionary *dict =
392
      [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues
393 394 395 396 397
                                             forKeys:kKeys
                                               count:GPBARRAYSIZE(kValues)];
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);
  int32_t value;
398 399
  XCTAssertTrue([dict getInt32:NULL forKey:YES]);
  XCTAssertTrue([dict getInt32:&value forKey:YES]);
400
  XCTAssertEqual(value, 200);
401 402
  XCTAssertTrue([dict getInt32:NULL forKey:NO]);
  XCTAssertTrue([dict getInt32:&value forKey:NO]);
403 404 405 406 407
  XCTAssertEqual(value, 201);

  __block NSUInteger idx = 0;
  BOOL *seenKeys = malloc(2 * sizeof(BOOL));
  int32_t *seenValues = malloc(2 * sizeof(int32_t));
408
  [dict enumerateKeysAndInt32sUsingBlock:^(BOOL aKey, int32_t aValue, BOOL *stop) {
409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429
    XCTAssertLessThan(idx, 2U);
    seenKeys[idx] = aKey;
    seenValues[idx] = aValue;
    XCTAssertNotEqual(stop, NULL);
    ++idx;
  }];
  for (int i = 0; i < 2; ++i) {
    BOOL foundKey = NO;
    for (int j = 0; (j < 2) && !foundKey; ++j) {
      if (kKeys[i] == seenKeys[j]) {
        foundKey = YES;
        XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
      }
    }
    XCTAssertTrue(foundKey, @"i = %d", i);
  }
  free(seenKeys);
  free(seenValues);

  // Stopping the enumeration.
  idx = 0;
430
  [dict enumerateKeysAndInt32sUsingBlock:^(BOOL aKey, int32_t aValue, BOOL *stop) {
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445
    #pragma unused(aKey, aValue)
    if (idx == 0) *stop = YES;
    XCTAssertNotEqual(idx, 2U);
    ++idx;
  }];
  [dict release];
}

- (void)testEquality {
  const BOOL kKeys1[] = { YES, NO };
  const BOOL kKeys2[] = { NO, YES };
  const int32_t kValues1[] = { 200, 201 };
  const int32_t kValues2[] = { 201, 200 };
  const int32_t kValues3[] = { 201 };
  GPBBoolInt32Dictionary *dict1 =
446
      [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues1
447 448 449 450
                                             forKeys:kKeys1
                                               count:GPBARRAYSIZE(kValues1)];
  XCTAssertNotNil(dict1);
  GPBBoolInt32Dictionary *dict1prime =
451
      [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues1
452 453 454 455
                                             forKeys:kKeys1
                                               count:GPBARRAYSIZE(kValues1)];
  XCTAssertNotNil(dict1prime);
  GPBBoolInt32Dictionary *dict2 =
456
      [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues2
457 458 459 460
                                             forKeys:kKeys1
                                               count:GPBARRAYSIZE(kValues2)];
  XCTAssertNotNil(dict2);
  GPBBoolInt32Dictionary *dict3 =
461
      [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues1
462 463 464 465
                                             forKeys:kKeys2
                                               count:GPBARRAYSIZE(kValues1)];
  XCTAssertNotNil(dict3);
  GPBBoolInt32Dictionary *dict4 =
466
      [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues3
467 468 469 470 471 472 473 474 475 476
                                             forKeys:kKeys1
                                               count:GPBARRAYSIZE(kValues3)];
  XCTAssertNotNil(dict4);

  // 1/1Prime should be different objects, but equal.
  XCTAssertNotEqual(dict1, dict1prime);
  XCTAssertEqualObjects(dict1, dict1prime);
  // Equal, so they must have same hash.
  XCTAssertEqual([dict1 hash], [dict1prime hash]);

477
  // 2 is same keys, different values; not equal.
478 479
  XCTAssertNotEqualObjects(dict1, dict2);

480
  // 3 is different keys, same values; not equal.
481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496
  XCTAssertNotEqualObjects(dict1, dict3);

  // 4 Fewer pairs; not equal
  XCTAssertNotEqualObjects(dict1, dict4);

  [dict1 release];
  [dict1prime release];
  [dict2 release];
  [dict3 release];
  [dict4 release];
}

- (void)testCopy {
  const BOOL kKeys[] = { YES, NO };
  const int32_t kValues[] = { 200, 201 };
  GPBBoolInt32Dictionary *dict =
497
      [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues
498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517
                                             forKeys:kKeys
                                               count:GPBARRAYSIZE(kValues)];
  XCTAssertNotNil(dict);

  GPBBoolInt32Dictionary *dict2 = [dict copy];
  XCTAssertNotNil(dict2);

  // Should be new object but equal.
  XCTAssertNotEqual(dict, dict2);
  XCTAssertEqualObjects(dict, dict2);
  XCTAssertTrue([dict2 isKindOfClass:[GPBBoolInt32Dictionary class]]);

  [dict2 release];
  [dict release];
}

- (void)testDictionaryFromDictionary {
  const BOOL kKeys[] = { YES, NO };
  const int32_t kValues[] = { 200, 201 };
  GPBBoolInt32Dictionary *dict =
518
      [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues
519 520 521 522 523
                                             forKeys:kKeys
                                               count:GPBARRAYSIZE(kValues)];
  XCTAssertNotNil(dict);

  GPBBoolInt32Dictionary *dict2 =
524
      [[GPBBoolInt32Dictionary alloc] initWithDictionary:dict];
525 526 527 528 529
  XCTAssertNotNil(dict2);

  // Should be new pointer, but equal objects.
  XCTAssertNotEqual(dict, dict2);
  XCTAssertEqualObjects(dict, dict2);
530
  [dict2 release];
531 532 533 534
  [dict release];
}

- (void)testAdds {
535
  GPBBoolInt32Dictionary *dict = [[GPBBoolInt32Dictionary alloc] init];
536 537 538
  XCTAssertNotNil(dict);

  XCTAssertEqual(dict.count, 0U);
539
  [dict setInt32:200 forKey:YES];
540 541 542 543 544
  XCTAssertEqual(dict.count, 1U);

  const BOOL kKeys[] = { NO };
  const int32_t kValues[] = { 201 };
  GPBBoolInt32Dictionary *dict2 =
545
      [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues
546 547 548 549 550 551 552
                                             forKeys:kKeys
                                               count:GPBARRAYSIZE(kValues)];
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);

  int32_t value;
553 554
  XCTAssertTrue([dict getInt32:NULL forKey:YES]);
  XCTAssertTrue([dict getInt32:&value forKey:YES]);
555
  XCTAssertEqual(value, 200);
556 557
  XCTAssertTrue([dict getInt32:NULL forKey:NO]);
  XCTAssertTrue([dict getInt32:&value forKey:NO]);
558 559
  XCTAssertEqual(value, 201);
  [dict2 release];
560
  [dict release];
561 562 563 564 565 566
}

- (void)testRemove {
  const BOOL kKeys[] = { YES, NO};
  const int32_t kValues[] = { 200, 201 };
  GPBBoolInt32Dictionary *dict =
567
      [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues
568 569 570 571 572
                                      forKeys:kKeys
                                        count:GPBARRAYSIZE(kValues)];
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);

573
  [dict removeInt32ForKey:NO];
574 575
  XCTAssertEqual(dict.count, 1U);
  int32_t value;
576 577
  XCTAssertTrue([dict getInt32:NULL forKey:YES]);
  XCTAssertTrue([dict getInt32:&value forKey:YES]);
578
  XCTAssertEqual(value, 200);
579
  XCTAssertFalse([dict getInt32:NULL forKey:NO]);
580 581

  // Remove again does nothing.
582
  [dict removeInt32ForKey:NO];
583
  XCTAssertEqual(dict.count, 1U);
584 585
  XCTAssertTrue([dict getInt32:NULL forKey:YES]);
  XCTAssertTrue([dict getInt32:&value forKey:YES]);
586
  XCTAssertEqual(value, 200);
587
  XCTAssertFalse([dict getInt32:NULL forKey:NO]);
588 589 590

  [dict removeAll];
  XCTAssertEqual(dict.count, 0U);
591 592
  XCTAssertFalse([dict getInt32:NULL forKey:YES]);
  XCTAssertFalse([dict getInt32:NULL forKey:NO]);
593 594 595 596 597 598 599
  [dict release];
}

- (void)testInplaceMutation {
  const BOOL kKeys[] = { YES, NO };
  const int32_t kValues[] = { 200, 201 };
  GPBBoolInt32Dictionary *dict =
600 601 602
      [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues
                                             forKeys:kKeys
                                               count:GPBARRAYSIZE(kValues)];
603 604 605
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);
  int32_t value;
606 607
  XCTAssertTrue([dict getInt32:NULL forKey:YES]);
  XCTAssertTrue([dict getInt32:&value forKey:YES]);
608
  XCTAssertEqual(value, 200);
609 610
  XCTAssertTrue([dict getInt32:NULL forKey:NO]);
  XCTAssertTrue([dict getInt32:&value forKey:NO]);
611 612
  XCTAssertEqual(value, 201);

613
  [dict setInt32:201 forKey:YES];
614
  XCTAssertEqual(dict.count, 2U);
615 616
  XCTAssertTrue([dict getInt32:NULL forKey:YES]);
  XCTAssertTrue([dict getInt32:&value forKey:YES]);
617
  XCTAssertEqual(value, 201);
618 619
  XCTAssertTrue([dict getInt32:NULL forKey:NO]);
  XCTAssertTrue([dict getInt32:&value forKey:NO]);
620 621
  XCTAssertEqual(value, 201);

622
  [dict setInt32:200 forKey:NO];
623
  XCTAssertEqual(dict.count, 2U);
624 625
  XCTAssertTrue([dict getInt32:NULL forKey:YES]);
  XCTAssertTrue([dict getInt32:&value forKey:YES]);
626
  XCTAssertEqual(value, 201);
627 628
  XCTAssertTrue([dict getInt32:NULL forKey:NO]);
  XCTAssertTrue([dict getInt32:&value forKey:NO]);
629 630 631 632 633
  XCTAssertEqual(value, 200);

  const BOOL kKeys2[] = { NO, YES };
  const int32_t kValues2[] = { 201, 200 };
  GPBBoolInt32Dictionary *dict2 =
634
      [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues2
635 636 637 638 639
                                             forKeys:kKeys2
                                               count:GPBARRAYSIZE(kValues2)];
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);
640 641
  XCTAssertTrue([dict getInt32:NULL forKey:YES]);
  XCTAssertTrue([dict getInt32:&value forKey:YES]);
642
  XCTAssertEqual(value, 200);
643 644
  XCTAssertTrue([dict getInt32:NULL forKey:NO]);
  XCTAssertTrue([dict getInt32:&value forKey:NO]);
645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666
  XCTAssertEqual(value, 201);

  [dict2 release];
  [dict release];
}

@end

//%PDDM-EXPAND BOOL_TESTS_FOR_POD_VALUE(UInt64, uint64_t, 300U, 301U)
// This block of code is generated, do not edit it directly.

#pragma mark - Bool -> UInt64

@interface GPBBoolUInt64DictionaryTests : XCTestCase
@end

@implementation GPBBoolUInt64DictionaryTests

- (void)testEmpty {
  GPBBoolUInt64Dictionary *dict = [[GPBBoolUInt64Dictionary alloc] init];
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 0U);
667 668
  XCTAssertFalse([dict getUInt64:NULL forKey:YES]);
  [dict enumerateKeysAndUInt64sUsingBlock:^(BOOL aKey, uint64_t aValue, BOOL *stop) {
669 670 671 672 673 674 675
    #pragma unused(aKey, aValue, stop)
    XCTFail(@"Shouldn't get here!");
  }];
  [dict release];
}

- (void)testOne {
676 677
  GPBBoolUInt64Dictionary *dict = [[GPBBoolUInt64Dictionary alloc] init];
  [dict setUInt64:300U forKey:YES];
678 679 680
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 1U);
  uint64_t value;
681 682
  XCTAssertTrue([dict getUInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getUInt64:&value forKey:YES]);
683
  XCTAssertEqual(value, 300U);
684 685
  XCTAssertFalse([dict getUInt64:NULL forKey:NO]);
  [dict enumerateKeysAndUInt64sUsingBlock:^(BOOL aKey, uint64_t aValue, BOOL *stop) {
686 687 688 689
    XCTAssertEqual(aKey, YES);
    XCTAssertEqual(aValue, 300U);
    XCTAssertNotEqual(stop, NULL);
  }];
690
  [dict release];
691 692 693 694 695 696
}

- (void)testBasics {
  const BOOL kKeys[] = { YES, NO };
  const uint64_t kValues[] = { 300U, 301U };
  GPBBoolUInt64Dictionary *dict =
697 698 699
      [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kValues)];
700 701 702
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);
  uint64_t value;
703 704
  XCTAssertTrue([dict getUInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getUInt64:&value forKey:YES]);
705
  XCTAssertEqual(value, 300U);
706 707
  XCTAssertTrue([dict getUInt64:NULL forKey:NO]);
  XCTAssertTrue([dict getUInt64:&value forKey:NO]);
708 709 710 711 712
  XCTAssertEqual(value, 301U);

  __block NSUInteger idx = 0;
  BOOL *seenKeys = malloc(2 * sizeof(BOOL));
  uint64_t *seenValues = malloc(2 * sizeof(uint64_t));
713
  [dict enumerateKeysAndUInt64sUsingBlock:^(BOOL aKey, uint64_t aValue, BOOL *stop) {
714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734
    XCTAssertLessThan(idx, 2U);
    seenKeys[idx] = aKey;
    seenValues[idx] = aValue;
    XCTAssertNotEqual(stop, NULL);
    ++idx;
  }];
  for (int i = 0; i < 2; ++i) {
    BOOL foundKey = NO;
    for (int j = 0; (j < 2) && !foundKey; ++j) {
      if (kKeys[i] == seenKeys[j]) {
        foundKey = YES;
        XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
      }
    }
    XCTAssertTrue(foundKey, @"i = %d", i);
  }
  free(seenKeys);
  free(seenValues);

  // Stopping the enumeration.
  idx = 0;
735
  [dict enumerateKeysAndUInt64sUsingBlock:^(BOOL aKey, uint64_t aValue, BOOL *stop) {
736 737 738 739 740 741 742 743 744 745 746 747 748 749 750
    #pragma unused(aKey, aValue)
    if (idx == 0) *stop = YES;
    XCTAssertNotEqual(idx, 2U);
    ++idx;
  }];
  [dict release];
}

- (void)testEquality {
  const BOOL kKeys1[] = { YES, NO };
  const BOOL kKeys2[] = { NO, YES };
  const uint64_t kValues1[] = { 300U, 301U };
  const uint64_t kValues2[] = { 301U, 300U };
  const uint64_t kValues3[] = { 301U };
  GPBBoolUInt64Dictionary *dict1 =
751 752 753
      [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues1
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kValues1)];
754 755
  XCTAssertNotNil(dict1);
  GPBBoolUInt64Dictionary *dict1prime =
756 757 758
      [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues1
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kValues1)];
759 760
  XCTAssertNotNil(dict1prime);
  GPBBoolUInt64Dictionary *dict2 =
761 762 763
      [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues2
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kValues2)];
764 765
  XCTAssertNotNil(dict2);
  GPBBoolUInt64Dictionary *dict3 =
766 767 768
      [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues1
                                               forKeys:kKeys2
                                                 count:GPBARRAYSIZE(kValues1)];
769 770
  XCTAssertNotNil(dict3);
  GPBBoolUInt64Dictionary *dict4 =
771 772 773
      [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues3
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kValues3)];
774 775 776 777 778 779 780 781
  XCTAssertNotNil(dict4);

  // 1/1Prime should be different objects, but equal.
  XCTAssertNotEqual(dict1, dict1prime);
  XCTAssertEqualObjects(dict1, dict1prime);
  // Equal, so they must have same hash.
  XCTAssertEqual([dict1 hash], [dict1prime hash]);

782
  // 2 is same keys, different values; not equal.
783 784
  XCTAssertNotEqualObjects(dict1, dict2);

785
  // 3 is different keys, same values; not equal.
786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801
  XCTAssertNotEqualObjects(dict1, dict3);

  // 4 Fewer pairs; not equal
  XCTAssertNotEqualObjects(dict1, dict4);

  [dict1 release];
  [dict1prime release];
  [dict2 release];
  [dict3 release];
  [dict4 release];
}

- (void)testCopy {
  const BOOL kKeys[] = { YES, NO };
  const uint64_t kValues[] = { 300U, 301U };
  GPBBoolUInt64Dictionary *dict =
802 803 804
      [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kValues)];
805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822
  XCTAssertNotNil(dict);

  GPBBoolUInt64Dictionary *dict2 = [dict copy];
  XCTAssertNotNil(dict2);

  // Should be new object but equal.
  XCTAssertNotEqual(dict, dict2);
  XCTAssertEqualObjects(dict, dict2);
  XCTAssertTrue([dict2 isKindOfClass:[GPBBoolUInt64Dictionary class]]);

  [dict2 release];
  [dict release];
}

- (void)testDictionaryFromDictionary {
  const BOOL kKeys[] = { YES, NO };
  const uint64_t kValues[] = { 300U, 301U };
  GPBBoolUInt64Dictionary *dict =
823 824 825
      [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kValues)];
826 827 828
  XCTAssertNotNil(dict);

  GPBBoolUInt64Dictionary *dict2 =
829
      [[GPBBoolUInt64Dictionary alloc] initWithDictionary:dict];
830 831 832 833 834
  XCTAssertNotNil(dict2);

  // Should be new pointer, but equal objects.
  XCTAssertNotEqual(dict, dict2);
  XCTAssertEqualObjects(dict, dict2);
835
  [dict2 release];
836 837 838 839
  [dict release];
}

- (void)testAdds {
840
  GPBBoolUInt64Dictionary *dict = [[GPBBoolUInt64Dictionary alloc] init];
841 842 843
  XCTAssertNotNil(dict);

  XCTAssertEqual(dict.count, 0U);
844
  [dict setUInt64:300U forKey:YES];
845 846 847 848 849
  XCTAssertEqual(dict.count, 1U);

  const BOOL kKeys[] = { NO };
  const uint64_t kValues[] = { 301U };
  GPBBoolUInt64Dictionary *dict2 =
850 851 852
      [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kValues)];
853 854 855 856 857
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);

  uint64_t value;
858 859
  XCTAssertTrue([dict getUInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getUInt64:&value forKey:YES]);
860
  XCTAssertEqual(value, 300U);
861 862
  XCTAssertTrue([dict getUInt64:NULL forKey:NO]);
  XCTAssertTrue([dict getUInt64:&value forKey:NO]);
863 864
  XCTAssertEqual(value, 301U);
  [dict2 release];
865
  [dict release];
866 867 868 869 870 871
}

- (void)testRemove {
  const BOOL kKeys[] = { YES, NO};
  const uint64_t kValues[] = { 300U, 301U };
  GPBBoolUInt64Dictionary *dict =
872 873 874
      [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues
                                        forKeys:kKeys
                                          count:GPBARRAYSIZE(kValues)];
875 876 877
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);

878
  [dict removeUInt64ForKey:NO];
879 880
  XCTAssertEqual(dict.count, 1U);
  uint64_t value;
881 882
  XCTAssertTrue([dict getUInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getUInt64:&value forKey:YES]);
883
  XCTAssertEqual(value, 300U);
884
  XCTAssertFalse([dict getUInt64:NULL forKey:NO]);
885 886

  // Remove again does nothing.
887
  [dict removeUInt64ForKey:NO];
888
  XCTAssertEqual(dict.count, 1U);
889 890
  XCTAssertTrue([dict getUInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getUInt64:&value forKey:YES]);
891
  XCTAssertEqual(value, 300U);
892
  XCTAssertFalse([dict getUInt64:NULL forKey:NO]);
893 894 895

  [dict removeAll];
  XCTAssertEqual(dict.count, 0U);
896 897
  XCTAssertFalse([dict getUInt64:NULL forKey:YES]);
  XCTAssertFalse([dict getUInt64:NULL forKey:NO]);
898 899 900 901 902 903 904
  [dict release];
}

- (void)testInplaceMutation {
  const BOOL kKeys[] = { YES, NO };
  const uint64_t kValues[] = { 300U, 301U };
  GPBBoolUInt64Dictionary *dict =
905 906 907
      [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kValues)];
908 909 910
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);
  uint64_t value;
911 912
  XCTAssertTrue([dict getUInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getUInt64:&value forKey:YES]);
913
  XCTAssertEqual(value, 300U);
914 915
  XCTAssertTrue([dict getUInt64:NULL forKey:NO]);
  XCTAssertTrue([dict getUInt64:&value forKey:NO]);
916 917
  XCTAssertEqual(value, 301U);

918
  [dict setUInt64:301U forKey:YES];
919
  XCTAssertEqual(dict.count, 2U);
920 921
  XCTAssertTrue([dict getUInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getUInt64:&value forKey:YES]);
922
  XCTAssertEqual(value, 301U);
923 924
  XCTAssertTrue([dict getUInt64:NULL forKey:NO]);
  XCTAssertTrue([dict getUInt64:&value forKey:NO]);
925 926
  XCTAssertEqual(value, 301U);

927
  [dict setUInt64:300U forKey:NO];
928
  XCTAssertEqual(dict.count, 2U);
929 930
  XCTAssertTrue([dict getUInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getUInt64:&value forKey:YES]);
931
  XCTAssertEqual(value, 301U);
932 933
  XCTAssertTrue([dict getUInt64:NULL forKey:NO]);
  XCTAssertTrue([dict getUInt64:&value forKey:NO]);
934 935 936 937 938
  XCTAssertEqual(value, 300U);

  const BOOL kKeys2[] = { NO, YES };
  const uint64_t kValues2[] = { 301U, 300U };
  GPBBoolUInt64Dictionary *dict2 =
939 940 941
      [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues2
                                               forKeys:kKeys2
                                                 count:GPBARRAYSIZE(kValues2)];
942 943 944
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);
945 946
  XCTAssertTrue([dict getUInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getUInt64:&value forKey:YES]);
947
  XCTAssertEqual(value, 300U);
948 949
  XCTAssertTrue([dict getUInt64:NULL forKey:NO]);
  XCTAssertTrue([dict getUInt64:&value forKey:NO]);
950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971
  XCTAssertEqual(value, 301U);

  [dict2 release];
  [dict release];
}

@end

//%PDDM-EXPAND BOOL_TESTS_FOR_POD_VALUE(Int64, int64_t, 400, 401)
// This block of code is generated, do not edit it directly.

#pragma mark - Bool -> Int64

@interface GPBBoolInt64DictionaryTests : XCTestCase
@end

@implementation GPBBoolInt64DictionaryTests

- (void)testEmpty {
  GPBBoolInt64Dictionary *dict = [[GPBBoolInt64Dictionary alloc] init];
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 0U);
972 973
  XCTAssertFalse([dict getInt64:NULL forKey:YES]);
  [dict enumerateKeysAndInt64sUsingBlock:^(BOOL aKey, int64_t aValue, BOOL *stop) {
974 975 976 977 978 979 980
    #pragma unused(aKey, aValue, stop)
    XCTFail(@"Shouldn't get here!");
  }];
  [dict release];
}

- (void)testOne {
981 982
  GPBBoolInt64Dictionary *dict = [[GPBBoolInt64Dictionary alloc] init];
  [dict setInt64:400 forKey:YES];
983 984 985
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 1U);
  int64_t value;
986 987
  XCTAssertTrue([dict getInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getInt64:&value forKey:YES]);
988
  XCTAssertEqual(value, 400);
989 990
  XCTAssertFalse([dict getInt64:NULL forKey:NO]);
  [dict enumerateKeysAndInt64sUsingBlock:^(BOOL aKey, int64_t aValue, BOOL *stop) {
991 992 993 994
    XCTAssertEqual(aKey, YES);
    XCTAssertEqual(aValue, 400);
    XCTAssertNotEqual(stop, NULL);
  }];
995
  [dict release];
996 997 998 999 1000 1001
}

- (void)testBasics {
  const BOOL kKeys[] = { YES, NO };
  const int64_t kValues[] = { 400, 401 };
  GPBBoolInt64Dictionary *dict =
1002
      [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues
1003 1004 1005 1006 1007
                                             forKeys:kKeys
                                               count:GPBARRAYSIZE(kValues)];
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);
  int64_t value;
1008 1009
  XCTAssertTrue([dict getInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getInt64:&value forKey:YES]);
1010
  XCTAssertEqual(value, 400);
1011 1012
  XCTAssertTrue([dict getInt64:NULL forKey:NO]);
  XCTAssertTrue([dict getInt64:&value forKey:NO]);
1013 1014 1015 1016 1017
  XCTAssertEqual(value, 401);

  __block NSUInteger idx = 0;
  BOOL *seenKeys = malloc(2 * sizeof(BOOL));
  int64_t *seenValues = malloc(2 * sizeof(int64_t));
1018
  [dict enumerateKeysAndInt64sUsingBlock:^(BOOL aKey, int64_t aValue, BOOL *stop) {
1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039
    XCTAssertLessThan(idx, 2U);
    seenKeys[idx] = aKey;
    seenValues[idx] = aValue;
    XCTAssertNotEqual(stop, NULL);
    ++idx;
  }];
  for (int i = 0; i < 2; ++i) {
    BOOL foundKey = NO;
    for (int j = 0; (j < 2) && !foundKey; ++j) {
      if (kKeys[i] == seenKeys[j]) {
        foundKey = YES;
        XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
      }
    }
    XCTAssertTrue(foundKey, @"i = %d", i);
  }
  free(seenKeys);
  free(seenValues);

  // Stopping the enumeration.
  idx = 0;
1040
  [dict enumerateKeysAndInt64sUsingBlock:^(BOOL aKey, int64_t aValue, BOOL *stop) {
1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055
    #pragma unused(aKey, aValue)
    if (idx == 0) *stop = YES;
    XCTAssertNotEqual(idx, 2U);
    ++idx;
  }];
  [dict release];
}

- (void)testEquality {
  const BOOL kKeys1[] = { YES, NO };
  const BOOL kKeys2[] = { NO, YES };
  const int64_t kValues1[] = { 400, 401 };
  const int64_t kValues2[] = { 401, 400 };
  const int64_t kValues3[] = { 401 };
  GPBBoolInt64Dictionary *dict1 =
1056
      [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues1
1057 1058 1059 1060
                                             forKeys:kKeys1
                                               count:GPBARRAYSIZE(kValues1)];
  XCTAssertNotNil(dict1);
  GPBBoolInt64Dictionary *dict1prime =
1061
      [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues1
1062 1063 1064 1065
                                             forKeys:kKeys1
                                               count:GPBARRAYSIZE(kValues1)];
  XCTAssertNotNil(dict1prime);
  GPBBoolInt64Dictionary *dict2 =
1066
      [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues2
1067 1068 1069 1070
                                             forKeys:kKeys1
                                               count:GPBARRAYSIZE(kValues2)];
  XCTAssertNotNil(dict2);
  GPBBoolInt64Dictionary *dict3 =
1071
      [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues1
1072 1073 1074 1075
                                             forKeys:kKeys2
                                               count:GPBARRAYSIZE(kValues1)];
  XCTAssertNotNil(dict3);
  GPBBoolInt64Dictionary *dict4 =
1076
      [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues3
1077 1078 1079 1080 1081 1082 1083 1084 1085 1086
                                             forKeys:kKeys1
                                               count:GPBARRAYSIZE(kValues3)];
  XCTAssertNotNil(dict4);

  // 1/1Prime should be different objects, but equal.
  XCTAssertNotEqual(dict1, dict1prime);
  XCTAssertEqualObjects(dict1, dict1prime);
  // Equal, so they must have same hash.
  XCTAssertEqual([dict1 hash], [dict1prime hash]);

1087
  // 2 is same keys, different values; not equal.
1088 1089
  XCTAssertNotEqualObjects(dict1, dict2);

1090
  // 3 is different keys, same values; not equal.
1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106
  XCTAssertNotEqualObjects(dict1, dict3);

  // 4 Fewer pairs; not equal
  XCTAssertNotEqualObjects(dict1, dict4);

  [dict1 release];
  [dict1prime release];
  [dict2 release];
  [dict3 release];
  [dict4 release];
}

- (void)testCopy {
  const BOOL kKeys[] = { YES, NO };
  const int64_t kValues[] = { 400, 401 };
  GPBBoolInt64Dictionary *dict =
1107
      [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues
1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127
                                             forKeys:kKeys
                                               count:GPBARRAYSIZE(kValues)];
  XCTAssertNotNil(dict);

  GPBBoolInt64Dictionary *dict2 = [dict copy];
  XCTAssertNotNil(dict2);

  // Should be new object but equal.
  XCTAssertNotEqual(dict, dict2);
  XCTAssertEqualObjects(dict, dict2);
  XCTAssertTrue([dict2 isKindOfClass:[GPBBoolInt64Dictionary class]]);

  [dict2 release];
  [dict release];
}

- (void)testDictionaryFromDictionary {
  const BOOL kKeys[] = { YES, NO };
  const int64_t kValues[] = { 400, 401 };
  GPBBoolInt64Dictionary *dict =
1128
      [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues
1129 1130 1131 1132 1133
                                             forKeys:kKeys
                                               count:GPBARRAYSIZE(kValues)];
  XCTAssertNotNil(dict);

  GPBBoolInt64Dictionary *dict2 =
1134
      [[GPBBoolInt64Dictionary alloc] initWithDictionary:dict];
1135 1136 1137 1138 1139
  XCTAssertNotNil(dict2);

  // Should be new pointer, but equal objects.
  XCTAssertNotEqual(dict, dict2);
  XCTAssertEqualObjects(dict, dict2);
1140
  [dict2 release];
1141 1142 1143 1144
  [dict release];
}

- (void)testAdds {
1145
  GPBBoolInt64Dictionary *dict = [[GPBBoolInt64Dictionary alloc] init];
1146 1147 1148
  XCTAssertNotNil(dict);

  XCTAssertEqual(dict.count, 0U);
1149
  [dict setInt64:400 forKey:YES];
1150 1151 1152 1153 1154
  XCTAssertEqual(dict.count, 1U);

  const BOOL kKeys[] = { NO };
  const int64_t kValues[] = { 401 };
  GPBBoolInt64Dictionary *dict2 =
1155
      [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues
1156 1157 1158 1159 1160 1161 1162
                                             forKeys:kKeys
                                               count:GPBARRAYSIZE(kValues)];
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);

  int64_t value;
1163 1164
  XCTAssertTrue([dict getInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getInt64:&value forKey:YES]);
1165
  XCTAssertEqual(value, 400);
1166 1167
  XCTAssertTrue([dict getInt64:NULL forKey:NO]);
  XCTAssertTrue([dict getInt64:&value forKey:NO]);
1168 1169
  XCTAssertEqual(value, 401);
  [dict2 release];
1170
  [dict release];
1171 1172 1173 1174 1175 1176
}

- (void)testRemove {
  const BOOL kKeys[] = { YES, NO};
  const int64_t kValues[] = { 400, 401 };
  GPBBoolInt64Dictionary *dict =
1177
      [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues
1178 1179 1180 1181 1182
                                      forKeys:kKeys
                                        count:GPBARRAYSIZE(kValues)];
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);

1183
  [dict removeInt64ForKey:NO];
1184 1185
  XCTAssertEqual(dict.count, 1U);
  int64_t value;
1186 1187
  XCTAssertTrue([dict getInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getInt64:&value forKey:YES]);
1188
  XCTAssertEqual(value, 400);
1189
  XCTAssertFalse([dict getInt64:NULL forKey:NO]);
1190 1191

  // Remove again does nothing.
1192
  [dict removeInt64ForKey:NO];
1193
  XCTAssertEqual(dict.count, 1U);
1194 1195
  XCTAssertTrue([dict getInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getInt64:&value forKey:YES]);
1196
  XCTAssertEqual(value, 400);
1197
  XCTAssertFalse([dict getInt64:NULL forKey:NO]);
1198 1199 1200

  [dict removeAll];
  XCTAssertEqual(dict.count, 0U);
1201 1202
  XCTAssertFalse([dict getInt64:NULL forKey:YES]);
  XCTAssertFalse([dict getInt64:NULL forKey:NO]);
1203 1204 1205 1206 1207 1208 1209
  [dict release];
}

- (void)testInplaceMutation {
  const BOOL kKeys[] = { YES, NO };
  const int64_t kValues[] = { 400, 401 };
  GPBBoolInt64Dictionary *dict =
1210 1211 1212
      [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues
                                             forKeys:kKeys
                                               count:GPBARRAYSIZE(kValues)];
1213 1214 1215
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);
  int64_t value;
1216 1217
  XCTAssertTrue([dict getInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getInt64:&value forKey:YES]);
1218
  XCTAssertEqual(value, 400);
1219 1220
  XCTAssertTrue([dict getInt64:NULL forKey:NO]);
  XCTAssertTrue([dict getInt64:&value forKey:NO]);
1221 1222
  XCTAssertEqual(value, 401);

1223
  [dict setInt64:401 forKey:YES];
1224
  XCTAssertEqual(dict.count, 2U);
1225 1226
  XCTAssertTrue([dict getInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getInt64:&value forKey:YES]);
1227
  XCTAssertEqual(value, 401);
1228 1229
  XCTAssertTrue([dict getInt64:NULL forKey:NO]);
  XCTAssertTrue([dict getInt64:&value forKey:NO]);
1230 1231
  XCTAssertEqual(value, 401);

1232
  [dict setInt64:400 forKey:NO];
1233
  XCTAssertEqual(dict.count, 2U);
1234 1235
  XCTAssertTrue([dict getInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getInt64:&value forKey:YES]);
1236
  XCTAssertEqual(value, 401);
1237 1238
  XCTAssertTrue([dict getInt64:NULL forKey:NO]);
  XCTAssertTrue([dict getInt64:&value forKey:NO]);
1239 1240 1241 1242 1243
  XCTAssertEqual(value, 400);

  const BOOL kKeys2[] = { NO, YES };
  const int64_t kValues2[] = { 401, 400 };
  GPBBoolInt64Dictionary *dict2 =
1244
      [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues2
1245 1246 1247 1248 1249
                                             forKeys:kKeys2
                                               count:GPBARRAYSIZE(kValues2)];
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);
1250 1251
  XCTAssertTrue([dict getInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getInt64:&value forKey:YES]);
1252
  XCTAssertEqual(value, 400);
1253 1254
  XCTAssertTrue([dict getInt64:NULL forKey:NO]);
  XCTAssertTrue([dict getInt64:&value forKey:NO]);
1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276
  XCTAssertEqual(value, 401);

  [dict2 release];
  [dict release];
}

@end

//%PDDM-EXPAND BOOL_TESTS_FOR_POD_VALUE(Bool, BOOL, NO, YES)
// This block of code is generated, do not edit it directly.

#pragma mark - Bool -> Bool

@interface GPBBoolBoolDictionaryTests : XCTestCase
@end

@implementation GPBBoolBoolDictionaryTests

- (void)testEmpty {
  GPBBoolBoolDictionary *dict = [[GPBBoolBoolDictionary alloc] init];
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 0U);
1277 1278
  XCTAssertFalse([dict getBool:NULL forKey:YES]);
  [dict enumerateKeysAndBoolsUsingBlock:^(BOOL aKey, BOOL aValue, BOOL *stop) {
1279 1280 1281 1282 1283 1284 1285
    #pragma unused(aKey, aValue, stop)
    XCTFail(@"Shouldn't get here!");
  }];
  [dict release];
}

- (void)testOne {
1286 1287
  GPBBoolBoolDictionary *dict = [[GPBBoolBoolDictionary alloc] init];
  [dict setBool:NO forKey:YES];
1288 1289 1290
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 1U);
  BOOL value;
1291 1292
  XCTAssertTrue([dict getBool:NULL forKey:YES]);
  XCTAssertTrue([dict getBool:&value forKey:YES]);
1293
  XCTAssertEqual(value, NO);
1294 1295
  XCTAssertFalse([dict getBool:NULL forKey:NO]);
  [dict enumerateKeysAndBoolsUsingBlock:^(BOOL aKey, BOOL aValue, BOOL *stop) {
1296 1297 1298 1299
    XCTAssertEqual(aKey, YES);
    XCTAssertEqual(aValue, NO);
    XCTAssertNotEqual(stop, NULL);
  }];
1300
  [dict release];
1301 1302 1303 1304 1305 1306
}

- (void)testBasics {
  const BOOL kKeys[] = { YES, NO };
  const BOOL kValues[] = { NO, YES };
  GPBBoolBoolDictionary *dict =
1307 1308 1309
      [[GPBBoolBoolDictionary alloc] initWithBools:kValues
                                           forKeys:kKeys
                                             count:GPBARRAYSIZE(kValues)];
1310 1311 1312
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);
  BOOL value;
1313 1314
  XCTAssertTrue([dict getBool:NULL forKey:YES]);
  XCTAssertTrue([dict getBool:&value forKey:YES]);
1315
  XCTAssertEqual(value, NO);
1316 1317
  XCTAssertTrue([dict getBool:NULL forKey:NO]);
  XCTAssertTrue([dict getBool:&value forKey:NO]);
1318 1319 1320 1321 1322
  XCTAssertEqual(value, YES);

  __block NSUInteger idx = 0;
  BOOL *seenKeys = malloc(2 * sizeof(BOOL));
  BOOL *seenValues = malloc(2 * sizeof(BOOL));
1323
  [dict enumerateKeysAndBoolsUsingBlock:^(BOOL aKey, BOOL aValue, BOOL *stop) {
1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344
    XCTAssertLessThan(idx, 2U);
    seenKeys[idx] = aKey;
    seenValues[idx] = aValue;
    XCTAssertNotEqual(stop, NULL);
    ++idx;
  }];
  for (int i = 0; i < 2; ++i) {
    BOOL foundKey = NO;
    for (int j = 0; (j < 2) && !foundKey; ++j) {
      if (kKeys[i] == seenKeys[j]) {
        foundKey = YES;
        XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
      }
    }
    XCTAssertTrue(foundKey, @"i = %d", i);
  }
  free(seenKeys);
  free(seenValues);

  // Stopping the enumeration.
  idx = 0;
1345
  [dict enumerateKeysAndBoolsUsingBlock:^(BOOL aKey, BOOL aValue, BOOL *stop) {
1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360
    #pragma unused(aKey, aValue)
    if (idx == 0) *stop = YES;
    XCTAssertNotEqual(idx, 2U);
    ++idx;
  }];
  [dict release];
}

- (void)testEquality {
  const BOOL kKeys1[] = { YES, NO };
  const BOOL kKeys2[] = { NO, YES };
  const BOOL kValues1[] = { NO, YES };
  const BOOL kValues2[] = { YES, NO };
  const BOOL kValues3[] = { YES };
  GPBBoolBoolDictionary *dict1 =
1361 1362 1363
      [[GPBBoolBoolDictionary alloc] initWithBools:kValues1
                                           forKeys:kKeys1
                                             count:GPBARRAYSIZE(kValues1)];
1364 1365
  XCTAssertNotNil(dict1);
  GPBBoolBoolDictionary *dict1prime =
1366 1367 1368
      [[GPBBoolBoolDictionary alloc] initWithBools:kValues1
                                           forKeys:kKeys1
                                             count:GPBARRAYSIZE(kValues1)];
1369 1370
  XCTAssertNotNil(dict1prime);
  GPBBoolBoolDictionary *dict2 =
1371 1372 1373
      [[GPBBoolBoolDictionary alloc] initWithBools:kValues2
                                           forKeys:kKeys1
                                             count:GPBARRAYSIZE(kValues2)];
1374 1375
  XCTAssertNotNil(dict2);
  GPBBoolBoolDictionary *dict3 =
1376 1377 1378
      [[GPBBoolBoolDictionary alloc] initWithBools:kValues1
                                           forKeys:kKeys2
                                             count:GPBARRAYSIZE(kValues1)];
1379 1380
  XCTAssertNotNil(dict3);
  GPBBoolBoolDictionary *dict4 =
1381 1382 1383
      [[GPBBoolBoolDictionary alloc] initWithBools:kValues3
                                           forKeys:kKeys1
                                             count:GPBARRAYSIZE(kValues3)];
1384 1385 1386 1387 1388 1389 1390 1391
  XCTAssertNotNil(dict4);

  // 1/1Prime should be different objects, but equal.
  XCTAssertNotEqual(dict1, dict1prime);
  XCTAssertEqualObjects(dict1, dict1prime);
  // Equal, so they must have same hash.
  XCTAssertEqual([dict1 hash], [dict1prime hash]);

1392
  // 2 is same keys, different values; not equal.
1393 1394
  XCTAssertNotEqualObjects(dict1, dict2);

1395
  // 3 is different keys, same values; not equal.
1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411
  XCTAssertNotEqualObjects(dict1, dict3);

  // 4 Fewer pairs; not equal
  XCTAssertNotEqualObjects(dict1, dict4);

  [dict1 release];
  [dict1prime release];
  [dict2 release];
  [dict3 release];
  [dict4 release];
}

- (void)testCopy {
  const BOOL kKeys[] = { YES, NO };
  const BOOL kValues[] = { NO, YES };
  GPBBoolBoolDictionary *dict =
1412 1413 1414
      [[GPBBoolBoolDictionary alloc] initWithBools:kValues
                                           forKeys:kKeys
                                             count:GPBARRAYSIZE(kValues)];
1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432
  XCTAssertNotNil(dict);

  GPBBoolBoolDictionary *dict2 = [dict copy];
  XCTAssertNotNil(dict2);

  // Should be new object but equal.
  XCTAssertNotEqual(dict, dict2);
  XCTAssertEqualObjects(dict, dict2);
  XCTAssertTrue([dict2 isKindOfClass:[GPBBoolBoolDictionary class]]);

  [dict2 release];
  [dict release];
}

- (void)testDictionaryFromDictionary {
  const BOOL kKeys[] = { YES, NO };
  const BOOL kValues[] = { NO, YES };
  GPBBoolBoolDictionary *dict =
1433 1434 1435
      [[GPBBoolBoolDictionary alloc] initWithBools:kValues
                                           forKeys:kKeys
                                             count:GPBARRAYSIZE(kValues)];
1436 1437 1438
  XCTAssertNotNil(dict);

  GPBBoolBoolDictionary *dict2 =
1439
      [[GPBBoolBoolDictionary alloc] initWithDictionary:dict];
1440 1441 1442 1443 1444
  XCTAssertNotNil(dict2);

  // Should be new pointer, but equal objects.
  XCTAssertNotEqual(dict, dict2);
  XCTAssertEqualObjects(dict, dict2);
1445
  [dict2 release];
1446 1447 1448 1449
  [dict release];
}

- (void)testAdds {
1450
  GPBBoolBoolDictionary *dict = [[GPBBoolBoolDictionary alloc] init];
1451 1452 1453
  XCTAssertNotNil(dict);

  XCTAssertEqual(dict.count, 0U);
1454
  [dict setBool:NO forKey:YES];
1455 1456 1457 1458 1459
  XCTAssertEqual(dict.count, 1U);

  const BOOL kKeys[] = { NO };
  const BOOL kValues[] = { YES };
  GPBBoolBoolDictionary *dict2 =
1460 1461 1462
      [[GPBBoolBoolDictionary alloc] initWithBools:kValues
                                           forKeys:kKeys
                                             count:GPBARRAYSIZE(kValues)];
1463 1464 1465 1466 1467
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);

  BOOL value;
1468 1469
  XCTAssertTrue([dict getBool:NULL forKey:YES]);
  XCTAssertTrue([dict getBool:&value forKey:YES]);
1470
  XCTAssertEqual(value, NO);
1471 1472
  XCTAssertTrue([dict getBool:NULL forKey:NO]);
  XCTAssertTrue([dict getBool:&value forKey:NO]);
1473 1474
  XCTAssertEqual(value, YES);
  [dict2 release];
1475
  [dict release];
1476 1477 1478 1479 1480 1481
}

- (void)testRemove {
  const BOOL kKeys[] = { YES, NO};
  const BOOL kValues[] = { NO, YES };
  GPBBoolBoolDictionary *dict =
1482 1483 1484
      [[GPBBoolBoolDictionary alloc] initWithBools:kValues
                                    forKeys:kKeys
                                      count:GPBARRAYSIZE(kValues)];
1485 1486 1487
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);

1488
  [dict removeBoolForKey:NO];
1489 1490
  XCTAssertEqual(dict.count, 1U);
  BOOL value;
1491 1492
  XCTAssertTrue([dict getBool:NULL forKey:YES]);
  XCTAssertTrue([dict getBool:&value forKey:YES]);
1493
  XCTAssertEqual(value, NO);
1494
  XCTAssertFalse([dict getBool:NULL forKey:NO]);
1495 1496

  // Remove again does nothing.
1497
  [dict removeBoolForKey:NO];
1498
  XCTAssertEqual(dict.count, 1U);
1499 1500
  XCTAssertTrue([dict getBool:NULL forKey:YES]);
  XCTAssertTrue([dict getBool:&value forKey:YES]);
1501
  XCTAssertEqual(value, NO);
1502
  XCTAssertFalse([dict getBool:NULL forKey:NO]);
1503 1504 1505

  [dict removeAll];
  XCTAssertEqual(dict.count, 0U);
1506 1507
  XCTAssertFalse([dict getBool:NULL forKey:YES]);
  XCTAssertFalse([dict getBool:NULL forKey:NO]);
1508 1509 1510 1511 1512 1513 1514
  [dict release];
}

- (void)testInplaceMutation {
  const BOOL kKeys[] = { YES, NO };
  const BOOL kValues[] = { NO, YES };
  GPBBoolBoolDictionary *dict =
1515 1516 1517
      [[GPBBoolBoolDictionary alloc] initWithBools:kValues
                                           forKeys:kKeys
                                             count:GPBARRAYSIZE(kValues)];
1518 1519 1520
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);
  BOOL value;
1521 1522
  XCTAssertTrue([dict getBool:NULL forKey:YES]);
  XCTAssertTrue([dict getBool:&value forKey:YES]);
1523
  XCTAssertEqual(value, NO);
1524 1525
  XCTAssertTrue([dict getBool:NULL forKey:NO]);
  XCTAssertTrue([dict getBool:&value forKey:NO]);
1526 1527
  XCTAssertEqual(value, YES);

1528
  [dict setBool:YES forKey:YES];
1529
  XCTAssertEqual(dict.count, 2U);
1530 1531
  XCTAssertTrue([dict getBool:NULL forKey:YES]);
  XCTAssertTrue([dict getBool:&value forKey:YES]);
1532
  XCTAssertEqual(value, YES);
1533 1534
  XCTAssertTrue([dict getBool:NULL forKey:NO]);
  XCTAssertTrue([dict getBool:&value forKey:NO]);
1535 1536
  XCTAssertEqual(value, YES);

1537
  [dict setBool:NO forKey:NO];
1538
  XCTAssertEqual(dict.count, 2U);
1539 1540
  XCTAssertTrue([dict getBool:NULL forKey:YES]);
  XCTAssertTrue([dict getBool:&value forKey:YES]);
1541
  XCTAssertEqual(value, YES);
1542 1543
  XCTAssertTrue([dict getBool:NULL forKey:NO]);
  XCTAssertTrue([dict getBool:&value forKey:NO]);
1544 1545 1546 1547 1548
  XCTAssertEqual(value, NO);

  const BOOL kKeys2[] = { NO, YES };
  const BOOL kValues2[] = { YES, NO };
  GPBBoolBoolDictionary *dict2 =
1549 1550 1551
      [[GPBBoolBoolDictionary alloc] initWithBools:kValues2
                                           forKeys:kKeys2
                                             count:GPBARRAYSIZE(kValues2)];
1552 1553 1554
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);
1555 1556
  XCTAssertTrue([dict getBool:NULL forKey:YES]);
  XCTAssertTrue([dict getBool:&value forKey:YES]);
1557
  XCTAssertEqual(value, NO);
1558 1559
  XCTAssertTrue([dict getBool:NULL forKey:NO]);
  XCTAssertTrue([dict getBool:&value forKey:NO]);
1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581
  XCTAssertEqual(value, YES);

  [dict2 release];
  [dict release];
}

@end

//%PDDM-EXPAND BOOL_TESTS_FOR_POD_VALUE(Float, float, 500.f, 501.f)
// This block of code is generated, do not edit it directly.

#pragma mark - Bool -> Float

@interface GPBBoolFloatDictionaryTests : XCTestCase
@end

@implementation GPBBoolFloatDictionaryTests

- (void)testEmpty {
  GPBBoolFloatDictionary *dict = [[GPBBoolFloatDictionary alloc] init];
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 0U);
1582 1583
  XCTAssertFalse([dict getFloat:NULL forKey:YES]);
  [dict enumerateKeysAndFloatsUsingBlock:^(BOOL aKey, float aValue, BOOL *stop) {
1584 1585 1586 1587 1588 1589 1590
    #pragma unused(aKey, aValue, stop)
    XCTFail(@"Shouldn't get here!");
  }];
  [dict release];
}

- (void)testOne {
1591 1592
  GPBBoolFloatDictionary *dict = [[GPBBoolFloatDictionary alloc] init];
  [dict setFloat:500.f forKey:YES];
1593 1594 1595
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 1U);
  float value;
1596 1597
  XCTAssertTrue([dict getFloat:NULL forKey:YES]);
  XCTAssertTrue([dict getFloat:&value forKey:YES]);
1598
  XCTAssertEqual(value, 500.f);
1599 1600
  XCTAssertFalse([dict getFloat:NULL forKey:NO]);
  [dict enumerateKeysAndFloatsUsingBlock:^(BOOL aKey, float aValue, BOOL *stop) {
1601 1602 1603 1604
    XCTAssertEqual(aKey, YES);
    XCTAssertEqual(aValue, 500.f);
    XCTAssertNotEqual(stop, NULL);
  }];
1605
  [dict release];
1606 1607 1608 1609 1610 1611
}

- (void)testBasics {
  const BOOL kKeys[] = { YES, NO };
  const float kValues[] = { 500.f, 501.f };
  GPBBoolFloatDictionary *dict =
1612
      [[GPBBoolFloatDictionary alloc] initWithFloats:kValues
1613 1614 1615 1616 1617
                                             forKeys:kKeys
                                               count:GPBARRAYSIZE(kValues)];
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);
  float value;
1618 1619
  XCTAssertTrue([dict getFloat:NULL forKey:YES]);
  XCTAssertTrue([dict getFloat:&value forKey:YES]);
1620
  XCTAssertEqual(value, 500.f);
1621 1622
  XCTAssertTrue([dict getFloat:NULL forKey:NO]);
  XCTAssertTrue([dict getFloat:&value forKey:NO]);
1623 1624 1625 1626 1627
  XCTAssertEqual(value, 501.f);

  __block NSUInteger idx = 0;
  BOOL *seenKeys = malloc(2 * sizeof(BOOL));
  float *seenValues = malloc(2 * sizeof(float));
1628
  [dict enumerateKeysAndFloatsUsingBlock:^(BOOL aKey, float aValue, BOOL *stop) {
1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649
    XCTAssertLessThan(idx, 2U);
    seenKeys[idx] = aKey;
    seenValues[idx] = aValue;
    XCTAssertNotEqual(stop, NULL);
    ++idx;
  }];
  for (int i = 0; i < 2; ++i) {
    BOOL foundKey = NO;
    for (int j = 0; (j < 2) && !foundKey; ++j) {
      if (kKeys[i] == seenKeys[j]) {
        foundKey = YES;
        XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
      }
    }
    XCTAssertTrue(foundKey, @"i = %d", i);
  }
  free(seenKeys);
  free(seenValues);

  // Stopping the enumeration.
  idx = 0;
1650
  [dict enumerateKeysAndFloatsUsingBlock:^(BOOL aKey, float aValue, BOOL *stop) {
1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665
    #pragma unused(aKey, aValue)
    if (idx == 0) *stop = YES;
    XCTAssertNotEqual(idx, 2U);
    ++idx;
  }];
  [dict release];
}

- (void)testEquality {
  const BOOL kKeys1[] = { YES, NO };
  const BOOL kKeys2[] = { NO, YES };
  const float kValues1[] = { 500.f, 501.f };
  const float kValues2[] = { 501.f, 500.f };
  const float kValues3[] = { 501.f };
  GPBBoolFloatDictionary *dict1 =
1666
      [[GPBBoolFloatDictionary alloc] initWithFloats:kValues1
1667 1668 1669 1670
                                             forKeys:kKeys1
                                               count:GPBARRAYSIZE(kValues1)];
  XCTAssertNotNil(dict1);
  GPBBoolFloatDictionary *dict1prime =
1671
      [[GPBBoolFloatDictionary alloc] initWithFloats:kValues1
1672 1673 1674 1675
                                             forKeys:kKeys1
                                               count:GPBARRAYSIZE(kValues1)];
  XCTAssertNotNil(dict1prime);
  GPBBoolFloatDictionary *dict2 =
1676
      [[GPBBoolFloatDictionary alloc] initWithFloats:kValues2
1677 1678 1679 1680
                                             forKeys:kKeys1
                                               count:GPBARRAYSIZE(kValues2)];
  XCTAssertNotNil(dict2);
  GPBBoolFloatDictionary *dict3 =
1681
      [[GPBBoolFloatDictionary alloc] initWithFloats:kValues1
1682 1683 1684 1685
                                             forKeys:kKeys2
                                               count:GPBARRAYSIZE(kValues1)];
  XCTAssertNotNil(dict3);
  GPBBoolFloatDictionary *dict4 =
1686
      [[GPBBoolFloatDictionary alloc] initWithFloats:kValues3
1687 1688 1689 1690 1691 1692 1693 1694 1695 1696
                                             forKeys:kKeys1
                                               count:GPBARRAYSIZE(kValues3)];
  XCTAssertNotNil(dict4);

  // 1/1Prime should be different objects, but equal.
  XCTAssertNotEqual(dict1, dict1prime);
  XCTAssertEqualObjects(dict1, dict1prime);
  // Equal, so they must have same hash.
  XCTAssertEqual([dict1 hash], [dict1prime hash]);

1697
  // 2 is same keys, different values; not equal.
1698 1699
  XCTAssertNotEqualObjects(dict1, dict2);

1700
  // 3 is different keys, same values; not equal.
1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716
  XCTAssertNotEqualObjects(dict1, dict3);

  // 4 Fewer pairs; not equal
  XCTAssertNotEqualObjects(dict1, dict4);

  [dict1 release];
  [dict1prime release];
  [dict2 release];
  [dict3 release];
  [dict4 release];
}

- (void)testCopy {
  const BOOL kKeys[] = { YES, NO };
  const float kValues[] = { 500.f, 501.f };
  GPBBoolFloatDictionary *dict =
1717
      [[GPBBoolFloatDictionary alloc] initWithFloats:kValues
1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737
                                             forKeys:kKeys
                                               count:GPBARRAYSIZE(kValues)];
  XCTAssertNotNil(dict);

  GPBBoolFloatDictionary *dict2 = [dict copy];
  XCTAssertNotNil(dict2);

  // Should be new object but equal.
  XCTAssertNotEqual(dict, dict2);
  XCTAssertEqualObjects(dict, dict2);
  XCTAssertTrue([dict2 isKindOfClass:[GPBBoolFloatDictionary class]]);

  [dict2 release];
  [dict release];
}

- (void)testDictionaryFromDictionary {
  const BOOL kKeys[] = { YES, NO };
  const float kValues[] = { 500.f, 501.f };
  GPBBoolFloatDictionary *dict =
1738
      [[GPBBoolFloatDictionary alloc] initWithFloats:kValues
1739 1740 1741 1742 1743
                                             forKeys:kKeys
                                               count:GPBARRAYSIZE(kValues)];
  XCTAssertNotNil(dict);

  GPBBoolFloatDictionary *dict2 =
1744
      [[GPBBoolFloatDictionary alloc] initWithDictionary:dict];
1745 1746 1747 1748 1749
  XCTAssertNotNil(dict2);

  // Should be new pointer, but equal objects.
  XCTAssertNotEqual(dict, dict2);
  XCTAssertEqualObjects(dict, dict2);
1750
  [dict2 release];
1751 1752 1753 1754
  [dict release];
}

- (void)testAdds {
1755
  GPBBoolFloatDictionary *dict = [[GPBBoolFloatDictionary alloc] init];
1756 1757 1758
  XCTAssertNotNil(dict);

  XCTAssertEqual(dict.count, 0U);
1759
  [dict setFloat:500.f forKey:YES];
1760 1761 1762 1763 1764
  XCTAssertEqual(dict.count, 1U);

  const BOOL kKeys[] = { NO };
  const float kValues[] = { 501.f };
  GPBBoolFloatDictionary *dict2 =
1765
      [[GPBBoolFloatDictionary alloc] initWithFloats:kValues
1766 1767 1768 1769 1770 1771 1772
                                             forKeys:kKeys
                                               count:GPBARRAYSIZE(kValues)];
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);

  float value;
1773 1774
  XCTAssertTrue([dict getFloat:NULL forKey:YES]);
  XCTAssertTrue([dict getFloat:&value forKey:YES]);
1775
  XCTAssertEqual(value, 500.f);
1776 1777
  XCTAssertTrue([dict getFloat:NULL forKey:NO]);
  XCTAssertTrue([dict getFloat:&value forKey:NO]);
1778 1779
  XCTAssertEqual(value, 501.f);
  [dict2 release];
1780
  [dict release];
1781 1782 1783 1784 1785 1786
}

- (void)testRemove {
  const BOOL kKeys[] = { YES, NO};
  const float kValues[] = { 500.f, 501.f };
  GPBBoolFloatDictionary *dict =
1787
      [[GPBBoolFloatDictionary alloc] initWithFloats:kValues
1788 1789 1790 1791 1792
                                      forKeys:kKeys
                                        count:GPBARRAYSIZE(kValues)];
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);

1793
  [dict removeFloatForKey:NO];
1794 1795
  XCTAssertEqual(dict.count, 1U);
  float value;
1796 1797
  XCTAssertTrue([dict getFloat:NULL forKey:YES]);
  XCTAssertTrue([dict getFloat:&value forKey:YES]);
1798
  XCTAssertEqual(value, 500.f);
1799
  XCTAssertFalse([dict getFloat:NULL forKey:NO]);
1800 1801

  // Remove again does nothing.
1802
  [dict removeFloatForKey:NO];
1803
  XCTAssertEqual(dict.count, 1U);
1804 1805
  XCTAssertTrue([dict getFloat:NULL forKey:YES]);
  XCTAssertTrue([dict getFloat:&value forKey:YES]);
1806
  XCTAssertEqual(value, 500.f);
1807
  XCTAssertFalse([dict getFloat:NULL forKey:NO]);
1808 1809 1810

  [dict removeAll];
  XCTAssertEqual(dict.count, 0U);
1811 1812
  XCTAssertFalse([dict getFloat:NULL forKey:YES]);
  XCTAssertFalse([dict getFloat:NULL forKey:NO]);
1813 1814 1815 1816 1817 1818 1819
  [dict release];
}

- (void)testInplaceMutation {
  const BOOL kKeys[] = { YES, NO };
  const float kValues[] = { 500.f, 501.f };
  GPBBoolFloatDictionary *dict =
1820 1821 1822
      [[GPBBoolFloatDictionary alloc] initWithFloats:kValues
                                             forKeys:kKeys
                                               count:GPBARRAYSIZE(kValues)];
1823 1824 1825
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);
  float value;
1826 1827
  XCTAssertTrue([dict getFloat:NULL forKey:YES]);
  XCTAssertTrue([dict getFloat:&value forKey:YES]);
1828
  XCTAssertEqual(value, 500.f);
1829 1830
  XCTAssertTrue([dict getFloat:NULL forKey:NO]);
  XCTAssertTrue([dict getFloat:&value forKey:NO]);
1831 1832
  XCTAssertEqual(value, 501.f);

1833
  [dict setFloat:501.f forKey:YES];
1834
  XCTAssertEqual(dict.count, 2U);
1835 1836
  XCTAssertTrue([dict getFloat:NULL forKey:YES]);
  XCTAssertTrue([dict getFloat:&value forKey:YES]);
1837
  XCTAssertEqual(value, 501.f);
1838 1839
  XCTAssertTrue([dict getFloat:NULL forKey:NO]);
  XCTAssertTrue([dict getFloat:&value forKey:NO]);
1840 1841
  XCTAssertEqual(value, 501.f);

1842
  [dict setFloat:500.f forKey:NO];
1843
  XCTAssertEqual(dict.count, 2U);
1844 1845
  XCTAssertTrue([dict getFloat:NULL forKey:YES]);
  XCTAssertTrue([dict getFloat:&value forKey:YES]);
1846
  XCTAssertEqual(value, 501.f);
1847 1848
  XCTAssertTrue([dict getFloat:NULL forKey:NO]);
  XCTAssertTrue([dict getFloat:&value forKey:NO]);
1849 1850 1851 1852 1853
  XCTAssertEqual(value, 500.f);

  const BOOL kKeys2[] = { NO, YES };
  const float kValues2[] = { 501.f, 500.f };
  GPBBoolFloatDictionary *dict2 =
1854
      [[GPBBoolFloatDictionary alloc] initWithFloats:kValues2
1855 1856 1857 1858 1859
                                             forKeys:kKeys2
                                               count:GPBARRAYSIZE(kValues2)];
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);
1860 1861
  XCTAssertTrue([dict getFloat:NULL forKey:YES]);
  XCTAssertTrue([dict getFloat:&value forKey:YES]);
1862
  XCTAssertEqual(value, 500.f);
1863 1864
  XCTAssertTrue([dict getFloat:NULL forKey:NO]);
  XCTAssertTrue([dict getFloat:&value forKey:NO]);
1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886
  XCTAssertEqual(value, 501.f);

  [dict2 release];
  [dict release];
}

@end

//%PDDM-EXPAND BOOL_TESTS_FOR_POD_VALUE(Double, double, 600., 601.)
// This block of code is generated, do not edit it directly.

#pragma mark - Bool -> Double

@interface GPBBoolDoubleDictionaryTests : XCTestCase
@end

@implementation GPBBoolDoubleDictionaryTests

- (void)testEmpty {
  GPBBoolDoubleDictionary *dict = [[GPBBoolDoubleDictionary alloc] init];
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 0U);
1887 1888
  XCTAssertFalse([dict getDouble:NULL forKey:YES]);
  [dict enumerateKeysAndDoublesUsingBlock:^(BOOL aKey, double aValue, BOOL *stop) {
1889 1890 1891 1892 1893 1894 1895
    #pragma unused(aKey, aValue, stop)
    XCTFail(@"Shouldn't get here!");
  }];
  [dict release];
}

- (void)testOne {
1896 1897
  GPBBoolDoubleDictionary *dict = [[GPBBoolDoubleDictionary alloc] init];
  [dict setDouble:600. forKey:YES];
1898 1899 1900
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 1U);
  double value;
1901 1902
  XCTAssertTrue([dict getDouble:NULL forKey:YES]);
  XCTAssertTrue([dict getDouble:&value forKey:YES]);
1903
  XCTAssertEqual(value, 600.);
1904 1905
  XCTAssertFalse([dict getDouble:NULL forKey:NO]);
  [dict enumerateKeysAndDoublesUsingBlock:^(BOOL aKey, double aValue, BOOL *stop) {
1906 1907 1908 1909
    XCTAssertEqual(aKey, YES);
    XCTAssertEqual(aValue, 600.);
    XCTAssertNotEqual(stop, NULL);
  }];
1910
  [dict release];
1911 1912 1913 1914 1915 1916
}

- (void)testBasics {
  const BOOL kKeys[] = { YES, NO };
  const double kValues[] = { 600., 601. };
  GPBBoolDoubleDictionary *dict =
1917 1918 1919
      [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kValues)];
1920 1921 1922
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);
  double value;
1923 1924
  XCTAssertTrue([dict getDouble:NULL forKey:YES]);
  XCTAssertTrue([dict getDouble:&value forKey:YES]);
1925
  XCTAssertEqual(value, 600.);
1926 1927
  XCTAssertTrue([dict getDouble:NULL forKey:NO]);
  XCTAssertTrue([dict getDouble:&value forKey:NO]);
1928 1929 1930 1931 1932
  XCTAssertEqual(value, 601.);

  __block NSUInteger idx = 0;
  BOOL *seenKeys = malloc(2 * sizeof(BOOL));
  double *seenValues = malloc(2 * sizeof(double));
1933
  [dict enumerateKeysAndDoublesUsingBlock:^(BOOL aKey, double aValue, BOOL *stop) {
1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954
    XCTAssertLessThan(idx, 2U);
    seenKeys[idx] = aKey;
    seenValues[idx] = aValue;
    XCTAssertNotEqual(stop, NULL);
    ++idx;
  }];
  for (int i = 0; i < 2; ++i) {
    BOOL foundKey = NO;
    for (int j = 0; (j < 2) && !foundKey; ++j) {
      if (kKeys[i] == seenKeys[j]) {
        foundKey = YES;
        XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
      }
    }
    XCTAssertTrue(foundKey, @"i = %d", i);
  }
  free(seenKeys);
  free(seenValues);

  // Stopping the enumeration.
  idx = 0;
1955
  [dict enumerateKeysAndDoublesUsingBlock:^(BOOL aKey, double aValue, BOOL *stop) {
1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970
    #pragma unused(aKey, aValue)
    if (idx == 0) *stop = YES;
    XCTAssertNotEqual(idx, 2U);
    ++idx;
  }];
  [dict release];
}

- (void)testEquality {
  const BOOL kKeys1[] = { YES, NO };
  const BOOL kKeys2[] = { NO, YES };
  const double kValues1[] = { 600., 601. };
  const double kValues2[] = { 601., 600. };
  const double kValues3[] = { 601. };
  GPBBoolDoubleDictionary *dict1 =
1971 1972 1973
      [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues1
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kValues1)];
1974 1975
  XCTAssertNotNil(dict1);
  GPBBoolDoubleDictionary *dict1prime =
1976 1977 1978
      [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues1
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kValues1)];
1979 1980
  XCTAssertNotNil(dict1prime);
  GPBBoolDoubleDictionary *dict2 =
1981 1982 1983
      [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues2
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kValues2)];
1984 1985
  XCTAssertNotNil(dict2);
  GPBBoolDoubleDictionary *dict3 =
1986 1987 1988
      [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues1
                                               forKeys:kKeys2
                                                 count:GPBARRAYSIZE(kValues1)];
1989 1990
  XCTAssertNotNil(dict3);
  GPBBoolDoubleDictionary *dict4 =
1991 1992 1993
      [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues3
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kValues3)];
1994 1995 1996 1997 1998 1999 2000 2001
  XCTAssertNotNil(dict4);

  // 1/1Prime should be different objects, but equal.
  XCTAssertNotEqual(dict1, dict1prime);
  XCTAssertEqualObjects(dict1, dict1prime);
  // Equal, so they must have same hash.
  XCTAssertEqual([dict1 hash], [dict1prime hash]);

2002
  // 2 is same keys, different values; not equal.
2003 2004
  XCTAssertNotEqualObjects(dict1, dict2);

2005
  // 3 is different keys, same values; not equal.
2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021
  XCTAssertNotEqualObjects(dict1, dict3);

  // 4 Fewer pairs; not equal
  XCTAssertNotEqualObjects(dict1, dict4);

  [dict1 release];
  [dict1prime release];
  [dict2 release];
  [dict3 release];
  [dict4 release];
}

- (void)testCopy {
  const BOOL kKeys[] = { YES, NO };
  const double kValues[] = { 600., 601. };
  GPBBoolDoubleDictionary *dict =
2022 2023 2024
      [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kValues)];
2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042
  XCTAssertNotNil(dict);

  GPBBoolDoubleDictionary *dict2 = [dict copy];
  XCTAssertNotNil(dict2);

  // Should be new object but equal.
  XCTAssertNotEqual(dict, dict2);
  XCTAssertEqualObjects(dict, dict2);
  XCTAssertTrue([dict2 isKindOfClass:[GPBBoolDoubleDictionary class]]);

  [dict2 release];
  [dict release];
}

- (void)testDictionaryFromDictionary {
  const BOOL kKeys[] = { YES, NO };
  const double kValues[] = { 600., 601. };
  GPBBoolDoubleDictionary *dict =
2043 2044 2045
      [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kValues)];
2046 2047 2048
  XCTAssertNotNil(dict);

  GPBBoolDoubleDictionary *dict2 =
2049
      [[GPBBoolDoubleDictionary alloc] initWithDictionary:dict];
2050 2051 2052 2053 2054
  XCTAssertNotNil(dict2);

  // Should be new pointer, but equal objects.
  XCTAssertNotEqual(dict, dict2);
  XCTAssertEqualObjects(dict, dict2);
2055
  [dict2 release];
2056 2057 2058 2059
  [dict release];
}

- (void)testAdds {
2060
  GPBBoolDoubleDictionary *dict = [[GPBBoolDoubleDictionary alloc] init];
2061 2062 2063
  XCTAssertNotNil(dict);

  XCTAssertEqual(dict.count, 0U);
2064
  [dict setDouble:600. forKey:YES];
2065 2066 2067 2068 2069
  XCTAssertEqual(dict.count, 1U);

  const BOOL kKeys[] = { NO };
  const double kValues[] = { 601. };
  GPBBoolDoubleDictionary *dict2 =
2070 2071 2072
      [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kValues)];
2073 2074 2075 2076 2077
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);

  double value;
2078 2079
  XCTAssertTrue([dict getDouble:NULL forKey:YES]);
  XCTAssertTrue([dict getDouble:&value forKey:YES]);
2080
  XCTAssertEqual(value, 600.);
2081 2082
  XCTAssertTrue([dict getDouble:NULL forKey:NO]);
  XCTAssertTrue([dict getDouble:&value forKey:NO]);
2083 2084
  XCTAssertEqual(value, 601.);
  [dict2 release];
2085
  [dict release];
2086 2087 2088 2089 2090 2091
}

- (void)testRemove {
  const BOOL kKeys[] = { YES, NO};
  const double kValues[] = { 600., 601. };
  GPBBoolDoubleDictionary *dict =
2092 2093 2094
      [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues
                                        forKeys:kKeys
                                          count:GPBARRAYSIZE(kValues)];
2095 2096 2097
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);

2098
  [dict removeDoubleForKey:NO];
2099 2100
  XCTAssertEqual(dict.count, 1U);
  double value;
2101 2102
  XCTAssertTrue([dict getDouble:NULL forKey:YES]);
  XCTAssertTrue([dict getDouble:&value forKey:YES]);
2103
  XCTAssertEqual(value, 600.);
2104
  XCTAssertFalse([dict getDouble:NULL forKey:NO]);
2105 2106

  // Remove again does nothing.
2107
  [dict removeDoubleForKey:NO];
2108
  XCTAssertEqual(dict.count, 1U);
2109 2110
  XCTAssertTrue([dict getDouble:NULL forKey:YES]);
  XCTAssertTrue([dict getDouble:&value forKey:YES]);
2111
  XCTAssertEqual(value, 600.);
2112
  XCTAssertFalse([dict getDouble:NULL forKey:NO]);
2113 2114 2115

  [dict removeAll];
  XCTAssertEqual(dict.count, 0U);
2116 2117
  XCTAssertFalse([dict getDouble:NULL forKey:YES]);
  XCTAssertFalse([dict getDouble:NULL forKey:NO]);
2118 2119 2120 2121 2122 2123 2124
  [dict release];
}

- (void)testInplaceMutation {
  const BOOL kKeys[] = { YES, NO };
  const double kValues[] = { 600., 601. };
  GPBBoolDoubleDictionary *dict =
2125 2126 2127
      [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kValues)];
2128 2129 2130
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);
  double value;
2131 2132
  XCTAssertTrue([dict getDouble:NULL forKey:YES]);
  XCTAssertTrue([dict getDouble:&value forKey:YES]);
2133
  XCTAssertEqual(value, 600.);
2134 2135
  XCTAssertTrue([dict getDouble:NULL forKey:NO]);
  XCTAssertTrue([dict getDouble:&value forKey:NO]);
2136 2137
  XCTAssertEqual(value, 601.);

2138
  [dict setDouble:601. forKey:YES];
2139
  XCTAssertEqual(dict.count, 2U);
2140 2141
  XCTAssertTrue([dict getDouble:NULL forKey:YES]);
  XCTAssertTrue([dict getDouble:&value forKey:YES]);
2142
  XCTAssertEqual(value, 601.);
2143 2144
  XCTAssertTrue([dict getDouble:NULL forKey:NO]);
  XCTAssertTrue([dict getDouble:&value forKey:NO]);
2145 2146
  XCTAssertEqual(value, 601.);

2147
  [dict setDouble:600. forKey:NO];
2148
  XCTAssertEqual(dict.count, 2U);
2149 2150
  XCTAssertTrue([dict getDouble:NULL forKey:YES]);
  XCTAssertTrue([dict getDouble:&value forKey:YES]);
2151
  XCTAssertEqual(value, 601.);
2152 2153
  XCTAssertTrue([dict getDouble:NULL forKey:NO]);
  XCTAssertTrue([dict getDouble:&value forKey:NO]);
2154 2155 2156 2157 2158
  XCTAssertEqual(value, 600.);

  const BOOL kKeys2[] = { NO, YES };
  const double kValues2[] = { 601., 600. };
  GPBBoolDoubleDictionary *dict2 =
2159 2160 2161
      [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues2
                                               forKeys:kKeys2
                                                 count:GPBARRAYSIZE(kValues2)];
2162 2163 2164
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);
2165 2166
  XCTAssertTrue([dict getDouble:NULL forKey:YES]);
  XCTAssertTrue([dict getDouble:&value forKey:YES]);
2167
  XCTAssertEqual(value, 600.);
2168 2169
  XCTAssertTrue([dict getDouble:NULL forKey:NO]);
  XCTAssertTrue([dict getDouble:&value forKey:NO]);
2170 2171 2172 2173 2174 2175 2176 2177
  XCTAssertEqual(value, 601.);

  [dict2 release];
  [dict release];
}

@end

2178
//%PDDM-EXPAND TESTS_FOR_BOOL_KEY_OBJECT_VALUE(Object, NSString*, @"abc", @"def")
2179 2180 2181 2182 2183 2184 2185 2186 2187 2188
// This block of code is generated, do not edit it directly.

#pragma mark - Bool -> Object

@interface GPBBoolObjectDictionaryTests : XCTestCase
@end

@implementation GPBBoolObjectDictionaryTests

- (void)testEmpty {
2189
  GPBBoolObjectDictionary<NSString*> *dict = [[GPBBoolObjectDictionary alloc] init];
2190 2191
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 0U);
2192
  XCTAssertNil([dict objectForKey:YES]);
2193
  [dict enumerateKeysAndObjectsUsingBlock:^(BOOL aKey, NSString* aObject, BOOL *stop) {
2194
    #pragma unused(aKey, aObject, stop)
2195 2196 2197 2198 2199 2200
    XCTFail(@"Shouldn't get here!");
  }];
  [dict release];
}

- (void)testOne {
2201 2202
  GPBBoolObjectDictionary<NSString*> *dict = [[GPBBoolObjectDictionary alloc] init];
  [dict setObject:@"abc" forKey:YES];
2203 2204
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 1U);
2205 2206
  XCTAssertEqualObjects([dict objectForKey:YES], @"abc");
  XCTAssertNil([dict objectForKey:NO]);
2207
  [dict enumerateKeysAndObjectsUsingBlock:^(BOOL aKey, NSString* aObject, BOOL *stop) {
2208
    XCTAssertEqual(aKey, YES);
2209
    XCTAssertEqualObjects(aObject, @"abc");
2210 2211
    XCTAssertNotEqual(stop, NULL);
  }];
2212
  [dict release];
2213 2214 2215 2216
}

- (void)testBasics {
  const BOOL kKeys[] = { YES, NO };
2217 2218
  const NSString* kObjects[] = { @"abc", @"def" };
  GPBBoolObjectDictionary<NSString*> *dict =
2219 2220 2221
      [[GPBBoolObjectDictionary alloc] initWithObjects:kObjects
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kObjects)];
2222 2223
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);
2224 2225
  XCTAssertEqualObjects([dict objectForKey:YES], @"abc");
  XCTAssertEqualObjects([dict objectForKey:NO], @"def");
2226 2227 2228

  __block NSUInteger idx = 0;
  BOOL *seenKeys = malloc(2 * sizeof(BOOL));
2229 2230
  NSString* *seenObjects = malloc(2 * sizeof(NSString*));
  [dict enumerateKeysAndObjectsUsingBlock:^(BOOL aKey, NSString* aObject, BOOL *stop) {
2231 2232
    XCTAssertLessThan(idx, 2U);
    seenKeys[idx] = aKey;
2233
    seenObjects[idx] = aObject;
2234 2235 2236 2237 2238 2239 2240 2241
    XCTAssertNotEqual(stop, NULL);
    ++idx;
  }];
  for (int i = 0; i < 2; ++i) {
    BOOL foundKey = NO;
    for (int j = 0; (j < 2) && !foundKey; ++j) {
      if (kKeys[i] == seenKeys[j]) {
        foundKey = YES;
2242
        XCTAssertEqualObjects(kObjects[i], seenObjects[j], @"i = %d, j = %d", i, j);
2243 2244 2245 2246 2247
      }
    }
    XCTAssertTrue(foundKey, @"i = %d", i);
  }
  free(seenKeys);
2248
  free(seenObjects);
2249 2250 2251

  // Stopping the enumeration.
  idx = 0;
2252
  [dict enumerateKeysAndObjectsUsingBlock:^(BOOL aKey, NSString* aObject, BOOL *stop) {
2253
    #pragma unused(aKey, aObject)
2254 2255 2256 2257 2258 2259 2260 2261 2262 2263
    if (idx == 0) *stop = YES;
    XCTAssertNotEqual(idx, 2U);
    ++idx;
  }];
  [dict release];
}

- (void)testEquality {
  const BOOL kKeys1[] = { YES, NO };
  const BOOL kKeys2[] = { NO, YES };
2264 2265 2266 2267
  const NSString* kObjects1[] = { @"abc", @"def" };
  const NSString* kObjects2[] = { @"def", @"abc" };
  const NSString* kObjects3[] = { @"def" };
  GPBBoolObjectDictionary<NSString*> *dict1 =
2268 2269 2270
      [[GPBBoolObjectDictionary alloc] initWithObjects:kObjects1
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kObjects1)];
2271
  XCTAssertNotNil(dict1);
2272
  GPBBoolObjectDictionary<NSString*> *dict1prime =
2273 2274 2275
      [[GPBBoolObjectDictionary alloc] initWithObjects:kObjects1
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kObjects1)];
2276
  XCTAssertNotNil(dict1prime);
2277
  GPBBoolObjectDictionary<NSString*> *dict2 =
2278 2279 2280
      [[GPBBoolObjectDictionary alloc] initWithObjects:kObjects2
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kObjects2)];
2281
  XCTAssertNotNil(dict2);
2282
  GPBBoolObjectDictionary<NSString*> *dict3 =
2283 2284 2285
      [[GPBBoolObjectDictionary alloc] initWithObjects:kObjects1
                                               forKeys:kKeys2
                                                 count:GPBARRAYSIZE(kObjects1)];
2286
  XCTAssertNotNil(dict3);
2287
  GPBBoolObjectDictionary<NSString*> *dict4 =
2288 2289 2290
      [[GPBBoolObjectDictionary alloc] initWithObjects:kObjects3
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kObjects3)];
2291 2292 2293 2294 2295 2296 2297 2298
  XCTAssertNotNil(dict4);

  // 1/1Prime should be different objects, but equal.
  XCTAssertNotEqual(dict1, dict1prime);
  XCTAssertEqualObjects(dict1, dict1prime);
  // Equal, so they must have same hash.
  XCTAssertEqual([dict1 hash], [dict1prime hash]);

2299
  // 2 is same keys, different objects; not equal.
2300 2301
  XCTAssertNotEqualObjects(dict1, dict2);

2302
  // 3 is different keys, same objects; not equal.
2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316
  XCTAssertNotEqualObjects(dict1, dict3);

  // 4 Fewer pairs; not equal
  XCTAssertNotEqualObjects(dict1, dict4);

  [dict1 release];
  [dict1prime release];
  [dict2 release];
  [dict3 release];
  [dict4 release];
}

- (void)testCopy {
  const BOOL kKeys[] = { YES, NO };
2317 2318
  const NSString* kObjects[] = { @"abc", @"def" };
  GPBBoolObjectDictionary<NSString*> *dict =
2319 2320 2321
      [[GPBBoolObjectDictionary alloc] initWithObjects:kObjects
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kObjects)];
2322 2323
  XCTAssertNotNil(dict);

2324
  GPBBoolObjectDictionary<NSString*> *dict2 = [dict copy];
2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337
  XCTAssertNotNil(dict2);

  // Should be new object but equal.
  XCTAssertNotEqual(dict, dict2);
  XCTAssertEqualObjects(dict, dict2);
  XCTAssertTrue([dict2 isKindOfClass:[GPBBoolObjectDictionary class]]);

  [dict2 release];
  [dict release];
}

- (void)testDictionaryFromDictionary {
  const BOOL kKeys[] = { YES, NO };
2338 2339
  const NSString* kObjects[] = { @"abc", @"def" };
  GPBBoolObjectDictionary<NSString*> *dict =
2340 2341 2342
      [[GPBBoolObjectDictionary alloc] initWithObjects:kObjects
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kObjects)];
2343 2344
  XCTAssertNotNil(dict);

2345
  GPBBoolObjectDictionary<NSString*> *dict2 =
2346
      [[GPBBoolObjectDictionary alloc] initWithDictionary:dict];
2347 2348 2349 2350 2351
  XCTAssertNotNil(dict2);

  // Should be new pointer, but equal objects.
  XCTAssertNotEqual(dict, dict2);
  XCTAssertEqualObjects(dict, dict2);
2352
  [dict2 release];
2353 2354 2355 2356
  [dict release];
}

- (void)testAdds {
2357
  GPBBoolObjectDictionary<NSString*> *dict = [[GPBBoolObjectDictionary alloc] init];
2358 2359 2360
  XCTAssertNotNil(dict);

  XCTAssertEqual(dict.count, 0U);
2361
  [dict setObject:@"abc" forKey:YES];
2362 2363 2364
  XCTAssertEqual(dict.count, 1U);

  const BOOL kKeys[] = { NO };
2365 2366
  const NSString* kObjects[] = { @"def" };
  GPBBoolObjectDictionary<NSString*> *dict2 =
2367 2368 2369
      [[GPBBoolObjectDictionary alloc] initWithObjects:kObjects
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kObjects)];
2370 2371 2372 2373
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);

2374 2375
  XCTAssertEqualObjects([dict objectForKey:YES], @"abc");
  XCTAssertEqualObjects([dict objectForKey:NO], @"def");
2376
  [dict2 release];
2377
  [dict release];
2378 2379 2380 2381
}

- (void)testRemove {
  const BOOL kKeys[] = { YES, NO};
2382 2383
  const NSString* kObjects[] = { @"abc", @"def" };
  GPBBoolObjectDictionary<NSString*> *dict =
2384 2385 2386
      [[GPBBoolObjectDictionary alloc] initWithObjects:kObjects
                                        forKeys:kKeys
                                          count:GPBARRAYSIZE(kObjects)];
2387 2388 2389
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);

2390
  [dict removeObjectForKey:NO];
2391
  XCTAssertEqual(dict.count, 1U);
2392 2393
  XCTAssertEqualObjects([dict objectForKey:YES], @"abc");
  XCTAssertNil([dict objectForKey:NO]);
2394 2395

  // Remove again does nothing.
2396
  [dict removeObjectForKey:NO];
2397
  XCTAssertEqual(dict.count, 1U);
2398 2399
  XCTAssertEqualObjects([dict objectForKey:YES], @"abc");
  XCTAssertNil([dict objectForKey:NO]);
2400 2401 2402

  [dict removeAll];
  XCTAssertEqual(dict.count, 0U);
2403 2404
  XCTAssertNil([dict objectForKey:YES]);
  XCTAssertNil([dict objectForKey:NO]);
2405 2406 2407 2408 2409
  [dict release];
}

- (void)testInplaceMutation {
  const BOOL kKeys[] = { YES, NO };
2410 2411
  const NSString* kObjects[] = { @"abc", @"def" };
  GPBBoolObjectDictionary<NSString*> *dict =
2412
      [[GPBBoolObjectDictionary alloc] initWithObjects:kObjects
2413 2414
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kObjects)];
2415 2416
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);
2417 2418
  XCTAssertEqualObjects([dict objectForKey:YES], @"abc");
  XCTAssertEqualObjects([dict objectForKey:NO], @"def");
2419

2420
  [dict setObject:@"def" forKey:YES];
2421
  XCTAssertEqual(dict.count, 2U);
2422 2423
  XCTAssertEqualObjects([dict objectForKey:YES], @"def");
  XCTAssertEqualObjects([dict objectForKey:NO], @"def");
2424

2425
  [dict setObject:@"abc" forKey:NO];
2426
  XCTAssertEqual(dict.count, 2U);
2427 2428
  XCTAssertEqualObjects([dict objectForKey:YES], @"def");
  XCTAssertEqualObjects([dict objectForKey:NO], @"abc");
2429 2430

  const BOOL kKeys2[] = { NO, YES };
2431 2432
  const NSString* kObjects2[] = { @"def", @"abc" };
  GPBBoolObjectDictionary<NSString*> *dict2 =
2433 2434 2435
      [[GPBBoolObjectDictionary alloc] initWithObjects:kObjects2
                                               forKeys:kKeys2
                                                 count:GPBARRAYSIZE(kObjects2)];
2436 2437 2438
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);
2439 2440
  XCTAssertEqualObjects([dict objectForKey:YES], @"abc");
  XCTAssertEqualObjects([dict objectForKey:NO], @"def");
2441 2442 2443 2444 2445 2446 2447 2448 2449 2450

  [dict2 release];
  [dict release];
}

@end

//%PDDM-EXPAND-END (8 expansions)