--- /dev/null
+// initialize.m
+// Test basic +initialize behavior
+// * +initialize before class method
+// * superclass +initialize before subclass +initialize
+// * subclass inheritance of superclass implementation
+// * messaging during +initialize
+#include "test.h"
+
+int state = 0;
+
+@interface Super0 { } @end
+@implementation Super0
++(void)initialize {
+ fail("objc_getClass() must not trigger +initialize");
+}
+@end
+
+@interface Super {} @end
+@implementation Super
++(void)initialize {
+ testprintf("in [Super initialize]\n");
+ testassert(state == 0);
+ state = 1;
+}
++(void)method {
+ fail("[Super method] shouldn't be called");
+}
+@end
+
+@interface Sub : Super { } @end
+@implementation Sub
++(void)initialize {
+ testprintf("in [Sub initialize]\n");
+ testassert(state == 1);
+ state = 2;
+}
++(void)method {
+ testprintf("in [Sub method]\n");
+ testassert(state == 2);
+ state = 3;
+}
+@end
+
+
+@interface Super2 { } @end
+@interface Sub2 : Super2 { } @end
+
+@implementation Super2
++(id)class { return self; }
++(void)initialize {
+ if (self == objc_getClass("Sub2")) {
+ testprintf("in [Super2 initialize] of Sub2\n");
+ testassert(state == 1);
+ state = 2;
+ } else if (self == objc_getClass("Super2")) {
+ testprintf("in [Super2 initialize] of Super2\n");
+ testassert(state == 0);
+ state = 1;
+ } else {
+ fail("in [Super2 initialize] of unknown class");
+ }
+}
++(void)method {
+ testprintf("in [Super2 method]\n");
+ testassert(state == 2);
+ state = 3;
+}
+@end
+
+@implementation Sub2
+// nothing here
+@end
+
+
+@interface Super3 { } @end
+@interface Sub3 : Super3 { } @end
+
+@implementation Super3
++(id)class { return self; }
++(void)initialize {
+ if (self == [Sub3 class]) { // this message triggers [Sub3 initialize]
+ testprintf("in [Super3 initialize] of Sub3\n");
+ testassert(state == 0);
+ state = 1;
+ } else if (self == [Super3 class]) {
+ testprintf("in [Super3 initialize] of Super3\n");
+ testassert(state == 1);
+ state = 2;
+ } else {
+ fail("in [Super3 initialize] of unknown class");
+ }
+}
++(void)method {
+ testprintf("in [Super3 method]\n");
+ testassert(state == 2);
+ state = 3;
+}
+@end
+
+@implementation Sub3
+// nothing here
+@end
+
+int main()
+{
+ // objc_getClass() must not +initialize anything
+ state = 0;
+ objc_getClass("Super0");
+ testassert(state == 0);
+
+ // initialize superclass, then subclass
+ state = 0;
+ [Sub method];
+ testassert(state == 3);
+
+ // check subclass's inheritance of superclass initialize
+ state = 0;
+ [Sub2 method];
+ testassert(state == 3);
+
+ // check subclass method called from superclass initialize
+ state = 0;
+ [Sub3 method];
+ testassert(state == 3);
+
+ succeed(__FILE__);
+
+ return 0;
+}