GPBDictionaryTests+Bool.m 82.3 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
  GPBBoolUInt32Dictionary *dict = [GPBBoolUInt32Dictionary dictionaryWithUInt32:100U forKey:YES];
67 68 69
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 1U);
  uint32_t value;
70 71
  XCTAssertTrue([dict getUInt32:NULL forKey:YES]);
  XCTAssertTrue([dict getUInt32:&value forKey:YES]);
72
  XCTAssertEqual(value, 100U);
73 74
  XCTAssertFalse([dict getUInt32:NULL forKey:NO]);
  [dict enumerateKeysAndUInt32sUsingBlock:^(BOOL aKey, uint32_t aValue, BOOL *stop) {
75 76 77 78 79 80 81 82 83 84
    XCTAssertEqual(aKey, YES);
    XCTAssertEqual(aValue, 100U);
    XCTAssertNotEqual(stop, NULL);
  }];
}

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

  __block NSUInteger idx = 0;
  BOOL *seenKeys = malloc(2 * sizeof(BOOL));
  uint32_t *seenValues = malloc(2 * sizeof(uint32_t));
101
  [dict enumerateKeysAndUInt32sUsingBlock:^(BOOL aKey, uint32_t aValue, BOOL *stop) {
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
    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;
123
  [dict enumerateKeysAndUInt32sUsingBlock:^(BOOL aKey, uint32_t aValue, BOOL *stop) {
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
    #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 =
139 140 141
      [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues1
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kValues1)];
142 143
  XCTAssertNotNil(dict1);
  GPBBoolUInt32Dictionary *dict1prime =
144 145 146
      [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues1
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kValues1)];
147 148
  XCTAssertNotNil(dict1prime);
  GPBBoolUInt32Dictionary *dict2 =
149 150 151
      [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues2
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kValues2)];
152 153
  XCTAssertNotNil(dict2);
  GPBBoolUInt32Dictionary *dict3 =
154 155 156
      [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues1
                                               forKeys:kKeys2
                                                 count:GPBARRAYSIZE(kValues1)];
157 158
  XCTAssertNotNil(dict3);
  GPBBoolUInt32Dictionary *dict4 =
159 160 161
      [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues3
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kValues3)];
162 163 164 165 166 167 168 169
  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]);

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

173
  // 3 is different keys, same values; not equal.
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
  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 =
190 191 192
      [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kValues)];
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
  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 =
211 212 213
      [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kValues)];
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
  XCTAssertNotNil(dict);

  GPBBoolUInt32Dictionary *dict2 =
      [GPBBoolUInt32Dictionary dictionaryWithDictionary:dict];
  XCTAssertNotNil(dict2);

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

- (void)testAdds {
  GPBBoolUInt32Dictionary *dict = [GPBBoolUInt32Dictionary dictionary];
  XCTAssertNotNil(dict);

  XCTAssertEqual(dict.count, 0U);
231
  [dict setUInt32:100U forKey:YES];
232 233 234 235 236
  XCTAssertEqual(dict.count, 1U);

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

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

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

264
  [dict removeUInt32ForKey:NO];
265 266
  XCTAssertEqual(dict.count, 1U);
  uint32_t value;
267 268
  XCTAssertTrue([dict getUInt32:NULL forKey:YES]);
  XCTAssertTrue([dict getUInt32:&value forKey:YES]);
269
  XCTAssertEqual(value, 100U);
270
  XCTAssertFalse([dict getUInt32:NULL forKey:NO]);
271 272

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

  [dict removeAll];
  XCTAssertEqual(dict.count, 0U);
282 283
  XCTAssertFalse([dict getUInt32:NULL forKey:YES]);
  XCTAssertFalse([dict getUInt32:NULL forKey:NO]);
284 285 286 287 288 289 290
  [dict release];
}

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

304
  [dict setUInt32:101U forKey:YES];
305
  XCTAssertEqual(dict.count, 2U);
306 307
  XCTAssertTrue([dict getUInt32:NULL forKey:YES]);
  XCTAssertTrue([dict getUInt32:&value forKey:YES]);
308
  XCTAssertEqual(value, 101U);
309 310
  XCTAssertTrue([dict getUInt32:NULL forKey:NO]);
  XCTAssertTrue([dict getUInt32:&value forKey:NO]);
311 312
  XCTAssertEqual(value, 101U);

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

  const BOOL kKeys2[] = { NO, YES };
  const uint32_t kValues2[] = { 101U, 100U };
  GPBBoolUInt32Dictionary *dict2 =
325 326 327
      [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues2
                                               forKeys:kKeys2
                                                 count:GPBARRAYSIZE(kValues2)];
328 329 330
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);
331 332
  XCTAssertTrue([dict getUInt32:NULL forKey:YES]);
  XCTAssertTrue([dict getUInt32:&value forKey:YES]);
333
  XCTAssertEqual(value, 100U);
334 335
  XCTAssertTrue([dict getUInt32:NULL forKey:NO]);
  XCTAssertTrue([dict getUInt32:&value forKey:NO]);
336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357
  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);
358 359
  XCTAssertFalse([dict getInt32:NULL forKey:YES]);
  [dict enumerateKeysAndInt32sUsingBlock:^(BOOL aKey, int32_t aValue, BOOL *stop) {
360 361 362 363 364 365 366
    #pragma unused(aKey, aValue, stop)
    XCTFail(@"Shouldn't get here!");
  }];
  [dict release];
}

- (void)testOne {
367
  GPBBoolInt32Dictionary *dict = [GPBBoolInt32Dictionary dictionaryWithInt32:200 forKey:YES];
368 369 370
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 1U);
  int32_t value;
371 372
  XCTAssertTrue([dict getInt32:NULL forKey:YES]);
  XCTAssertTrue([dict getInt32:&value forKey:YES]);
373
  XCTAssertEqual(value, 200);
374 375
  XCTAssertFalse([dict getInt32:NULL forKey:NO]);
  [dict enumerateKeysAndInt32sUsingBlock:^(BOOL aKey, int32_t aValue, BOOL *stop) {
376 377 378 379 380 381 382 383 384 385
    XCTAssertEqual(aKey, YES);
    XCTAssertEqual(aValue, 200);
    XCTAssertNotEqual(stop, NULL);
  }];
}

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

  __block NSUInteger idx = 0;
  BOOL *seenKeys = malloc(2 * sizeof(BOOL));
  int32_t *seenValues = malloc(2 * sizeof(int32_t));
