4 // Test basic +initialize behavior
5 // * +initialize before class method
6 // * superclass +initialize before subclass +initialize
7 // * subclass inheritance of superclass implementation
8 // * messaging during +initialize
9 // * +initialize provoked by class_getMethodImplementation
10 // * +initialize not provoked by objc_getClass
16 @interface Super0 : TestRoot @end
17 @implementation Super0
19 fail("objc_getClass() must not trigger +initialize");
23 @interface Super : TestRoot @end
26 testprintf("in [Super initialize]\n");
27 testassert(state == 0);
31 fail("[Super method] shouldn't be called");
35 @interface Sub : Super @end
38 testprintf("in [Sub initialize]\n");
39 testassert(state == 1);
43 testprintf("in [Sub method]\n");
44 testassert(state == 2);
50 @interface Super2 : TestRoot @end
51 @interface Sub2 : Super2 @end
53 @implementation Super2
55 if (self == objc_getClass("Sub2")) {
56 testprintf("in [Super2 initialize] of Sub2\n");
57 testassert(state == 1);
59 } else if (self == objc_getClass("Super2")) {
60 testprintf("in [Super2 initialize] of Super2\n");
61 testassert(state == 0);
64 fail("in [Super2 initialize] of unknown class");
68 testprintf("in [Super2 method]\n");
69 testassert(state == 2);
79 @interface Super3 : TestRoot @end
80 @interface Sub3 : Super3 @end
82 @implementation Super3
84 if (self == [Sub3 class]) { // this message triggers [Sub3 initialize]
85 testprintf("in [Super3 initialize] of Sub3\n");
86 testassert(state == 0);
88 } else if (self == [Super3 class]) {
89 testprintf("in [Super3 initialize] of Super3\n");
90 testassert(state == 1);
93 fail("in [Super3 initialize] of unknown class");
97 testprintf("in [Super3 method]\n");
98 testassert(state == 2);
108 @interface Super4 : TestRoot @end
109 @implementation Super4
110 -(void)instanceMethod {
111 testassert(state == 1);
115 testprintf("in [Super4 initialize]\n");
116 testassert(state == 0);
118 id x = [[self alloc] init];
125 @interface Super5 : TestRoot @end
126 @implementation Super5
127 -(void)instanceMethod {
130 testassert(state == 1);
134 testprintf("in [Super5 initialize]\n");
135 testassert(state == 0);
137 class_getMethodImplementation(self, @selector(instanceMethod));
138 // this is the "memoized" case for getNonMetaClass
139 class_getMethodImplementation(object_getClass(self), @selector(classMethod));
145 @interface Super6 : TestRoot @end
146 @interface Sub6 : Super6 @end
147 @implementation Super6
151 testprintf("in [Super6 initialize] (#%d)\n", 1+(int)once);
155 testassert(state == 0);
159 testassert(state == 2);
164 testassert(state == 5);
167 testassert(state == 3);
174 testprintf("in [Sub6 initialize]\n");
175 testassert(state == 1);
178 testassert(state == 4);
184 @interface Super7 : TestRoot @end
185 @interface Sub7 : Super7 @end
186 @implementation Super7
190 testprintf("in [Super7 initialize] (#%d)\n", 1+(int)once);
194 testassert(state == 0);
198 testassert(state == 2);
203 testassert(state == 5);
206 testassert(state == 3);
213 testprintf("in [Sub7 initialize]\n");
214 testassert(state == 1);
217 testassert(state == 4);
227 // objc_getClass() must not +initialize anything
229 objc_getClass("Super0");
230 testassert(state == 0);
232 // initialize superclass, then subclass
235 testassert(state == 3);
237 // check subclass's inheritance of superclass initialize
240 testassert(state == 3);
242 // check subclass method called from superclass initialize
245 testassert(state == 3);
247 // check class_getMethodImplementation (instance method)
249 cls = objc_getClass("Super4");
250 testassert(state == 0);
251 class_getMethodImplementation(cls, @selector(classMethod));
252 testassert(state == 2);
254 // check class_getMethodImplementation (class method)
255 // this is the "slow" case for getNonMetaClass
257 cls = objc_getClass("Super5");
258 testassert(state == 0);
259 class_getMethodImplementation(object_getClass(cls), @selector(instanceMethod));
260 testassert(state == 2);
262 // check +initialize cycles
263 // this is the "cls is a subclass" case for getNonMetaClass
266 testassert(state == 6);
268 // check +initialize cycles
269 // this is the "cls is a subclass" case for getNonMetaClass
272 testassert(state == 6);