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