402
  [dict enumerateKeysAndInt32sUsingBlock:^(BOOL aKey, int32_t aValue, BOOL *stop) {
403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423
    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;
424
  [dict enumerateKeysAndInt32sUsingBlock:^(BOOL aKey, int32_t aValue, BOOL *stop) {
425 426 427 428 429 430 431 432 433 434 435 436 437 438 439
    #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 =
440
      [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues1
441 442 443 444
                                             forKeys:kKeys1
                                               count:GPBARRAYSIZE(kValues1)];
  XCTAssertNotNil(dict1);
  GPBBoolInt32Dictionary *dict1prime =
445
      [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues1
446 447 448 449
                                             forKeys:kKeys1
                                               count:GPBARRAYSIZE(kValues1)];
  XCTAssertNotNil(dict1prime);
  GPBBoolInt32Dictionary *dict2 =
450
      [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues2
451 452 453 454
                                             forKeys:kKeys1
                                               count:GPBARRAYSIZE(kValues2)];
  XCTAssertNotNil(dict2);
  GPBBoolInt32Dictionary *dict3 =
455
      [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues1
456 457 458 459
                                             forKeys:kKeys2
                                               count:GPBARRAYSIZE(kValues1)];
  XCTAssertNotNil(dict3);
  GPBBoolInt32Dictionary *dict4 =
460
      [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues3
461 462 463 464 465 466 467 468 469 470
                                             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]);

471
  // 2 is same keys, different values; not equal.
472 473
  XCTAssertNotEqualObjects(dict1, dict2);

474
  // 3 is different keys, same values; not equal.
475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490
  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 =
491
      [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues
492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511
                                             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 =
512
      [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues
513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531
                                             forKeys:kKeys
                                               count:GPBARRAYSIZE(kValues)];
  XCTAssertNotNil(dict);

  GPBBoolInt32Dictionary *dict2 =
      [GPBBoolInt32Dictionary dictionaryWithDictionary:dict];
  XCTAssertNotNil(dict2);

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

- (void)testAdds {
  GPBBoolInt32Dictionary *dict = [GPBBoolInt32Dictionary dictionary];
  XCTAssertNotNil(dict);

  XCTAssertEqual(dict.count, 0U);
532
  [dict setInt32:200 forKey:YES];
533 534 535 536 537
  XCTAssertEqual(dict.count, 1U);

  const BOOL kKeys[] = { NO };
  const int32_t kValues[] = { 201 };
  GPBBoolInt32Dictionary *dict2 =
538
      [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues
539 540 541 542 543 544 545
                                             forKeys:kKeys
                                               count:GPBARRAYSIZE(kValues)];
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);

  int32_t value;
546 547
  XCTAssertTrue([dict getInt32:NULL forKey:YES]);
  XCTAssertTrue([dict getInt32:&value forKey:YES]);
548
  XCTAssertEqual(value, 200);
549 550
  XCTAssertTrue([dict getInt32:NULL forKey:NO]);
  XCTAssertTrue([dict getInt32:&value forKey:NO]);
551 552 553 554 555 556 557 558
  XCTAssertEqual(value, 201);
  [dict2 release];
}

- (void)testRemove {
  const BOOL kKeys[] = { YES, NO};
  const int32_t kValues[] = { 200, 201 };
  GPBBoolInt32Dictionary *dict =
559
      [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues
560 561 562 563 564
                                      forKeys:kKeys
                                        count:GPBARRAYSIZE(kValues)];
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);

565
  [dict removeInt32ForKey:NO];
566 567
  XCTAssertEqual(dict.count, 1U);
  int32_t value;
568 569
  XCTAssertTrue([dict getInt32:NULL forKey:YES]);
  XCTAssertTrue([dict getInt32:&value forKey:YES]);
570
  XCTAssertEqual(value, 200);
571
  XCTAssertFalse([dict getInt32:NULL forKey:NO]);
572 573

  // Remove again does nothing.
574
  [dict removeInt32ForKey:NO];
575
  XCTAssertEqual(dict.count, 1U);
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 582

  [dict removeAll];
  XCTAssertEqual(dict.count, 0U);
583 584
  XCTAssertFalse([dict getInt32:NULL forKey:YES]);
  XCTAssertFalse([dict getInt32:NULL forKey:NO]);
585 586 587 588 589 590 591
  [dict release];
}

- (void)testInplaceMutation {
  const BOOL kKeys[] = { YES, NO };
  const int32_t kValues[] = { 200, 201 };
  GPBBoolInt32Dictionary *dict =
592 593 594
      [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues
                                             forKeys:kKeys
                                               count:GPBARRAYSIZE(kValues)];
595 596 597
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);
  int32_t value;
598 599
  XCTAssertTrue([dict getInt32:NULL forKey:YES]);
  XCTAssertTrue([dict getInt32:&value forKey:YES]);
600
  XCTAssertEqual(value, 200);
601 602
  XCTAssertTrue([dict getInt32:NULL forKey:NO]);
  XCTAssertTrue([dict getInt32:&value forKey:NO]);
603 604
  XCTAssertEqual(value, 201);

605
  [dict setInt32:201 forKey:YES];
606
  XCTAssertEqual(dict.count, 2U);
607 608
  XCTAssertTrue([dict getInt32:NULL forKey:YES]);
  XCTAssertTrue([dict getInt32:&value forKey:YES]);
609
  XCTAssertEqual(value, 201);
610 611
  XCTAssertTrue([dict getInt32:NULL forKey:NO]);
  XCTAssertTrue([dict getInt32:&value forKey:NO]);
612 613
  XCTAssertEqual(value, 201);

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

  const BOOL kKeys2[] = { NO, YES };
  const int32_t kValues2[] = { 201, 200 };
  GPBBoolInt32Dictionary *dict2 =
626
      [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues2
627 628 629 630 631
                                             forKeys:kKeys2
                                               count:GPBARRAYSIZE(kValues2)];
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);
632 633
  XCTAssertTrue([dict getInt32:NULL forKey:YES]);
  XCTAssertTrue([dict getInt32:&value forKey:YES]);
634
  XCTAssertEqual(value, 200);
635 636
  XCTAssertTrue([dict getInt32:NULL forKey:NO]);
  XCTAssertTrue([dict getInt32:&value forKey:NO]);
637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658
  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);
659 660
  XCTAssertFalse([dict getUInt64:NULL forKey:YES]);
  [dict enumerateKeysAndUInt64sUsingBlock:^(BOOL aKey, uint64_t aValue, BOOL *stop) {
661 662 663 664 665 666 667
    #pragma unused(aKey, aValue, stop)
    XCTFail(@"Shouldn't get here!");
  }];
  [dict release];
}

- (void)testOne {
668
  GPBBoolUInt64Dictionary *dict = [GPBBoolUInt64Dictionary dictionaryWithUInt64:300U forKey:YES];
669 670 671
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 1U);
  uint64_t value;
672 673
  XCTAssertTrue([dict getUInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getUInt64:&value forKey:YES]);
674
  XCTAssertEqual(value, 300U);
675 676
  XCTAssertFalse([dict getUInt64:NULL forKey:NO]);
  [dict enumerateKeysAndUInt64sUsingBlock:^(BOOL aKey, uint64_t aValue, BOOL *stop) {
677 678 679 680 681 682 683 684 685 686
    XCTAssertEqual(aKey, YES);
    XCTAssertEqual(aValue, 300U);
    XCTAssertNotEqual(stop, NULL);
  }];
}

- (void)testBasics {
  const BOOL kKeys[] = { YES, NO };
  const uint64_t kValues[] = { 300U, 301U };
  GPBBoolUInt64Dictionary *dict =
687 688 689
      [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kValues)];
690 691 692
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);
  uint64_t value;
693 694
  XCTAssertTrue([dict getUInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getUInt64:&value forKey:YES]);
695
  XCTAssertEqual(value, 300U);
696 697
  XCTAssertTrue([dict getUInt64:NULL forKey:NO]);
  XCTAssertTrue([dict getUInt64:&value forKey:NO]);
698 699 700 701 702
  XCTAssertEqual(value, 301U);

  __block NSUInteger idx = 0;
  BOOL *seenKeys = malloc(2 * sizeof(BOOL));
  uint64_t *seenValues = malloc(2 * sizeof(uint64_t));
703
  [dict enumerateKeysAndUInt64sUsingBlock:^(BOOL aKey, uint64_t aValue, BOOL *stop) {
704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724
    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;
725
  [dict enumerateKeysAndUInt64sUsingBlock:^(BOOL aKey, uint64_t aValue, BOOL *stop) {
726 727 728 729 730 731 732 733 734 735 736 737 738 739 740
    #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 =
741 742 743
      [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues1
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kValues1)];
744 745
  XCTAssertNotNil(dict1);
  GPBBoolUInt64Dictionary *dict1prime =
746 747 748
      [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues1
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kValues1)];
749 750
  XCTAssertNotNil(dict1prime);
  GPBBoolUInt64Dictionary *dict2 =
751 752 753
      [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues2
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kValues2)];
754 755
  XCTAssertNotNil(dict2);
  GPBBoolUInt64Dictionary *dict3 =
756 757 758
      [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues1
                                               forKeys:kKeys2
                                                 count:GPBARRAYSIZE(kValues1)];
759 760
  XCTAssertNotNil(dict3);
  GPBBoolUInt64Dictionary *dict4 =
761 762 763
      [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues3
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kValues3)];
764 765 766 767 768 769 770 771
  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]);

772
  // 2 is same keys, different values; not equal.
773 774
  XCTAssertNotEqualObjects(dict1, dict2);

775
  // 3 is different keys, same values; not equal.
776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791
  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 =
792 793 794
      [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kValues)];
795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812
  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 =
813 814 815
      [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kValues)];
816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832
  XCTAssertNotNil(dict);

  GPBBoolUInt64Dictionary *dict2 =
      [GPBBoolUInt64Dictionary dictionaryWithDictionary:dict];
  XCTAssertNotNil(dict2);

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

- (void)testAdds {
  GPBBoolUInt64Dictionary *dict = [GPBBoolUInt64Dictionary dictionary];
  XCTAssertNotNil(dict);

  XCTAssertEqual(dict.count, 0U);
833
  [dict setUInt64:300U forKey:YES];
834 835 836 837 838
  XCTAssertEqual(dict.count, 1U);

  const BOOL kKeys[] = { NO };
  const uint64_t kValues[] = { 301U };
  GPBBoolUInt64Dictionary *dict2 =
839 840 841
      [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kValues)];
842 843 844 845 846
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);

  uint64_t value;
847 848
  XCTAssertTrue([dict getUInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getUInt64:&value forKey:YES]);
849
  XCTAssertEqual(value, 300U);
850 851
  XCTAssertTrue([dict getUInt64:NULL forKey:NO]);
  XCTAssertTrue([dict getUInt64:&value forKey:NO]);
852 853 854 855 856 857 858 859
  XCTAssertEqual(value, 301U);
  [dict2 release];
}

