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