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