- (void)testRemove {
  const BOOL kKeys[] = { YES, NO};
  const uint64_t kValues[] = { 300U, 301U };
  GPBBoolUInt64Dictionary *dict =
860 861 862
      [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues
                                        forKeys:kKeys
                                          count:GPBARRAYSIZE(kValues)];
863 864 865
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);

866
  [dict removeUInt64ForKey:NO];
867 868
  XCTAssertEqual(dict.count, 1U);
  uint64_t value;
869 870
  XCTAssertTrue([dict getUInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getUInt64:&value forKey:YES]);
871
  XCTAssertEqual(value, 300U);
872
  XCTAssertFalse([dict getUInt64:NULL forKey:NO]);
873 874

  // Remove again does nothing.
875
  [dict removeUInt64ForKey:NO];
876
  XCTAssertEqual(dict.count, 1U);
877 878
  XCTAssertTrue([dict getUInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getUInt64:&value forKey:YES]);
879
  XCTAssertEqual(value, 300U);
880
  XCTAssertFalse([dict getUInt64:NULL forKey:NO]);
881 882 883

  [dict removeAll];
  XCTAssertEqual(dict.count, 0U);
884 885
  XCTAssertFalse([dict getUInt64:NULL forKey:YES]);
  XCTAssertFalse([dict getUInt64:NULL forKey:NO]);
886 887 888 889 890 891 892
  [dict release];
}

- (void)testInplaceMutation {
  const BOOL kKeys[] = { YES, NO };
  const uint64_t kValues[] = { 300U, 301U };
  GPBBoolUInt64Dictionary *dict =
893 894 895
      [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kValues)];
896 897 898
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);
  uint64_t value;
899 900
  XCTAssertTrue([dict getUInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getUInt64:&value forKey:YES]);
901
  XCTAssertEqual(value, 300U);
902 903
  XCTAssertTrue([dict getUInt64:NULL forKey:NO]);
  XCTAssertTrue([dict getUInt64:&value forKey:NO]);
904 905
  XCTAssertEqual(value, 301U);

906
  [dict setUInt64:301U forKey:YES];
907
  XCTAssertEqual(dict.count, 2U);
908 909
  XCTAssertTrue([dict getUInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getUInt64:&value forKey:YES]);
910
  XCTAssertEqual(value, 301U);
911 912
  XCTAssertTrue([dict getUInt64:NULL forKey:NO]);
  XCTAssertTrue([dict getUInt64:&value forKey:NO]);
913 914
  XCTAssertEqual(value, 301U);

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

  const BOOL kKeys2[] = { NO, YES };
  const uint64_t kValues2[] = { 301U, 300U };
  GPBBoolUInt64Dictionary *dict2 =
927 928 929
      [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues2
                                               forKeys:kKeys2
                                                 count:GPBARRAYSIZE(kValues2)];
930 931 932
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);
933 934
  XCTAssertTrue([dict getUInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getUInt64:&value forKey:YES]);
935
  XCTAssertEqual(value, 300U);
936 937
  XCTAssertTrue([dict getUInt64:NULL forKey:NO]);
  XCTAssertTrue([dict getUInt64:&value forKey:NO]);
938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959
  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);
960 961
  XCTAssertFalse([dict getInt64:NULL forKey:YES]);
  [dict enumerateKeysAndInt64sUsingBlock:^(BOOL aKey, int64_t aValue, BOOL *stop) {
962 963 964 965 966 967 968
    #pragma unused(aKey, aValue, stop)
    XCTFail(@"Shouldn't get here!");
  }];
  [dict release];
}

- (void)testOne {
969
  GPBBoolInt64Dictionary *dict = [GPBBoolInt64Dictionary dictionaryWithInt64:400 forKey:YES];
970 971 972
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 1U);
  int64_t value;
973 974
  XCTAssertTrue([dict getInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getInt64:&value forKey:YES]);
975
  XCTAssertEqual(value, 400);
976 977
  XCTAssertFalse([dict getInt64:NULL forKey:NO]);
  [dict enumerateKeysAndInt64sUsingBlock:^(BOOL aKey, int64_t aValue, BOOL *stop) {
978 979 980 981 982 983 984 985 986 987
    XCTAssertEqual(aKey, YES);
    XCTAssertEqual(aValue, 400);
    XCTAssertNotEqual(stop, NULL);
  }];
}

- (void)testBasics {
  const BOOL kKeys[] = { YES, NO };
  const int64_t kValues[] = { 400, 401 };
  GPBBoolInt64Dictionary *dict =
988
      [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues
989 990 991 992 993
                                             forKeys:kKeys
                                               count:GPBARRAYSIZE(kValues)];
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);
  int64_t value;
994 995
  XCTAssertTrue([dict getInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getInt64:&value forKey:YES]);
996
  XCTAssertEqual(value, 400);
997 998
  XCTAssertTrue([dict getInt64:NULL forKey:NO]);
  XCTAssertTrue([dict getInt64:&value forKey:NO]);
999 1000 1001 1002 1003
  XCTAssertEqual(value, 401);

  __block NSUInteger idx = 0;
  BOOL *seenKeys = malloc(2 * sizeof(BOOL));
  int64_t *seenValues = malloc(2 * sizeof(int64_t));
