]> git.saurik.com Git - apple/objc4.git/blob - test/foreach.m
objc4-680.tar.gz
[apple/objc4.git] / test / foreach.m
1 // TEST_CFLAGS -framework Foundation
2
3 #include "test.h"
4 #import <Foundation/Foundation.h>
5
6 /* foreach tester */
7
8 int Errors = 0;
9
10 bool testHandwritten(const char *style, const char *test, const char *message, id collection, NSSet *reference) {
11 unsigned int counter = 0;
12 bool result = true;
13 testprintf("testing: %s %s %s\n", style, test, message);
14 /*
15 for (id elem in collection)
16 if ([reference member:elem]) ++counter;
17 */
18 NSFastEnumerationState state;
19 id __unsafe_unretained buffer[4];
20 state.state = 0;
21 NSUInteger limit = [collection countByEnumeratingWithState:&state objects:buffer count:4];
22 if (limit != 0) {
23 unsigned long mutationsPtr = *state.mutationsPtr;
24 do {
25 unsigned long innerCounter = 0;
26 do {
27 if (mutationsPtr != *state.mutationsPtr) objc_enumerationMutation(collection);
28 id elem = state.itemsPtr[innerCounter++];
29
30 if ([reference member:elem]) ++counter;
31
32 } while (innerCounter < limit);
33 } while ((limit = [collection countByEnumeratingWithState:&state objects:buffer count:4]));
34 }
35
36
37
38 if (counter == [reference count]) {
39 testprintf("success: %s %s %s\n", style, test, message);
40 }
41 else {
42 result = false;
43 printf("** failed: %s %s %s (%d vs %d)\n", style, test, message, counter, (int)[reference count]);
44 ++Errors;
45 }
46 return result;
47 }
48
49 bool testCompiler(const char *style, const char *test, const char *message, id collection, NSSet *reference) {
50 unsigned int counter = 0;
51 bool result = true;
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);
57 }
58 else {
59 result = false;
60 printf("** failed: %s %s %s (%d vs %d)\n", style, test, message, counter, (int)[reference count]);
61 ++Errors;
62 }
63 return result;
64 }
65
66 void testContinue(NSArray *array) {
67 bool broken = false;
68 testprintf("testing: continue statements\n");
69 for (id __unused elem in array) {
70 if ([array count])
71 continue;
72 broken = true;
73 }
74 if (broken) {
75 printf("** continue statement did not work\n");
76 ++Errors;
77 }
78 }
79
80
81 // array is filled with NSNumbers, in order, from 0 - N
82 bool testBreak(unsigned int where, NSArray *array) {
83 PUSH_POOL {
84 unsigned int counter = 0;
85 id enumerator = [array objectEnumerator];
86 for (id __unused elem in enumerator) {
87 if (++counter == where)
88 break;
89 }
90 if (counter != where) {
91 ++Errors;
92 printf("*** break at %d didn't work (actual was %d)\n", where, counter);
93 return false;
94 }
95 for (id __unused elem in enumerator)
96 ++counter;
97 if (counter != [array count]) {
98 ++Errors;
99 printf("*** break at %d didn't finish (actual was %d)\n", where, counter);
100 return false;
101 }
102 } POP_POOL;
103 return true;
104 }
105
106 bool testBreaks(NSArray *array) {
107 bool result = true;
108 testprintf("testing breaks\n");
109 unsigned int counter = 0;
110 for (counter = 1; counter < [array count]; ++counter) {
111 result = testBreak(counter, array) && result;
112 }
113 return result;
114 }
115
116 bool testCompleteness(const char *test, const char *message, id collection, NSSet *reference) {
117 bool result = true;
118 result = result && testHandwritten("handwritten", test, message, collection, reference);
119 result = result && testCompiler("compiler", test, message, collection, reference);
120 return result;
121 }
122
123 bool testEnumerator(const char *test, const char *message, id collection, NSSet *reference) {
124 bool result = true;
125 result = result && testHandwritten("handwritten", test, message, [collection objectEnumerator], reference);
126 result = result && testCompiler("compiler", test, message, [collection objectEnumerator], reference);
127 return result;
128 }
129
130 NSMutableSet *ReferenceSet = nil;
131 NSMutableArray *ReferenceArray = nil;
132
133 void makeReferences(int n) {
134 if (!ReferenceSet) {
135 int i;
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];
142 RELEASE_VAR(number);
143 }
144 }
145 }
146
147 void testCollections(const char *test, NSArray *array, NSSet *set) {
148 PUSH_POOL {
149 id collection;
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);
156 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);
162 } POP_POOL;
163 }
164
165 void testInnerDecl(const char *test, const char *message, id collection) {
166 unsigned int counter = 0;
167 for (id __unused x in collection)
168 ++counter;
169 if (counter != [collection count]) {
170 printf("** failed: %s %s\n", test, message);
171 ++Errors;
172 }
173 }
174
175
176 void testOuterDecl(const char *test, const char *message, id collection) {
177 unsigned int counter = 0;
178 id x;
179 for (x in collection)
180 ++counter;
181 if (counter != [collection count]) {
182 printf("** failed: %s %s\n", test, message);
183 ++Errors;
184 }
185 }
186 void testInnerExpression(const char *test, const char *message, id collection) {
187 unsigned int counter = 0;
188 for (id __unused x in [collection self])
189 ++counter;
190 if (counter != [collection count]) {
191 printf("** failed: %s %s\n", test, message);
192 ++Errors;
193 }
194 }
195 void testOuterExpression(const char *test, const char *message, id collection) {
196 unsigned int counter = 0;
197 id x;
198 for (x in [collection self])
199 ++counter;
200 if (counter != [collection count]) {
201 printf("** failed: %s %s\n", test, message);
202 ++Errors;
203 }
204 }
205
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);
211 }
212
213
214 int main() {
215 PUSH_POOL {
216 testCollections("nil", nil, nil);
217 testCollections("empty", [NSArray array], [NSSet set]);
218 makeReferences(100);
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);
225 } POP_POOL;
226 exit(Errors);
227 }