1 // TEST_CFLAGS -framework Foundation
4 #import <Foundation/Foundation.h>
10 bool testHandwritten(const char *style, const char *test, const char *message, id collection, NSSet *reference) {
11 unsigned int counter = 0;
13 testprintf("testing: %s %s %s\n", style, test, message);
15 for (id elem in collection)
16 if ([reference member:elem]) ++counter;
18 NSFastEnumerationState state;
19 id __unsafe_unretained buffer[4];
21 NSUInteger limit = [collection countByEnumeratingWithState:&state objects:buffer count:4];
23 unsigned long mutationsPtr = *state.mutationsPtr;
25 unsigned long innerCounter = 0;
27 if (mutationsPtr != *state.mutationsPtr) objc_enumerationMutation(collection);
28 id elem = state.itemsPtr[innerCounter++];
30 if ([reference member:elem]) ++counter;
32 } while (innerCounter < limit);
33 } while ((limit = [collection countByEnumeratingWithState:&state objects:buffer count:4]));
38 if (counter == [reference count]) {
39 testprintf("success: %s %s %s\n", style, test, message);
43 printf("** failed: %s %s %s (%d vs %d)\n", style, test, message, counter, (int)[reference count]);
49 bool testCompiler(const char *style, const char *test, const char *message, id collection, NSSet *reference) {
50 unsigned int counter = 0;
52 testprintf("testing: %s %s %s\n", style, test, message);
53 for (id elem in collection)
54 if ([reference member:elem]) ++counter;
55 if (counter == [reference count]) {
56 testprintf("success: %s %s %s\n", style, test, message);
60 printf("** failed: %s %s %s (%d vs %d)\n", style, test, message, counter, (int)[reference count]);
66 void testContinue(NSArray *array) {
68 testprintf("testing: continue statements\n");
69 for (id __unused elem in array) {
75 printf("** continue statement did not work\n");
81 // array is filled with NSNumbers, in order, from 0 - N
82 bool testBreak(unsigned int where, NSArray *array) {
84 unsigned int counter = 0;
85 id enumerator = [array objectEnumerator];
86 for (id __unused elem in enumerator) {
87 if (++counter == where)
90 if (counter != where) {
92 printf("*** break at %d didn't work (actual was %d)\n", where, counter);
95 for (id __unused elem in enumerator)
97 if (counter != [array count]) {
99 printf("*** break at %d didn't finish (actual was %d)\n", where, counter);
106 bool testBreaks(NSArray *array) {
108 testprintf("testing breaks\n");
109 unsigned int counter = 0;
110 for (counter = 1; counter < [array count]; ++counter) {
111 result = testBreak(counter, array) && result;
116 bool testCompleteness(const char *test, const char *message, id collection, NSSet *reference) {
118 result = result && testHandwritten("handwritten", test, message, collection, reference);
119 result = result && testCompiler("compiler", test, message, collection, reference);
123 bool testEnumerator(const char *test, const char *message, id collection, NSSet *reference) {
125 result = result && testHandwritten("handwritten", test, message, [collection objectEnumerator], reference);
126 result = result && testCompiler("compiler", test, message, [collection objectEnumerator], reference);
130 NSMutableSet *ReferenceSet = nil;
131 NSMutableArray *ReferenceArray = nil;
133 void makeReferences(int n) {
136 ReferenceSet = [[NSMutableSet alloc] init];
137 ReferenceArray = [[NSMutableArray alloc] init];
138 for (i = 0; i < n; ++i) {
139 NSNumber *number = [[NSNumber alloc] initWithInt:i];
140 [ReferenceSet addObject:number];
141 [ReferenceArray addObject:number];
147 void testCollections(const char *test, NSArray *array, NSSet *set) {
150 collection = [NSMutableArray arrayWithArray:array];
151 testCompleteness(test, "mutable array", collection, set);
152 testEnumerator(test, "mutable array enumerator", collection, set);
153 collection = [NSArray arrayWithArray:array];
154 testCompleteness(test, "immutable array", collection, set);
155 testEnumerator(test, "immutable array enumerator", collection, set);
157 testCompleteness(test, "immutable set", collection, set);
158 testEnumerator(test, "immutable set enumerator", collection, set);
159 collection = [NSMutableSet setWithArray:array];
160 testCompleteness(test, "mutable set", collection, set);
161 testEnumerator(test, "mutable set enumerator", collection, set);
165 void testInnerDecl(const char *test, const char *message, id collection) {
166 unsigned int counter = 0;
167 for (id __unused x in collection)
169 if (counter != [collection count]) {
170 printf("** failed: %s %s\n", test, message);
176 void testOuterDecl(const char *test, const char *message, id collection) {
177 unsigned int counter = 0;
179 for (x in collection)
181 if (counter != [collection count]) {
182 printf("** failed: %s %s\n", test, message);
186 void testInnerExpression(const char *test, const char *message, id collection) {
187 unsigned int counter = 0;
188 for (id __unused x in [collection self])
190 if (counter != [collection count]) {
191 printf("** failed: %s %s\n", test, message);
195 void testOuterExpression(const char *test, const char *message, id collection) {
196 unsigned int counter = 0;
198 for (x in [collection self])
200 if (counter != [collection count]) {
201 printf("** failed: %s %s\n", test, message);
206 void testExpressions(const char *message, id collection) {
207 testInnerDecl("inner", message, collection);
208 testOuterDecl("outer", message, collection);
209 testInnerExpression("outer expression", message, collection);
210 testOuterExpression("outer expression", message, collection);
216 testCollections("nil", nil, nil);
217 testCollections("empty", [NSArray array], [NSSet set]);
219 testCollections("100 item", ReferenceArray, ReferenceSet);
220 testExpressions("array", ReferenceArray);
221 testBreaks(ReferenceArray);
222 testContinue(ReferenceArray);
223 if (Errors == 0) succeed(__FILE__);
224 else fail("foreach %d errors detected\n", Errors);