]> git.saurik.com Git - apple/objc4.git/blobdiff - test/category.m
objc4-437.tar.gz
[apple/objc4.git] / test / category.m
diff --git a/test/category.m b/test/category.m
new file mode 100644 (file)
index 0000000..4c946b4
--- /dev/null
@@ -0,0 +1,107 @@
+#include "test.h"
+#include <string.h>
+#include <objc/objc-runtime.h>
+
+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__);
+}
+