1004
  [dict enumerateKeysAndInt64sUsingBlock:^(BOOL aKey, int64_t aValue, BOOL *stop) {
1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025
    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;
1026
  [dict enumerateKeysAndInt64sUsingBlock:^(BOOL aKey, int64_t aValue, BOOL *stop) {
1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041
    #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 =
1042
      [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues1
1043 1044 1045 1046
                                             forKeys:kKeys1
                                               count:GPBARRAYSIZE(kValues1)];
  XCTAssertNotNil(dict1);
  GPBBoolInt64Dictionary *dict1prime =
1047
      [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues1
1048 1049 1050 1051
                                             forKeys:kKeys1
                                               count:GPBARRAYSIZE(kValues1)];
  XCTAssertNotNil(dict1prime);
  GPBBoolInt64Dictionary *dict2 =
1052
      [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues2
1053 1054 1055 1056
                                             forKeys:kKeys1
                                               count:GPBARRAYSIZE(kValues2)];
  XCTAssertNotNil(dict2);
  GPBBoolInt64Dictionary *dict3 =
1057
      [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues1
1058 1059 1060 1061
                                             forKeys:kKeys2
                                               count:GPBARRAYSIZE(kValues1)];
  XCTAssertNotNil(dict3);
  GPBBoolInt64Dictionary *dict4 =
1062
      [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues3
1063 1064 1065 1066 1067 1068 1069 1070 1071 1072
                                             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]);

1073
  // 2 is same keys, different values; not equal.
1074 1075
  XCTAssertNotEqualObjects(dict1, dict2);

1076
  // 3 is different keys, same values; not equal.
1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092
  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 =
1093
      [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues
1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113
                                             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 =
1114
      [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues
1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133
                                             forKeys:kKeys
                                               count:GPBARRAYSIZE(kValues)];
  XCTAssertNotNil(dict);

  GPBBoolInt64Dictionary *dict2 =
      [GPBBoolInt64Dictionary dictionaryWithDictionary:dict];
  XCTAssertNotNil(dict2);

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

- (void)testAdds {
  GPBBoolInt64Dictionary *dict = [GPBBoolInt64Dictionary dictionary];
  XCTAssertNotNil(dict);

  XCTAssertEqual(dict.count, 0U);
1134
  [dict setInt64:400 forKey:YES];
1135 1136 1137 1138 1139
  XCTAssertEqual(dict.count, 1U);

  const BOOL kKeys[] = { NO };
  const int64_t kValues[] = { 401 };
  GPBBoolInt64Dictionary *dict2 =
1140
      [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues
1141 1142 1143 1144 1145 1146 1147
                                             forKeys:kKeys
                                               count:GPBARRAYSIZE(kValues)];
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);

  int64_t value;
1148 1149
  XCTAssertTrue([dict getInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getInt64:&value forKey:YES]);
1150
  XCTAssertEqual(value, 400);
1151 1152
  XCTAssertTrue([dict getInt64:NULL forKey:NO]);
  XCTAssertTrue([dict getInt64:&value forKey:NO]);
1153 1154 1155 1156 1157 1158 1159 1160
  XCTAssertEqual(value, 401);
  [dict2 release];
}

- (void)testRemove {
  const BOOL kKeys[] = { YES, NO};
  const int64_t kValues[] = { 400, 401 };
  GPBBoolInt64Dictionary *dict =
1161
      [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues
1162 1163 1164 1165 1166
                                      forKeys:kKeys
                                        count:GPBARRAYSIZE(kValues)];
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);

1167
  [dict removeInt64ForKey:NO];
1168 1169
  XCTAssertEqual(dict.count, 1U);
  int64_t value;
1170 1171
  XCTAssertTrue([dict getInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getInt64:&value forKey:YES]);
1172
  XCTAssertEqual(value, 400);
1173
  XCTAssertFalse([dict getInt64:NULL forKey:NO]);
1174 1175

  // Remove again does nothing.
1176
  [dict removeInt64ForKey:NO];
1177
  XCTAssertEqual(dict.count, 1U);
1178 1179
  XCTAssertTrue([dict getInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getInt64:&value forKey:YES]);
1180
  XCTAssertEqual(value, 400);
1181
  XCTAssertFalse([dict getInt64:NULL forKey:NO]);
1182 1183 1184

  [dict removeAll];
  XCTAssertEqual(dict.count, 0U);
1185 1186
  XCTAssertFalse([dict getInt64:NULL forKey:YES]);
  XCTAssertFalse([dict getInt64:NULL forKey:NO]);
1187 1188 1189 1190 1191 1192 1193
  [dict release];
}

- (void)testInplaceMutation {
  const BOOL kKeys[] = { YES, NO };
  const int64_t kValues[] = { 400, 401 };
  GPBBoolInt64Dictionary *dict =
1194 1195 1196
      [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues
                                             forKeys:kKeys
                                               count:GPBARRAYSIZE(kValues)];
1197 1198 1199
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);
  int64_t value;
1200 1201
  XCTAssertTrue([dict getInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getInt64:&value forKey:YES]);
1202
  XCTAssertEqual(value, 400);
1203 1204
  XCTAssertTrue([dict getInt64:NULL forKey:NO]);
  XCTAssertTrue([dict getInt64:&value forKey:NO]);
1205 1206
  XCTAssertEqual(value, 401);

1207
  [dict setInt64:401 forKey:YES];
1208
  XCTAssertEqual(dict.count, 2U);
1209 1210
  XCTAssertTrue([dict getInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getInt64:&value forKey:YES]);
1211
  XCTAssertEqual(value, 401);
1212 1213
  XCTAssertTrue([dict getInt64:NULL forKey:NO]);
  XCTAssertTrue([dict getInt64:&value forKey:NO]);
1214 1215
  XCTAssertEqual(value, 401);

1216
  [dict setInt64:400 forKey:NO];
1217
  XCTAssertEqual(dict.count, 2U);
1218 1219
  XCTAssertTrue([dict getInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getInt64:&value forKey:YES]);
1220
  XCTAssertEqual(value, 401);
1221 1222
  XCTAssertTrue([dict getInt64:NULL forKey:NO]);
  XCTAssertTrue([dict getInt64:&value forKey:NO]);
1223 1224 1225 1226 1227
  XCTAssertEqual(value, 400);

  const BOOL kKeys2[] = { NO, YES };
  const int64_t kValues2[] = { 401, 400 };
  GPBBoolInt64Dictionary *dict2 =
1228
      [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues2
1229 1230 1231 1232 1233
                                             forKeys:kKeys2
                                               count:GPBARRAYSIZE(kValues2)];
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);
1234 1235
  XCTAssertTrue([dict getInt64:NULL forKey:YES]);
  XCTAssertTrue([dict getInt64:&value forKey:YES]);
1236
  XCTAssertEqual(value, 400);
1237 1238
  XCTAssertTrue([dict getInt64:NULL forKey:NO]);
  XCTAssertTrue([dict getInt64:&value forKey:NO]);
1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260
  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);
1261 1262
  XCTAssertFalse([dict getBool:NULL forKey:YES]);
  [dict enumerateKeysAndBoolsUsingBlock:^(BOOL aKey, BOOL aValue, BOOL *stop) {
1263 1264 1265 1266 1267 1268 1269
    #pragma unused(aKey, aValue, stop)
    XCTFail(@"Shouldn't get here!");
  }];
  [dict release];
}

- (void)testOne {
1270
  GPBBoolBoolDictionary *dict = [GPBBoolBoolDictionary dictionaryWithBool:NO forKey:YES];
1271 1272 1273
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 1U);
  BOOL value;
1274 1275
  XCTAssertTrue([dict getBool:NULL forKey:YES]);
  XCTAssertTrue([dict getBool:&value forKey:YES]);
1276
  XCTAssertEqual(value, NO);
1277 1278
  XCTAssertFalse([dict getBool:NULL forKey:NO]);
  [dict enumerateKeysAndBoolsUsingBlock:^(BOOL aKey, BOOL aValue, BOOL *stop) {
1279 1280 1281 1282 1283 1284 1285 1286 1287 1288
    XCTAssertEqual(aKey, YES);
    XCTAssertEqual(aValue, NO);
    XCTAssertNotEqual(stop, NULL);
  }];
}

- (void)testBasics {
  const BOOL kKeys[] = { YES, NO };
  const BOOL kValues[] = { NO, YES };
  GPBBoolBoolDictionary *dict =
1289 1290 1291
      [[GPBBoolBoolDictionary alloc] initWithBools:kValues
                                           forKeys:kKeys
                                             count:GPBARRAYSIZE(kValues)];
1292 1293 1294
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);
  BOOL value;
1295 1296
  XCTAssertTrue([dict getBool:NULL forKey:YES]);
  XCTAssertTrue([dict getBool:&value forKey:YES]);
1297
  XCTAssertEqual(value, NO);
1298 1299
  XCTAssertTrue([dict getBool:NULL forKey:NO]);
  XCTAssertTrue([dict getBool:&value forKey:NO]);
1300 1301 1302 1303 1304
  XCTAssertEqual(value, YES);

  __block NSUInteger idx = 0;
  BOOL *seenKeys = malloc(2 * sizeof(BOOL));
  BOOL *seenValues = malloc(2 * sizeof(BOOL));
1305
  [dict enumerateKeysAndBoolsUsingBlock:^(BOOL aKey, BOOL aValue, BOOL *stop) {
1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326
    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;
1327
  [dict enumerateKeysAndBoolsUsingBlock:^(BOOL aKey, BOOL aValue, BOOL *stop) {
1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342
    #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 =
1343 1344 1345
      [[GPBBoolBoolDictionary alloc] initWithBools:kValues1
                                           forKeys:kKeys1
                                             count:GPBARRAYSIZE(kValues1)];
1346 1347
  XCTAssertNotNil(dict1);
  GPBBoolBoolDictionary *dict1prime =
1348 1349 1350
      [[GPBBoolBoolDictionary alloc] initWithBools:kValues1
                                           forKeys:kKeys1
                                             count:GPBARRAYSIZE(kValues1)];
1351 1352
  XCTAssertNotNil(dict1prime);
  GPBBoolBoolDictionary *dict2 =
1353 1354 1355
      [[GPBBoolBoolDictionary alloc] initWithBools:kValues2
                                           forKeys:kKeys1
                                             count:GPBARRAYSIZE(kValues2)];
1356 1357
  XCTAssertNotNil(dict2);
  GPBBoolBoolDictionary *dict3 =
1358 1359 1360
      [[GPBBoolBoolDictionary alloc] initWithBools:kValues1
                                           forKeys:kKeys2
                                             count:GPBARRAYSIZE(kValues1)];
1361 1362
  XCTAssertNotNil(dict3);
  GPBBoolBoolDictionary *dict4 =
1363 1364 1365
      [[GPBBoolBoolDictionary alloc] initWithBools:kValues3
                                           forKeys:kKeys1
                                             count:GPBARRAYSIZE(kValues3)];
1366 1367 1368 1369 1370 1371 1372 1373
  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]);

1374
  // 2 is same keys, different values; not equal.
1375 1376
  XCTAssertNotEqualObjects(dict1, dict2);

1377
  // 3 is different keys, same values; not equal.
1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393
  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 =
1394 1395 1396
      [[GPBBoolBoolDictionary alloc] initWithBools:kValues
                                           forKeys:kKeys
                                             count:GPBARRAYSIZE(kValues)];
1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414
  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 =
1415 1416 1417
      [[GPBBoolBoolDictionary alloc] initWithBools:kValues
                                           forKeys:kKeys
                                             count:GPBARRAYSIZE(kValues)];
1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434
  XCTAssertNotNil(dict);

  GPBBoolBoolDictionary *dict2 =
      [GPBBoolBoolDictionary dictionaryWithDictionary:dict];
  XCTAssertNotNil(dict2);

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

- (void)testAdds {
  GPBBoolBoolDictionary *dict = [GPBBoolBoolDictionary dictionary];
  XCTAssertNotNil(dict);

  XCTAssertEqual(dict.count, 0U);
1435
  [dict setBool:NO forKey:YES];
1436 1437 1438 1439 1440
  XCTAssertEqual(dict.count, 1U);

  const BOOL kKeys[] = { NO };
  const BOOL kValues[] = { YES };
  GPBBoolBoolDictionary *dict2 =
1441 1442 1443
      [[GPBBoolBoolDictionary alloc] initWithBools:kValues
                                           forKeys:kKeys
                                             count:GPBARRAYSIZE(kValues)];
1444 1445 1446 1447 1448
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);

  BOOL value;
1449 1450
  XCTAssertTrue([dict getBool:NULL forKey:YES]);
  XCTAssertTrue([dict getBool:&value forKey:YES]);
1451
  XCTAssertEqual(value, NO);
1452 1453
  XCTAssertTrue([dict getBool:NULL forKey:NO]);
  XCTAssertTrue([dict getBool:&value forKey:NO]);
1454 1455 1456 1457 1458 1459 1460 1461
  XCTAssertEqual(value, YES);
  [dict2 release];
}

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

1468
  [dict removeBoolForKey:NO];
1469 1470
  XCTAssertEqual(dict.count, 1U);
  BOOL value;
1471 1472
  XCTAssertTrue([dict getBool:NULL forKey:YES]);
  XCTAssertTrue([dict getBool:&value forKey:YES]);
1473
  XCTAssertEqual(value, NO);
1474
  XCTAssertFalse([dict getBool:NULL forKey:NO]);
1475 1476

  // Remove again does nothing.
1477
  [dict removeBoolForKey:NO];
1478
  XCTAssertEqual(dict.count, 1U);
1479 1480
  XCTAssertTrue([dict getBool:NULL forKey:YES]);
  XCTAssertTrue([dict getBool:&value forKey:YES]);
1481
  XCTAssertEqual(value, NO);
1482
  XCTAssertFalse([dict getBool:NULL forKey:NO]);
1483 1484 1485

  [dict removeAll];
  XCTAssertEqual(dict.count, 0U);
1486 1487
  XCTAssertFalse([dict getBool:NULL forKey:YES]);
  XCTAssertFalse([dict getBool:NULL forKey:NO]);
1488 1489 1490 1491 1492 1493 1494
  [dict release];
}

