]> git.saurik.com Git - apple/objc4.git/blob - test/addMethod.m
objc4-493.9.tar.gz
[apple/objc4.git] / test / addMethod.m
1 // TEST_CONFIG
2
3 #include "test.h"
4 #include <objc/runtime.h>
5
6 @interface Super { @public id isa; } @end
7 @implementation Super
8 +(void)initialize { }
9 +class { return self; }
10 +(id) new { return class_createInstance(self, 0); }
11
12 -(int)superMethod { return 0; }
13 -(int)bothMethod { return 0; }
14 @end
15
16 @interface Sub : Super @end
17 @implementation Sub
18 -(int)subMethod { return 0; }
19 -(int)bothMethod { return 0; }
20 @end
21
22 @interface Sub2 : Super @end
23 @implementation Sub2
24 -(int)subMethod { return 0; }
25 -(int)bothMethod { return 0; }
26 @end
27
28
29 id fn(id self __attribute__((unused)), SEL cmd __attribute__((unused)), ...) { return nil; }
30
31 int main()
32 {
33 IMP superMethodFromSuper = class_getMethodImplementation([Super class], @selector(superMethod));
34 IMP bothMethodFromSuper = class_getMethodImplementation([Super class], @selector(bothMethod));
35 IMP subMethodFromSub = class_getMethodImplementation([Sub class], @selector(subMethod));
36 IMP bothMethodFromSub = class_getMethodImplementation([Sub class], @selector(bothMethod));
37 IMP subMethodFromSub2 = class_getMethodImplementation([Sub2 class], @selector(subMethod));
38 IMP bothMethodFromSub2 = class_getMethodImplementation([Sub2 class], @selector(bothMethod));
39
40 testassert(superMethodFromSuper);
41 testassert(bothMethodFromSuper);
42 testassert(subMethodFromSub);
43 testassert(bothMethodFromSub);
44 testassert(subMethodFromSub2);
45 testassert(bothMethodFromSub2);
46
47 BOOL ok;
48 IMP imp;
49
50 // class_addMethod doesn't replace existing implementations
51 ok = class_addMethod([Super class], @selector(superMethod), &fn, NULL);
52 testassert(!ok);
53 testassert(class_getMethodImplementation([Super class], @selector(superMethod)) == superMethodFromSuper);
54
55 // class_addMethod does override superclass implementations
56 ok = class_addMethod([Sub class], @selector(superMethod), &fn, NULL);
57 testassert(ok);
58 testassert(class_getMethodImplementation([Sub class], @selector(superMethod)) == &fn);
59
60 // class_addMethod does add root implementations
61 ok = class_addMethod([Super class], @selector(superMethodNew2), &fn, NULL);
62 testassert(ok);
63 testassert(class_getMethodImplementation([Super class], @selector(superMethodNew2)) == &fn);
64 testassert(class_getMethodImplementation([Sub class], @selector(superMethodNew2)) == &fn);
65
66
67 // class_replaceMethod does add new implementations,
68 // returning NULL if super has an implementation
69 imp = class_replaceMethod([Sub2 class], @selector(superMethod), &fn, NULL);
70 testassert(imp == NULL);
71 testassert(class_getMethodImplementation([Sub2 class], @selector(superMethod)) == fn);
72
73 // class_replaceMethod does add new implementations,
74 // returning NULL if super has no implementation
75 imp = class_replaceMethod([Sub2 class], @selector(subMethodNew), &fn, NULL);
76 testassert(imp == NULL);
77 testassert(class_getMethodImplementation([Sub2 class], @selector(subMethodNew)) == fn);
78
79 // class_replaceMethod does add new implemetations
80 // returning NULL if there is no super class
81 imp = class_replaceMethod([Super class], @selector(superMethodNew), &fn, NULL);
82 testassert(imp == NULL);
83 testassert(class_getMethodImplementation([Super class], @selector(superMethodNew)) == fn);
84
85
86 // class_replaceMethod does replace existing implementations,
87 // returning existing implementation (regardless of super)
88 imp = class_replaceMethod([Sub2 class], @selector(subMethod), &fn, NULL);
89 testassert(imp == subMethodFromSub2);
90 testassert(class_getMethodImplementation([Sub2 class], @selector(subMethod)) == fn);
91
92 // class_replaceMethod does replace existing implemetations,
93 // returning existing implementation (regardless of super)
94 imp = class_replaceMethod([Sub2 class], @selector(bothMethod), &fn, NULL);
95 testassert(imp == bothMethodFromSub2);
96 testassert(class_getMethodImplementation([Sub2 class], @selector(bothMethod)) == fn);
97
98 // class_replaceMethod does replace existing implemetations,
99 // returning existing implementation (regardless of super)
100 imp = class_replaceMethod([Super class], @selector(superMethod), &fn, NULL);
101 testassert(imp == superMethodFromSuper);
102 testassert(class_getMethodImplementation([Super class], @selector(superMethod)) == fn);
103
104 // fixme actually try calling them
105
106 succeed(__FILE__);
107 }