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