- (void)testInplaceMutation {
  const BOOL kKeys[] = { YES, NO };
  const BOOL kValues[] = { NO, YES };
  GPBBoolBoolDictionary *dict =
1495 1496 1497
      [[GPBBoolBoolDictionary alloc] initWithBools:kValues
                                           forKeys:kKeys
                                             count:GPBARRAYSIZE(kValues)];
1498 1499 1500
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);
  BOOL value;
1501 1502
  XCTAssertTrue([dict getBool:NULL forKey:YES]);
  XCTAssertTrue([dict getBool:&value forKey:YES]);
1503
  XCTAssertEqual(value, NO);
1504 1505
  XCTAssertTrue([dict getBool:NULL forKey:NO]);
  XCTAssertTrue([dict getBool:&value forKey:NO]);
1506 1507
  XCTAssertEqual(value, YES);

1508
  [dict setBool:YES forKey:YES];
1509
  XCTAssertEqual(dict.count, 2U);
1510 1511
  XCTAssertTrue([dict getBool:NULL forKey:YES]);
  XCTAssertTrue([dict getBool:&value forKey:YES]);
1512
  XCTAssertEqual(value, YES);
1513 1514
  XCTAssertTrue([dict getBool:NULL forKey:NO]);
  XCTAssertTrue([dict getBool:&value forKey:NO]);
1515 1516
  XCTAssertEqual(value, YES);

1517
  [dict setBool:NO forKey:NO];
1518
  XCTAssertEqual(dict.count, 2U);
1519 1520
  XCTAssertTrue([dict getBool:NULL forKey:YES]);
  XCTAssertTrue([dict getBool:&value forKey:YES]);
1521
  XCTAssertEqual(value, YES);
1522 1523
  XCTAssertTrue([dict getBool:NULL forKey:NO]);
  XCTAssertTrue([dict getBool:&value forKey:NO]);
1524 1525 1526 1527 1528
  XCTAssertEqual(value, NO);

  const BOOL kKeys2[] = { NO, YES };
  const BOOL kValues2[] = { YES, NO };
  GPBBoolBoolDictionary *dict2 =
1529 1530 1531
      [[GPBBoolBoolDictionary alloc] initWithBools:kValues2
                                           forKeys:kKeys2
                                             count:GPBARRAYSIZE(kValues2)];
1532 1533 1534
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);
1535 1536
  XCTAssertTrue([dict getBool:NULL forKey:YES]);
  XCTAssertTrue([dict getBool:&value forKey:YES]);
1537
  XCTAssertEqual(value, NO);
1538 1539
  XCTAssertTrue([dict getBool:NULL forKey:NO]);
  XCTAssertTrue([dict getBool:&value forKey:NO]);
1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561
  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);
1562 1563
  XCTAssertFalse([dict getFloat:NULL forKey:YES]);
  [dict enumerateKeysAndFloatsUsingBlock:^(BOOL aKey, float aValue, BOOL *stop) {
1564 1565 1566 1567 1568 1569 1570
    #pragma unused(aKey, aValue, stop)
    XCTFail(@"Shouldn't get here!");
  }];
  [dict release];
}

- (void)testOne {
1571
  GPBBoolFloatDictionary *dict = [GPBBoolFloatDictionary dictionaryWithFloat:500.f forKey:YES];
1572 1573 1574
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 1U);
  float value;
1575 1576
  XCTAssertTrue([dict getFloat:NULL forKey:YES]);
  XCTAssertTrue([dict getFloat:&value forKey:YES]);
1577
  XCTAssertEqual(value, 500.f);
1578 1579
  XCTAssertFalse([dict getFloat:NULL forKey:NO]);
  [dict enumerateKeysAndFloatsUsingBlock:^(BOOL aKey, float aValue, BOOL *stop) {
1580 1581 1582 1583 1584 1585 1586 1587 1588 1589
    XCTAssertEqual(aKey, YES);
    XCTAssertEqual(aValue, 500.f);
    XCTAssertNotEqual(stop, NULL);
  }];
}

- (void)testBasics {
  const BOOL kKeys[] = { YES, NO };
  const float kValues[] = { 500.f, 501.f };
  GPBBoolFloatDictionary *dict =
1590
      [[GPBBoolFloatDictionary alloc] initWithFloats:kValues
1591 1592 1593 1594 1595
                                             forKeys:kKeys
                                               count:GPBARRAYSIZE(kValues)];
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);
  float value;
1596 1597
  XCTAssertTrue([dict getFloat:NULL forKey:YES]);
  XCTAssertTrue([dict getFloat:&value forKey:YES]);
1598
  XCTAssertEqual(value, 500.f);
1599 1600
  XCTAssertTrue([dict getFloat:NULL forKey:NO]);
  XCTAssertTrue([dict getFloat:&value forKey:NO]);
1601 1602 1603 1604 1605
  XCTAssertEqual(value, 501.f);

  __block NSUInteger idx = 0;
  BOOL *seenKeys = malloc(2 * sizeof(BOOL));
  float *seenValues = malloc(2 * sizeof(float));
