X-Git-Url: https://git.saurik.com/apple/objc4.git/blobdiff_plain/7c0e6487d7b67b6bf6c632300ee4b74e8950b051..7af964d1562d70f51a8e9aca24215ac3d83d0624:/test/category.m diff --git a/test/category.m b/test/category.m new file mode 100644 index 0000000..4c946b4 --- /dev/null +++ b/test/category.m @@ -0,0 +1,107 @@ +#include "test.h" +#include +#include + +static int state = 0; + +@interface Super { id isa; } @end +@implementation Super ++(void)initialize { } ++class { return self; } +-(void)instancemethod { fail("-instancemethod not overridden by category"); } ++(void)method { fail("+method not overridden by category"); } +@end + +@interface Super (Category) @end +@implementation Super (Category) ++(void)method { + testprintf("in [Super(Category) method]\n"); + testassert(self == [Super class]); + testassert(state == 0); + state = 1; +} +-(void)instancemethod { + testprintf("in [Super(Category) instancemethod]\n"); + testassert(self->isa == [Super class]); + testassert(state == 1); + state = 2; +} +@end + +@interface Super (PropertyCategory) +@property int i; +@end +@implementation Super (PropertyCategory) +- (int)i { return 0; } +- (void)setI:(int)value { (void)value; } +@end + +// rdar://5086110 memory smasher in category with class method and property +@interface Super (r5086110) +@property int property5086110; +@end +@implementation Super (r5086110) ++(void)method5086110 { + fail("method method5086110 called!"); +} +- (int)property5086110 { fail("property5086110 called!"); return 0; } +- (void)setProperty5086110:(int)value { fail("setProperty5086110 called!"); (void)value; } +@end + + +@interface PropertyClass : Super { + int q; +} +@property(readonly) int q; +@end +@implementation PropertyClass +@synthesize q; +@end + +@interface PropertyClass (PropertyCategory) +@property int q; +@end +@implementation PropertyClass (PropertyCategory) +@dynamic q; +@end + + +int main() +{ + id buf[10] = {0}; + + // methods introduced by category + state = 0; + [Super method]; + buf[0] = [Super class]; + [(Super *)buf instancemethod]; + testassert(state == 2); + + // property introduced by category + objc_property_t p = class_getProperty([Super class], "i"); + testassert(p); + testassert(0 == strcmp(property_getName(p), "i")); + testassert(property_getAttributes(p)); + + // methods introduced by category's property + Method m; + m = class_getInstanceMethod([Super class], @selector(i)); + testassert(m); + m = class_getInstanceMethod([Super class], @selector(setI:)); + testassert(m); + + // class's property shadowed by category's property + objc_property_t *plist = class_copyPropertyList([PropertyClass class], NULL); + testassert(plist); + testassert(plist[0]); + testassert(0 == strcmp(property_getName(plist[0]), "q")); + testassert(0 == strcmp(property_getAttributes(plist[0]), "Ti,D")); + testassert(plist[1]); + testassert(0 == strcmp(property_getName(plist[1]), "q")); + testassert(0 == strcmp(property_getAttributes(plist[1]), "Ti,R,Vq")); + testassert(!plist[2]); + free(plist); + + succeed(__FILE__); +} +