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