1606
  [dict enumerateKeysAndFloatsUsingBlock:^(BOOL aKey, float aValue, BOOL *stop) {
1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627
    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;
1628
  [dict enumerateKeysAndFloatsUsingBlock:^(BOOL aKey, float aValue, BOOL *stop) {
1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643
    #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 =
1644
      [[GPBBoolFloatDictionary alloc] initWithFloats:kValues1
1645 1646 1647 1648
                                             forKeys:kKeys1
                                               count:GPBARRAYSIZE(kValues1)];
  XCTAssertNotNil(dict1);
  GPBBoolFloatDictionary *dict1prime =
1649
      [[GPBBoolFloatDictionary alloc] initWithFloats:kValues1
1650 1651 1652 1653
                                             forKeys:kKeys1
                                               count:GPBARRAYSIZE(kValues1)];
  XCTAssertNotNil(dict1prime);
  GPBBoolFloatDictionary *dict2 =
1654
      [[GPBBoolFloatDictionary alloc] initWithFloats:kValues2
1655 1656 1657 1658
                                             forKeys:kKeys1
                                               count:GPBARRAYSIZE(kValues2)];
  XCTAssertNotNil(dict2);
  GPBBoolFloatDictionary *dict3 =
1659
      [[GPBBoolFloatDictionary alloc] initWithFloats:kValues1
1660 1661 1662 1663
                                             forKeys:kKeys2
                                               count:GPBARRAYSIZE(kValues1)];
  XCTAssertNotNil(dict3);
  GPBBoolFloatDictionary *dict4 =
1664
      [[GPBBoolFloatDictionary alloc] initWithFloats:kValues3
1665 1666 1667 1668 1669 1670 1671 1672 1673 1674
                                             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]);

1675
  // 2 is same keys, different values; not equal.
1676 1677
  XCTAssertNotEqualObjects(dict1, dict2);

1678
  // 3 is different keys, same values; not equal.
1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694
  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 =
1695
      [[GPBBoolFloatDictionary alloc] initWithFloats:kValues
1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715
                                             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 =
1716
      [[GPBBoolFloatDictionary alloc] initWithFloats:kValues
1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735
                                             forKeys:kKeys
                                               count:GPBARRAYSIZE(kValues)];
  XCTAssertNotNil(dict);

  GPBBoolFloatDictionary *dict2 =
      [GPBBoolFloatDictionary dictionaryWithDictionary:dict];
  XCTAssertNotNil(dict2);

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

- (void)testAdds {
  GPBBoolFloatDictionary *dict = [GPBBoolFloatDictionary dictionary];
  XCTAssertNotNil(dict);

  XCTAssertEqual(dict.count, 0U);
1736
  [dict setFloat:500.f forKey:YES];
1737 1738 1739 1740 1741
  XCTAssertEqual(dict.count, 1U);

  const BOOL kKeys[] = { NO };
  const float kValues[] = { 501.f };
  GPBBoolFloatDictionary *dict2 =
1742
      [[GPBBoolFloatDictionary alloc] initWithFloats:kValues
1743 1744 1745 1746 1747 1748 1749
                                             forKeys:kKeys
                                               count:GPBARRAYSIZE(kValues)];
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);

  float value;
1750 1751
  XCTAssertTrue([dict getFloat:NULL forKey:YES]);
  XCTAssertTrue([dict getFloat:&value forKey:YES]);
1752
  XCTAssertEqual(value, 500.f);
1753 1754
  XCTAssertTrue([dict getFloat:NULL forKey:NO]);
  XCTAssertTrue([dict getFloat:&value forKey:NO]);
1755 1756 1757 1758 1759 1760 1761 1762
  XCTAssertEqual(value, 501.f);
  [dict2 release];
}

- (void)testRemove {
  const BOOL kKeys[] = { YES, NO};
  const float kValues[] = { 500.f, 501.f };
  GPBBoolFloatDictionary *dict =
1763
      [[GPBBoolFloatDictionary alloc] initWithFloats:kValues
1764 1765 1766 1767 1768
                                      forKeys:kKeys
                                        count:GPBARRAYSIZE(kValues)];
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);

1769
  [dict removeFloatForKey:NO];
1770 1771
  XCTAssertEqual(dict.count, 1U);
  float value;
1772 1773
  XCTAssertTrue([dict getFloat:NULL forKey:YES]);
  XCTAssertTrue([dict getFloat:&value forKey:YES]);
1774
  XCTAssertEqual(value, 500.f);
1775
  XCTAssertFalse([dict getFloat:NULL forKey:NO]);
1776 1777

  // Remove again does nothing.
1778
  [dict removeFloatForKey:NO];
1779
  XCTAssertEqual(dict.count, 1U);
1780 1781
  XCTAssertTrue([dict getFloat:NULL forKey:YES]);
  XCTAssertTrue([dict getFloat:&value forKey:YES]);
1782
  XCTAssertEqual(value, 500.f);
1783
  XCTAssertFalse([dict getFloat:NULL forKey:NO]);
1784 1785 1786

  [dict removeAll];
  XCTAssertEqual(dict.count, 0U);
1787 1788
  XCTAssertFalse([dict getFloat:NULL forKey:YES]);
  XCTAssertFalse([dict getFloat:NULL forKey:NO]);
1789 1790 1791 1792 1793 1794 1795
  [dict release];
}

- (void)testInplaceMutation {
  const BOOL kKeys[] = { YES, NO };
  const float kValues[] = { 500.f, 501.f };
  GPBBoolFloatDictionary *dict =
1796 1797 1798
      [[GPBBoolFloatDictionary alloc] initWithFloats:kValues
                                             forKeys:kKeys
                                               count:GPBARRAYSIZE(kValues)];
1799 1800 1801
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);
  float value;
1802 1803
  XCTAssertTrue([dict getFloat:NULL forKey:YES]);
  XCTAssertTrue([dict getFloat:&value forKey:YES]);
1804
  XCTAssertEqual(value, 500.f);
1805 1806
  XCTAssertTrue([dict getFloat:NULL forKey:NO]);
  XCTAssertTrue([dict getFloat:&value forKey:NO]);
1807 1808
  XCTAssertEqual(value, 501.f);

1809
  [dict setFloat:501.f forKey:YES];
1810
  XCTAssertEqual(dict.count, 2U);
1811 1812
  XCTAssertTrue([dict getFloat:NULL forKey:YES]);
  XCTAssertTrue([dict getFloat:&value forKey:YES]);
1813
  XCTAssertEqual(value, 501.f);
1814 1815
  XCTAssertTrue([dict getFloat:NULL forKey:NO]);
  XCTAssertTrue([dict getFloat:&value forKey:NO]);
1816 1817
  XCTAssertEqual(value, 501.f);

1818
  [dict setFloat:500.f forKey:NO];
1819
  XCTAssertEqual(dict.count, 2U);
1820 1821
  XCTAssertTrue([dict getFloat:NULL forKey:YES]);
  XCTAssertTrue([dict getFloat:&value forKey:YES]);
1822
  XCTAssertEqual(value, 501.f);
1823 1824
  XCTAssertTrue([dict getFloat:NULL forKey:NO]);
  XCTAssertTrue([dict getFloat:&value forKey:NO]);
1825 1826 1827 1828 1829
  XCTAssertEqual(value, 500.f);

  const BOOL kKeys2[] = { NO, YES };
  const float kValues2[] = { 501.f, 500.f };
  GPBBoolFloatDictionary *dict2 =
1830
      [[GPBBoolFloatDictionary alloc] initWithFloats:kValues2
1831 1832 1833 1834 1835
                                             forKeys:kKeys2
                                               count:GPBARRAYSIZE(kValues2)];
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);
1836 1837
  XCTAssertTrue([dict getFloat:NULL forKey:YES]);
  XCTAssertTrue([dict getFloat:&value forKey:YES]);
1838
  XCTAssertEqual(value, 500.f);
1839 1840
  XCTAssertTrue([dict getFloat:NULL forKey:NO]);
  XCTAssertTrue([dict getFloat:&value forKey:NO]);
1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862
  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);
1863 1864
  XCTAssertFalse([dict getDouble:NULL forKey:YES]);
  [dict enumerateKeysAndDoublesUsingBlock:^(BOOL aKey, double aValue, BOOL *stop) {
1865 1866 1867 1868 1869 1870 1871
    #pragma unused(aKey, aValue, stop)
    XCTFail(@"Shouldn't get here!");
  }];
  [dict release];
}

- (void)testOne {
1872
  GPBBoolDoubleDictionary *dict = [GPBBoolDoubleDictionary dictionaryWithDouble:600. forKey:YES];
1873 1874 1875
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 1U);
  double value;
1876 1877
  XCTAssertTrue([dict getDouble:NULL forKey:YES]);
  XCTAssertTrue([dict getDouble:&value forKey:YES]);
1878
  XCTAssertEqual(value, 600.);
1879 1880
  XCTAssertFalse([dict getDouble:NULL forKey:NO]);
  [dict enumerateKeysAndDoublesUsingBlock:^(BOOL aKey, double aValue, BOOL *stop) {
1881 1882 1883 1884 1885 1886 1887 1888 1889 1890
    XCTAssertEqual(aKey, YES);
    XCTAssertEqual(aValue, 600.);
    XCTAssertNotEqual(stop, NULL);
  }];
}

- (void)testBasics {
  const BOOL kKeys[] = { YES, NO };
  const double kValues[] = { 600., 601. };
  GPBBoolDoubleDictionary *dict =
1891 1892 1893
      [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kValues)];
1894 1895 1896
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);
  double value;
1897 1898
  XCTAssertTrue([dict getDouble:NULL forKey:YES]);
  XCTAssertTrue([dict getDouble:&value forKey:YES]);
1899
  XCTAssertEqual(value, 600.);
1900 1901
  XCTAssertTrue([dict getDouble:NULL forKey:NO]);
  XCTAssertTrue([dict getDouble:&value forKey:NO]);
1902 1903 1904 1905 1906
  XCTAssertEqual(value, 601.);

  __block NSUInteger idx = 0;
  BOOL *seenKeys = malloc(2 * sizeof(BOOL));
  double *seenValues = malloc(2 * sizeof(double));
