]>
Commit | Line | Data |
---|---|---|
13ba007e A |
1 | // See instructions in weak.h |
2 | ||
3 | #include "test.h" | |
4 | #include "weak.h" | |
5 | ||
6 | // Subclass of superclass that isn't there | |
7 | @interface MyMissingSuper : MissingSuper | |
8 | +(int) method; | |
9 | @end | |
10 | @implementation MyMissingSuper | |
11 | +(int) method { return 1+[super method]; } | |
12 | +(void) load { state++; } | |
13 | @end | |
14 | ||
15 | // Subclass of subclass of superclass that isn't there | |
16 | @interface MyMissingSub : MyMissingSuper | |
17 | +(int) method; | |
18 | @end | |
19 | @implementation MyMissingSub | |
20 | +(int) method { return 1+[super method]; } | |
21 | +(void) load { state++; } | |
22 | @end | |
23 | ||
24 | // Subclass of real superclass | |
25 | @interface MyNotMissingSuper : NotMissingSuper | |
26 | +(int) method; | |
27 | @end | |
28 | @implementation MyNotMissingSuper | |
29 | +(int) method { return 1+[super method]; } | |
30 | +(void) load { state++; } | |
31 | @end | |
32 | ||
33 | // Subclass of subclass of superclass that isn't there | |
34 | @interface MyNotMissingSub : MyNotMissingSuper | |
35 | +(int) method; | |
36 | @end | |
37 | @implementation MyNotMissingSub | |
38 | +(int) method { return 1+[super method]; } | |
39 | +(void) load { state++; } | |
40 | @end | |
41 | ||
42 | // Categories on all of the above | |
43 | @interface MissingRoot (MissingRootExtras) | |
44 | +(void)load; | |
45 | +(int) cat_method; | |
46 | @end | |
47 | @implementation MissingRoot (MissingRootExtras) | |
48 | +(void)load { state++; } | |
49 | +(int) cat_method { return 40; } | |
50 | @end | |
51 | ||
52 | @interface MissingSuper (MissingSuperExtras) | |
53 | +(void)load; | |
54 | +(int) cat_method; | |
55 | @end | |
56 | @implementation MissingSuper (MissingSuperExtras) | |
57 | +(void)load { state++; } | |
58 | +(int) cat_method { return 1+[super cat_method]; } | |
59 | @end | |
60 | ||
61 | @interface MyMissingSuper (MyMissingSuperExtras) | |
62 | +(void)load; | |
63 | +(int) cat_method; | |
64 | @end | |
65 | @implementation MyMissingSuper (MyMissingSuperExtras) | |
66 | +(void)load { state++; } | |
67 | +(int) cat_method { return 1+[super cat_method]; } | |
68 | @end | |
69 | ||
70 | @interface MyMissingSub (MyMissingSubExtras) | |
71 | +(void)load; | |
72 | +(int) cat_method; | |
73 | @end | |
74 | @implementation MyMissingSub (MyMissingSubExtras) | |
75 | +(void)load { state++; } | |
76 | +(int) cat_method { return 1+[super cat_method]; } | |
77 | @end | |
78 | ||
79 | ||
80 | @interface NotMissingRoot (NotMissingRootExtras) | |
81 | +(void)load; | |
82 | +(int) cat_method; | |
83 | @end | |
84 | @implementation NotMissingRoot (NotMissingRootExtras) | |
85 | +(void)load { state++; } | |
86 | +(int) cat_method { return 30; } | |
87 | @end | |
88 | ||
89 | @interface NotMissingSuper (NotMissingSuperExtras) | |
90 | +(void)load; | |
91 | +(int) cat_method; | |
92 | @end | |
93 | @implementation NotMissingSuper (NotMissingSuperExtras) | |
94 | +(void)load { state++; } | |
95 | +(int) cat_method { return 1+[super cat_method]; } | |
96 | @end | |
97 | ||
98 | @interface MyNotMissingSuper (MyNotMissingSuperExtras) | |
99 | +(void)load; | |
100 | +(int) cat_method; | |
101 | @end | |
102 | @implementation MyNotMissingSuper (MyNotMissingSuperExtras) | |
103 | +(void)load { state++; } | |
104 | +(int) cat_method { return 1+[super cat_method]; } | |
105 | @end | |
106 | ||
107 | @interface MyNotMissingSub (MyNotMissingSubExtras) | |
108 | +(void)load; | |
109 | +(int) cat_method; | |
110 | @end | |
111 | @implementation MyNotMissingSub (MyNotMissingSubExtras) | |
112 | +(void)load { state++; } | |
113 | +(int) cat_method { return 1+[super cat_method]; } | |
114 | @end | |
115 | ||
116 | ||
117 | #if WEAK_FRAMEWORK | |
118 | # define TESTIVAR(cond) testassert(cond) | |
119 | #else | |
120 | # define TESTIVAR(cond) /* rdar */ | |
121 | #endif | |
122 | ||
123 | static BOOL classInList(__unsafe_unretained Class classes[], const char *name) | |
124 | { | |
125 | for (int i = 0; classes[i] != nil; i++) { | |
126 | if (0 == strcmp(class_getName(classes[i]), name)) return YES; | |
127 | } | |
128 | return NO; | |
129 | } | |
130 | ||
131 | static BOOL classInNameList(const char **names, const char *name) | |
132 | { | |
133 | const char **cp; | |
134 | for (cp = names; *cp; cp++) { | |
135 | if (0 == strcmp(*cp, name)) return YES; | |
136 | } | |
137 | return NO; | |
138 | } | |
139 | ||
140 | int main(int argc __unused, char **argv) | |
141 | { | |
142 | BOOL weakMissing; | |
143 | if (strstr(argv[0], "-not-missing.exe")) { | |
144 | weakMissing = NO; | |
145 | } else if (strstr(argv[0], "-missing.exe")) { | |
146 | weakMissing = YES; | |
147 | } else { | |
148 | fail("executable name must be weak*-missing.exe or weak*-not-missing.exe"); | |
149 | } | |
150 | ||
151 | // class and category +load methods | |
152 | if (weakMissing) testassert(state == 8); | |
153 | else testassert(state == 16); | |
154 | state = 0; | |
155 | ||
156 | // classes | |
157 | testassert([NotMissingRoot class]); | |
158 | testassert([NotMissingSuper class]); | |
159 | testassert([MyNotMissingSuper class]); | |
160 | testassert([MyNotMissingSub class]); | |
161 | if (weakMissing) { | |
162 | testassert([MissingRoot class] == nil); | |
163 | testassert([MissingSuper class] == nil); | |
164 | testassert([MyMissingSuper class] == nil); | |
165 | testassert([MyMissingSub class] == nil); | |
166 | } else { | |
167 | testassert([MissingRoot class]); | |
168 | testassert([MissingSuper class]); | |
169 | testassert([MyMissingSuper class]); | |
170 | testassert([MyMissingSub class]); | |
171 | } | |
172 | ||
173 | // objc_getClass | |
174 | testassert(objc_getClass("NotMissingRoot")); | |
175 | testassert(objc_getClass("NotMissingSuper")); | |
176 | testassert(objc_getClass("MyNotMissingSuper")); | |
177 | testassert(objc_getClass("MyNotMissingSub")); | |
178 | if (weakMissing) { | |
179 | testassert(objc_getClass("MissingRoot") == nil); | |
180 | testassert(objc_getClass("MissingSuper") == nil); | |
181 | testassert(objc_getClass("MyMissingSuper") == nil); | |
182 | testassert(objc_getClass("MyMissingSub") == nil); | |
183 | } else { | |
184 | testassert(objc_getClass("MissingRoot")); | |
185 | testassert(objc_getClass("MissingSuper")); | |
186 | testassert(objc_getClass("MyMissingSuper")); | |
187 | testassert(objc_getClass("MyMissingSub")); | |
188 | } | |
189 | ||
190 | // class list | |
191 | union { | |
192 | Class *c; | |
193 | void *v; | |
194 | } classes; | |
195 | classes.c = objc_copyClassList(NULL); | |
196 | testassert(classInList(classes.c, "NotMissingRoot")); | |
197 | testassert(classInList(classes.c, "NotMissingSuper")); | |
198 | testassert(classInList(classes.c, "MyNotMissingSuper")); | |
199 | testassert(classInList(classes.c, "MyNotMissingSub")); | |
200 | if (weakMissing) { | |
201 | testassert(! classInList(classes.c, "MissingRoot")); | |
202 | testassert(! classInList(classes.c, "MissingSuper")); | |
203 | testassert(! classInList(classes.c, "MyMissingSuper")); | |
204 | testassert(! classInList(classes.c, "MyMissingSub")); | |
205 | } else { | |
206 | testassert(classInList(classes.c, "MissingRoot")); | |
207 | testassert(classInList(classes.c, "MissingSuper")); | |
208 | testassert(classInList(classes.c, "MyMissingSuper")); | |
209 | testassert(classInList(classes.c, "MyMissingSub")); | |
210 | } | |
211 | free(classes.v); | |
212 | ||
213 | // class name list | |
214 | const char *image = class_getImageName(objc_getClass("NotMissingRoot")); | |
215 | testassert(image); | |
216 | const char **names = objc_copyClassNamesForImage(image, NULL); | |
217 | testassert(names); | |
218 | testassert(classInNameList(names, "NotMissingRoot")); | |
219 | testassert(classInNameList(names, "NotMissingSuper")); | |
220 | if (weakMissing) { | |
221 | testassert(! classInNameList(names, "MissingRoot")); | |
222 | testassert(! classInNameList(names, "MissingSuper")); | |
223 | } else { | |
224 | testassert(classInNameList(names, "MissingRoot")); | |
225 | testassert(classInNameList(names, "MissingSuper")); | |
226 | } | |
227 | free(names); | |
228 | ||
229 | image = class_getImageName(objc_getClass("MyNotMissingSub")); | |
230 | testassert(image); | |
231 | names = objc_copyClassNamesForImage(image, NULL); | |
232 | testassert(names); | |
233 | testassert(classInNameList(names, "MyNotMissingSuper")); | |
234 | testassert(classInNameList(names, "MyNotMissingSub")); | |
235 | if (weakMissing) { | |
236 | testassert(! classInNameList(names, "MyMissingSuper")); | |
237 | testassert(! classInNameList(names, "MyMissingSub")); | |
238 | } else { | |
239 | testassert(classInNameList(names, "MyMissingSuper")); | |
240 | testassert(classInNameList(names, "MyMissingSub")); | |
241 | } | |
242 | free(names); | |
243 | ||
244 | // methods | |
245 | testassert(20 == [NotMissingRoot method]); | |
246 | testassert(21 == [NotMissingSuper method]); | |
247 | testassert(22 == [MyNotMissingSuper method]); | |
248 | testassert(23 == [MyNotMissingSub method]); | |
249 | if (weakMissing) { | |
250 | testassert(0 == [MissingRoot method]); | |
251 | testassert(0 == [MissingSuper method]); | |
252 | testassert(0 == [MyMissingSuper method]); | |
253 | testassert(0 == [MyMissingSub method]); | |
254 | } else { | |
255 | testassert(10 == [MissingRoot method]); | |
256 | testassert(11 == [MissingSuper method]); | |
257 | testassert(12 == [MyMissingSuper method]); | |
258 | testassert(13 == [MyMissingSub method]); | |
259 | } | |
260 | ||
261 | // category methods | |
262 | testassert(30 == [NotMissingRoot cat_method]); | |
263 | testassert(31 == [NotMissingSuper cat_method]); | |
264 | testassert(32 == [MyNotMissingSuper cat_method]); | |
265 | testassert(33 == [MyNotMissingSub cat_method]); | |
266 | if (weakMissing) { | |
267 | testassert(0 == [MissingRoot cat_method]); | |
268 | testassert(0 == [MissingSuper cat_method]); | |
269 | testassert(0 == [MyMissingSuper cat_method]); | |
270 | testassert(0 == [MyMissingSub cat_method]); | |
271 | } else { | |
272 | testassert(40 == [MissingRoot cat_method]); | |
273 | testassert(41 == [MissingSuper cat_method]); | |
274 | testassert(42 == [MyMissingSuper cat_method]); | |
275 | testassert(43 == [MyMissingSub cat_method]); | |
276 | } | |
277 | ||
278 | // allocations and ivars | |
279 | id obj; | |
280 | NotMissingSuper *obj2; | |
281 | MissingSuper *obj3; | |
282 | testassert((obj = [[NotMissingRoot alloc] init])); | |
283 | RELEASE_VAR(obj); | |
284 | testassert((obj2 = [[NotMissingSuper alloc] init])); | |
285 | TESTIVAR(obj2->ivar == 200); | |
286 | RELEASE_VAR(obj2); | |
287 | testassert((obj2 = [[MyNotMissingSuper alloc] init])); | |
288 | TESTIVAR(obj2->ivar == 200); | |
289 | RELEASE_VAR(obj2); | |
290 | testassert((obj2 = [[MyNotMissingSub alloc] init])); | |
291 | TESTIVAR(obj2->ivar == 200); | |
292 | RELEASE_VAR(obj2); | |
293 | if (weakMissing) { | |
294 | testassert([[MissingRoot alloc] init] == nil); | |
295 | testassert([[MissingSuper alloc] init] == nil); | |
296 | testassert([[MyMissingSuper alloc] init] == nil); | |
297 | testassert([[MyMissingSub alloc] init] == nil); | |
298 | } else { | |
299 | testassert((obj = [[MissingRoot alloc] init])); | |
300 | RELEASE_VAR(obj); | |
301 | testassert((obj3 = [[MissingSuper alloc] init])); | |
302 | TESTIVAR(obj3->ivar == 100); | |
303 | RELEASE_VAR(obj3); | |
304 | testassert((obj3 = [[MyMissingSuper alloc] init])); | |
305 | TESTIVAR(obj3->ivar == 100); | |
306 | RELEASE_VAR(obj3); | |
307 | testassert((obj3 = [[MyMissingSub alloc] init])); | |
308 | TESTIVAR(obj3->ivar == 100); | |
309 | RELEASE_VAR(obj3); | |
310 | } | |
311 | ||
312 | *strrchr(argv[0], '.') = 0; | |
313 | succeed(basename(argv[0])); | |
314 | return 0; | |
315 | } | |
316 |