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