1907
  [dict enumerateKeysAndDoublesUsingBlock:^(BOOL aKey, double aValue, BOOL *stop) {
1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928
    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;
1929
  [dict enumerateKeysAndDoublesUsingBlock:^(BOOL aKey, double aValue, BOOL *stop) {
1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944
    #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 =
1945 1946 1947
      [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues1
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kValues1)];
1948 1949
  XCTAssertNotNil(dict1);
  GPBBoolDoubleDictionary *dict1prime =
1950 1951 1952
      [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues1
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kValues1)];
1953 1954
  XCTAssertNotNil(dict1prime);
  GPBBoolDoubleDictionary *dict2 =
1955 1956 1957
      [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues2
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kValues2)];
1958 1959
  XCTAssertNotNil(dict2);
  GPBBoolDoubleDictionary *dict3 =
1960 1961 1962
      [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues1
                                               forKeys:kKeys2
                                                 count:GPBARRAYSIZE(kValues1)];
1963 1964
  XCTAssertNotNil(dict3);
  GPBBoolDoubleDictionary *dict4 =
1965 1966 1967
      [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues3
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kValues3)];
1968 1969 1970 1971 1972 1973 1974 1975
  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]);

1976
  // 2 is same keys, different values; not equal.
1977 1978
  XCTAssertNotEqualObjects(dict1, dict2);

1979
  // 3 is different keys, same values; not equal.
1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995
  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 =
1996 1997 1998
      [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kValues)];
1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016
  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 =
2017 2018 2019
      [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kValues)];
2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036
  XCTAssertNotNil(dict);

  GPBBoolDoubleDictionary *dict2 =
      [GPBBoolDoubleDictionary dictionaryWithDictionary:dict];
  XCTAssertNotNil(dict2);

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

- (void)testAdds {
  GPBBoolDoubleDictionary *dict = [GPBBoolDoubleDictionary dictionary];
  XCTAssertNotNil(dict);

  XCTAssertEqual(dict.count, 0U);
2037
  [dict setDouble:600. forKey:YES];
2038 2039 2040 2041 2042
  XCTAssertEqual(dict.count, 1U);

  const BOOL kKeys[] = { NO };
  const double kValues[] = { 601. };
  GPBBoolDoubleDictionary *dict2 =
2043 2044 2045
      [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kValues)];
2046 2047 2048 2049 2050
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);

  double value;
2051 2052
  XCTAssertTrue([dict getDouble:NULL forKey:YES]);
  XCTAssertTrue([dict getDouble:&value forKey:YES]);
2053
  XCTAssertEqual(value, 600.);
2054 2055
  XCTAssertTrue([dict getDouble:NULL forKey:NO]);
  XCTAssertTrue([dict getDouble:&value forKey:NO]);
2056 2057 2058 2059 2060 2061 2062 2063
  XCTAssertEqual(value, 601.);
  [dict2 release];
}

- (void)testRemove {
  const BOOL kKeys[] = { YES, NO};
  const double kValues[] = { 600., 601. };
  GPBBoolDoubleDictionary *dict =
2064 2065 2066
      [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues
                                        forKeys:kKeys
                                          count:GPBARRAYSIZE(kValues)];
2067 2068 2069
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);

2070
  [dict removeDoubleForKey:NO];
2071 2072
  XCTAssertEqual(dict.count, 1U);
  double value;
2073 2074
  XCTAssertTrue([dict getDouble:NULL forKey:YES]);
  XCTAssertTrue([dict getDouble:&value forKey:YES]);
2075
  XCTAssertEqual(value, 600.);
2076
  XCTAssertFalse([dict getDouble:NULL forKey:NO]);
2077 2078

  // Remove again does nothing.
2079
  [dict removeDoubleForKey:NO];
2080
  XCTAssertEqual(dict.count, 1U);
2081 2082
  XCTAssertTrue([dict getDouble:NULL forKey:YES]);
  XCTAssertTrue([dict getDouble:&value forKey:YES]);
2083
  XCTAssertEqual(value, 600.);
2084
  XCTAssertFalse([dict getDouble:NULL forKey:NO]);
2085 2086 2087

  [dict removeAll];
  XCTAssertEqual(dict.count, 0U);
2088 2089
  XCTAssertFalse([dict getDouble:NULL forKey:YES]);
  XCTAssertFalse([dict getDouble:NULL forKey:NO]);
2090 2091 2092 2093 2094 2095 2096
  [dict release];
}

- (void)testInplaceMutation {
  const BOOL kKeys[] = { YES, NO };
  const double kValues[] = { 600., 601. };
  GPBBoolDoubleDictionary *dict =
2097 2098 2099
      [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kValues)];
2100 2101 2102
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);
  double value;
2103 2104
  XCTAssertTrue([dict getDouble:NULL forKey:YES]);
  XCTAssertTrue([dict getDouble:&value forKey:YES]);
2105
  XCTAssertEqual(value, 600.);
2106 2107
  XCTAssertTrue([dict getDouble:NULL forKey:NO]);
  XCTAssertTrue([dict getDouble:&value forKey:NO]);
2108 2109
  XCTAssertEqual(value, 601.);

2110
  [dict setDouble:601. forKey:YES];
2111
  XCTAssertEqual(dict.count, 2U);
2112 2113
  XCTAssertTrue([dict getDouble:NULL forKey:YES]);
  XCTAssertTrue([dict getDouble:&value forKey:YES]);
2114
  XCTAssertEqual(value, 601.);
2115 2116
  XCTAssertTrue([dict getDouble:NULL forKey:NO]);
  XCTAssertTrue([dict getDouble:&value forKey:NO]);
2117 2118
  XCTAssertEqual(value, 601.);

2119
  [dict setDouble:600. forKey:NO];
2120
  XCTAssertEqual(dict.count, 2U);
2121 2122
  XCTAssertTrue([dict getDouble:NULL forKey:YES]);
  XCTAssertTrue([dict getDouble:&value forKey:YES]);
2123
  XCTAssertEqual(value, 601.);
2124 2125
  XCTAssertTrue([dict getDouble:NULL forKey:NO]);
  XCTAssertTrue([dict getDouble:&value forKey:NO]);
2126 2127 2128 2129 2130
  XCTAssertEqual(value, 600.);

  const BOOL kKeys2[] = { NO, YES };
  const double kValues2[] = { 601., 600. };
  GPBBoolDoubleDictionary *dict2 =
2131 2132 2133
      [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues2
                                               forKeys:kKeys2
                                                 count:GPBARRAYSIZE(kValues2)];
2134 2135 2136
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);
2137 2138
  XCTAssertTrue([dict getDouble:NULL forKey:YES]);
  XCTAssertTrue([dict getDouble:&value forKey:YES]);
2139
  XCTAssertEqual(value, 600.);
2140 2141
  XCTAssertTrue([dict getDouble:NULL forKey:NO]);
  XCTAssertTrue([dict getDouble:&value forKey:NO]);
2142 2143 2144 2145 2146 2147 2148 2149
  XCTAssertEqual(value, 601.);

  [dict2 release];
  [dict release];
}

@end

2150
//%PDDM-EXPAND TESTS_FOR_BOOL_KEY_OBJECT_VALUE(Object, NSString*, @"abc", @"def")
2151 2152 2153 2154 2155 2156 2157 2158 2159 2160
// This block of code is generated, do not edit it directly.

#pragma mark - Bool -> Object

@interface GPBBoolObjectDictionaryTests : XCTestCase
@end

@implementation GPBBoolObjectDictionaryTests

- (void)testEmpty {
2161
  GPBBoolObjectDictionary<NSString*> *dict = [[GPBBoolObjectDictionary alloc] init];
2162 2163
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 0U);
2164
  XCTAssertNil([dict objectForKey:YES]);
2165
  [dict enumerateKeysAndObjectsUsingBlock:^(BOOL aKey, NSString* aObject, BOOL *stop) {
2166
    #pragma unused(aKey, aObject, stop)
2167 2168 2169 2170 2171 2172
    XCTFail(@"Shouldn't get here!");
  }];
  [dict release];
}

- (void)testOne {
2173
  GPBBoolObjectDictionary<NSString*> *dict = [GPBBoolObjectDictionary dictionaryWithObject:@"abc" forKey:YES];
2174 2175
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 1U);
2176 2177
  XCTAssertEqualObjects([dict objectForKey:YES], @"abc");
  XCTAssertNil([dict objectForKey:NO]);
2178
  [dict enumerateKeysAndObjectsUsingBlock:^(BOOL aKey, NSString* aObject, BOOL *stop) {
2179
    XCTAssertEqual(aKey, YES);
2180
    XCTAssertEqualObjects(aObject, @"abc");
2181 2182 2183 2184 2185 2186
    XCTAssertNotEqual(stop, NULL);
  }];
}

