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