]> git.saurik.com Git - apple/objc4.git/blob - test/category.m
objc4-437.3.tar.gz
[apple/objc4.git] / test / category.m
1 #include "test.h"
2 #include <string.h>
3 #include <objc/objc-runtime.h>
4
5 static int state = 0;
6
7 @interface Super { id isa; } @end
8 @implementation Super
9 +(void)initialize { }
10 +class { return self; }
11 -(void)instancemethod { fail("-instancemethod not overridden by category"); }
12 +(void)method { fail("+method not overridden by category"); }
13 @end
14
15 @interface Super (Category) @end
16 @implementation Super (Category)
17 +(void)method {
18 testprintf("in [Super(Category) method]\n");
19 testassert(self == [Super class]);
20 testassert(state == 0);
21 state = 1;
22 }
23 -(void)instancemethod {
24 testprintf("in [Super(Category) instancemethod]\n");
25 testassert(self->isa == [Super class]);
26 testassert(state == 1);
27 state = 2;
28 }
29 @end
30
31 @interface Super (PropertyCategory)
32 @property int i;
33 @end
34 @implementation Super (PropertyCategory)
35 - (int)i { return 0; }
36 - (void)setI:(int)value { (void)value; }
37 @end
38
39 // rdar://5086110 memory smasher in category with class method and property
40 @interface Super (r5086110)
41 @property int property5086110;
42 @end
43 @implementation Super (r5086110)
44 +(void)method5086110 {
45 fail("method method5086110 called!");
46 }
47 - (int)property5086110 { fail("property5086110 called!"); return 0; }
48 - (void)setProperty5086110:(int)value { fail("setProperty5086110 called!"); (void)value; }
49 @end
50
51
52 @interface PropertyClass : Super {
53 int q;
54 }
55 @property(readonly) int q;
56 @end
57 @implementation PropertyClass
58 @synthesize q;
59 @end
60
61 @interface PropertyClass (PropertyCategory)
62 @property int q;
63 @end
64 @implementation PropertyClass (PropertyCategory)
65 @dynamic q;
66 @end
67
68
69 int main()
70 {
71 id buf[10] = {0};
72
73 // methods introduced by category
74 state = 0;
75 [Super method];
76 buf[0] = [Super class];
77 [(Super *)buf instancemethod];
78 testassert(state == 2);
79
80 // property introduced by category
81 objc_property_t p = class_getProperty([Super class], "i");
82 testassert(p);
83 testassert(0 == strcmp(property_getName(p), "i"));
84 testassert(property_getAttributes(p));
85
86 // methods introduced by category's property
87 Method m;
88 m = class_getInstanceMethod([Super class], @selector(i));
89 testassert(m);
90 m = class_getInstanceMethod([Super class], @selector(setI:));
91 testassert(m);
92
93 // class's property shadowed by category's property
94 objc_property_t *plist = class_copyPropertyList([PropertyClass class], NULL);
95 testassert(plist);
96 testassert(plist[0]);
97 testassert(0 == strcmp(property_getName(plist[0]), "q"));
98 testassert(0 == strcmp(property_getAttributes(plist[0]), "Ti,D"));
99 testassert(plist[1]);
100 testassert(0 == strcmp(property_getName(plist[1]), "q"));
101 testassert(0 == strcmp(property_getAttributes(plist[1]), "Ti,R,Vq"));
102 testassert(!plist[2]);
103 free(plist);
104
105 succeed(__FILE__);
106 }
107