- (void)testBasics {
  const BOOL kKeys[] = { YES, NO };
2187 2188
  const NSString* kObjects[] = { @"abc", @"def" };
  GPBBoolObjectDictionary<NSString*> *dict =
2189 2190 2191
      [[GPBBoolObjectDictionary alloc] initWithObjects:kObjects
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kObjects)];
2192 2193
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);
2194 2195
  XCTAssertEqualObjects([dict objectForKey:YES], @"abc");
  XCTAssertEqualObjects([dict objectForKey:NO], @"def");
2196 2197 2198

  __block NSUInteger idx = 0;
  BOOL *seenKeys = malloc(2 * sizeof(BOOL));
2199 2200
  NSString* *seenObjects = malloc(2 * sizeof(NSString*));
  [dict enumerateKeysAndObjectsUsingBlock:^(BOOL aKey, NSString* aObject, BOOL *stop) {
2201 2202
    XCTAssertLessThan(idx, 2U);
    seenKeys[idx] = aKey;
2203
    seenObjects[idx] = aObject;
2204 2205 2206 2207 2208 2209 2210 2211
    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;
2212
        XCTAssertEqualObjects(kObjects[i], seenObjects[j], @"i = %d, j = %d", i, j);
2213 2214 2215 2216 2217
      }
    }
    XCTAssertTrue(foundKey, @"i = %d", i);
  }
  free(seenKeys);
2218
  free(seenObjects);
2219 2220 2221

  // Stopping the enumeration.
  idx = 0;
2222
  [dict enumerateKeysAndObjectsUsingBlock:^(BOOL aKey, NSString* aObject, BOOL *stop) {
2223
    #pragma unused(aKey, aObject)
2224 2225 2226 2227 2228 2229 2230 2231 2232 2233
    if (idx == 0) *stop = YES;
    XCTAssertNotEqual(idx, 2U);
    ++idx;
  }];
  [dict release];
}

- (void)testEquality {
  const BOOL kKeys1[] = { YES, NO };
  const BOOL kKeys2[] = { NO, YES };
2234 2235 2236 2237
  const NSString* kObjects1[] = { @"abc", @"def" };
  const NSString* kObjects2[] = { @"def", @"abc" };
  const NSString* kObjects3[] = { @"def" };
  GPBBoolObjectDictionary<NSString*> *dict1 =
2238 2239 2240
      [[GPBBoolObjectDictionary alloc] initWithObjects:kObjects1
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kObjects1)];
2241
  XCTAssertNotNil(dict1);
2242
  GPBBoolObjectDictionary<NSString*> *dict1prime =
2243 2244 2245
      [[GPBBoolObjectDictionary alloc] initWithObjects:kObjects1
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kObjects1)];
2246
  XCTAssertNotNil(dict1prime);
2247
  GPBBoolObjectDictionary<NSString*> *dict2 =
2248 2249 2250
      [[GPBBoolObjectDictionary alloc] initWithObjects:kObjects2
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kObjects2)];
2251
  XCTAssertNotNil(dict2);
2252
  GPBBoolObjectDictionary<NSString*> *dict3 =
2253 2254 2255
      [[GPBBoolObjectDictionary alloc] initWithObjects:kObjects1
                                               forKeys:kKeys2
                                                 count:GPBARRAYSIZE(kObjects1)];
2256
  XCTAssertNotNil(dict3);
2257
  GPBBoolObjectDictionary<NSString*> *dict4 =
2258 2259 2260
      [[GPBBoolObjectDictionary alloc] initWithObjects:kObjects3
                                               forKeys:kKeys1
                                                 count:GPBARRAYSIZE(kObjects3)];
2261 2262 2263 2264 2265 2266 2267 2268
  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]);

2269
  // 2 is same keys, different objects; not equal.
2270 2271
  XCTAssertNotEqualObjects(dict1, dict2);

2272
  // 3 is different keys, same objects; not equal.
2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286
  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 };
2287 2288
  const NSString* kObjects[] = { @"abc", @"def" };
  GPBBoolObjectDictionary<NSString*> *dict =
2289 2290 2291
      [[GPBBoolObjectDictionary alloc] initWithObjects:kObjects
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kObjects)];
2292 2293
  XCTAssertNotNil(dict);

2294
  GPBBoolObjectDictionary<NSString*> *dict2 = [dict copy];
2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307
  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 };
2308 2309
  const NSString* kObjects[] = { @"abc", @"def" };
  GPBBoolObjectDictionary<NSString*> *dict =
2310 2311 2312
      [[GPBBoolObjectDictionary alloc] initWithObjects:kObjects
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kObjects)];
2313 2314
  XCTAssertNotNil(dict);

2315
  GPBBoolObjectDictionary<NSString*> *dict2 =
2316 2317 2318 2319 2320 2321 2322 2323 2324 2325
      [GPBBoolObjectDictionary dictionaryWithDictionary:dict];
  XCTAssertNotNil(dict2);

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

- (void)testAdds {
2326
  GPBBoolObjectDictionary<NSString*> *dict = [GPBBoolObjectDictionary dictionary];
2327 2328 2329
  XCTAssertNotNil(dict);

  XCTAssertEqual(dict.count, 0U);
2330
  [dict setObject:@"abc" forKey:YES];
2331 2332 2333
  XCTAssertEqual(dict.count, 1U);

  const BOOL kKeys[] = { NO };
2334 2335
  const NSString* kObjects[] = { @"def" };
  GPBBoolObjectDictionary<NSString*> *dict2 =
2336 2337 2338
      [[GPBBoolObjectDictionary alloc] initWithObjects:kObjects
                                               forKeys:kKeys
                                                 count:GPBARRAYSIZE(kObjects)];
2339 2340 2341 2342
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);

2343 2344
  XCTAssertEqualObjects([dict objectForKey:YES], @"abc");
  XCTAssertEqualObjects([dict objectForKey:NO], @"def");
2345 2346 2347 2348 2349
  [dict2 release];
}

- (void)testRemove {
  const BOOL kKeys[] = { YES, NO};
2350 2351
  const NSString* kObjects[] = { @"abc", @"def" };
  GPBBoolObjectDictionary<NSString*> *dict =
2352 2353 2354
      [[GPBBoolObjectDictionary alloc] initWithObjects:kObjects
                                        forKeys:kKeys
                                          count:GPBARRAYSIZE(kObjects)];
2355 2356 2357
  XCTAssertNotNil(dict);
  XCTAssertEqual(dict.count, 2U);

2358
  [dict removeObjectForKey:NO];
2359
  XCTAssertEqual(dict.count, 1U);
2360 2361
  XCTAssertEqualObjects([dict objectForKey:YES], @"abc");
  XCTAssertNil([dict objectForKey:NO]);
2362 2363

  // Remove again does nothing.
2364
  [dict removeObjectForKey:NO];
2365
  XCTAssertEqual(dict.count, 1U);
2366 2367
  XCTAssertEqualObjects([dict objectForKey:YES], @"abc");
  XCTAssertNil([dict objectForKey:NO]);
2368 2369 2370

  [dict removeAll];
  XCTAssertEqual(dict.count, 0U);
2371 2372
  XCTAssertNil([dict objectForKey:YES]);
  XCTAssertNil([dict objectForKey:NO]);
2373 2374 2375 2376 2377
  [dict release];
}

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

2388
  [dict setObject:@"def" forKey:YES];
2389
  XCTAssertEqual(dict.count, 2U);
2390 2391
  XCTAssertEqualObjects([dict objectForKey:YES], @"def");
  XCTAssertEqualObjects([dict objectForKey:NO], @"def");
2392

2393
  [dict setObject:@"abc" forKey:NO];
2394
  XCTAssertEqual(dict.count, 2U);
2395 2396
  XCTAssertEqualObjects([dict objectForKey:YES], @"def");
  XCTAssertEqualObjects([dict objectForKey:NO], @"abc");
2397 2398

  const BOOL kKeys2[] = { NO, YES };
2399 2400
  const NSString* kObjects2[] = { @"def", @"abc" };
  GPBBoolObjectDictionary<NSString*> *dict2 =
2401 2402 2403
      [[GPBBoolObjectDictionary alloc] initWithObjects:kObjects2
                                               forKeys:kKeys2
                                                 count:GPBARRAYSIZE(kObjects2)];
2404 2405 2406
  XCTAssertNotNil(dict2);
  [dict addEntriesFromDictionary:dict2];
  XCTAssertEqual(dict.count, 2U);
2407 2408
  XCTAssertEqualObjects([dict objectForKey:YES], @"abc");
  XCTAssertEqualObjects([dict objectForKey:NO], @"def");
2409 2410 2411 2412 2413 2414 2415 2416 2417 2418

  [dict2 release];
  [dict release];
}

@end

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