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