]> git.saurik.com Git - apple/objc4.git/blobdiff - test/protocol.m
objc4-437.tar.gz
[apple/objc4.git] / test / protocol.m
diff --git a/test/protocol.m b/test/protocol.m
new file mode 100644 (file)
index 0000000..33214b8
--- /dev/null
@@ -0,0 +1,202 @@
+#include "test.h"
+
+#include <string.h>
+#include <objc/Protocol.h>
+#include <objc/objc-runtime.h>
+
+@protocol Proto1 
++proto1ClassMethod;
+-proto1InstanceMethod;
+@end
+
+@protocol Proto2
++proto2ClassMethod;
+-proto2InstanceMethod;
+@end
+
+@protocol Proto3 <Proto2>
++proto3ClassMethod;
+-proto3InstanceMethod;
+@end
+
+@protocol Proto4
+@property int i;
+@end
+
+@protocol ProtoEmpty
+@end
+
+@interface Super <Proto1> { id isa; } @end
+@implementation Super
++class { return self; }
++(void)initialize { } 
++proto1ClassMethod { return self; }
+-proto1InstanceMethod { return self; }
+@end
+
+@interface SubNoProtocols : Super { } @end
+@implementation SubNoProtocols @end
+
+@interface SuperNoProtocols { id isa; } @end
+@implementation SuperNoProtocols
++class { return self; }
++(void)initialize { } 
+@end
+
+@interface SubProp : Super <Proto4> { int i; } @end
+@implementation SubProp 
+@synthesize i;
+@end
+
+
+int main()
+{
+    Class cls;
+    Protocol **list;
+    Protocol *protocol, *empty;
+#if !__OBJC2__
+    struct objc_method_description *desc;
+#endif
+    struct objc_method_description desc2;
+    objc_property_t *proplist;
+    unsigned int count;
+
+    protocol = @protocol(Proto3);
+    empty = @protocol(ProtoEmpty);
+    testassert(protocol);
+    testassert(empty);
+
+#if !__OBJC2__
+    testassert([protocol isKindOf:[Protocol class]]);
+    testassert([empty isKindOf:[Protocol class]]);
+    testassert(0 == strcmp([protocol name], "Proto3"));
+    testassert(0 == strcmp([empty name], "ProtoEmpty"));
+#endif
+    testassert(0 == strcmp(protocol_getName(protocol), "Proto3"));
+    testassert(0 == strcmp(protocol_getName(empty), "ProtoEmpty"));
+
+    testassert(class_conformsToProtocol([Super class], @protocol(Proto1)));
+    testassert(!class_conformsToProtocol([SubProp class], @protocol(Proto1)));
+    testassert(class_conformsToProtocol([SubProp class], @protocol(Proto4)));
+    testassert(!class_conformsToProtocol([SubProp class], @protocol(Proto3)));
+    testassert(!class_conformsToProtocol([Super class], @protocol(Proto3)));
+
+    testassert(!protocol_conformsToProtocol(@protocol(Proto1), @protocol(Proto2)));
+    testassert(protocol_conformsToProtocol(@protocol(Proto3), @protocol(Proto2)));
+    testassert(!protocol_conformsToProtocol(@protocol(Proto2), @protocol(Proto3)));
+
+#if !__OBJC2__
+    testassert([@protocol(Proto1) isEqual:@protocol(Proto1)]);
+    testassert(! [@protocol(Proto1) isEqual:@protocol(Proto2)]);
+#endif
+    testassert(protocol_isEqual(@protocol(Proto1), @protocol(Proto1)));
+    testassert(! protocol_isEqual(@protocol(Proto1), @protocol(Proto2)));
+
+#if !__OBJC2__
+    desc = [protocol descriptionForInstanceMethod:@selector(proto3InstanceMethod)];
+    testassert(desc);
+    testassert(desc->name == @selector(proto3InstanceMethod));
+    desc = [protocol descriptionForClassMethod:@selector(proto3ClassMethod)];
+    testassert(desc);
+    testassert(desc->name == @selector(proto3ClassMethod));
+    desc = [protocol descriptionForInstanceMethod:@selector(proto3ClassMethod)];
+    testassert(!desc);
+    desc = [protocol descriptionForClassMethod:@selector(proto3InstanceMethod)];
+    testassert(!desc);    
+    desc = [empty descriptionForInstanceMethod:@selector(proto3ClassMethod)];
+    testassert(!desc);
+    desc = [empty descriptionForClassMethod:@selector(proto3InstanceMethod)];
+    testassert(!desc);    
+#endif
+    desc2 = protocol_getMethodDescription(protocol, @selector(proto3InstanceMethod), YES, YES);
+    testassert(desc2.name && desc2.types);
+    testassert(desc2.name == @selector(proto3InstanceMethod));
+    desc2 = protocol_getMethodDescription(protocol, @selector(proto3ClassMethod), YES, NO);
+    testassert(desc2.name && desc2.types);
+    testassert(desc2.name == @selector(proto3ClassMethod));
+
+    desc2 = protocol_getMethodDescription(protocol, @selector(proto3ClassMethod), YES, YES);
+    testassert(!desc2.name && !desc2.types);
+    desc2 = protocol_getMethodDescription(protocol, @selector(proto3InstanceMethod), YES, NO);
+    testassert(!desc2.name && !desc2.types);
+    desc2 = protocol_getMethodDescription(empty, @selector(proto3ClassMethod), YES, YES);
+    testassert(!desc2.name && !desc2.types);
+    desc2 = protocol_getMethodDescription(empty, @selector(proto3InstanceMethod), YES, NO);
+    testassert(!desc2.name && !desc2.types);
+
+    count = 100;
+    list = protocol_copyProtocolList(@protocol(Proto2), &count);
+    testassert(!list);
+    testassert(count == 0);
+    count = 100;
+    list = protocol_copyProtocolList(@protocol(Proto3), &count);
+    testassert(list);
+    testassert(count == 1);
+    testassert(protocol_isEqual(list[0], @protocol(Proto2)));
+    testassert(!list[1]);
+    free(list);    
+
+    count = 100;
+    cls = objc_getClass("Super");
+    testassert(cls);
+    list = class_copyProtocolList(cls, &count);
+    testassert(list);
+    testassert(list[count] == NULL);
+    testassert(count == 1);
+    testassert(0 == strcmp(protocol_getName(list[0]), "Proto1"));
+    free(list);
+
+    count = 100;
+    cls = objc_getClass("SuperNoProtocols");
+    testassert(cls);
+    list = class_copyProtocolList(cls, &count);
+    testassert(!list);
+    testassert(count == 0);
+
+    count = 100;
+    cls = objc_getClass("SubNoProtocols");
+    testassert(cls);
+    list = class_copyProtocolList(cls, &count);
+    testassert(!list);
+    testassert(count == 0);
+
+
+    cls = objc_getClass("SuperNoProtocols");
+    testassert(cls);
+    list = class_copyProtocolList(cls, NULL);
+    testassert(!list);
+
+    cls = objc_getClass("Super");
+    testassert(cls);
+    list = class_copyProtocolList(cls, NULL);
+    testassert(list);
+    free(list);
+
+    count = 100;
+    list = class_copyProtocolList(NULL, &count);
+    testassert(!list);
+    testassert(count == 0);
+
+
+    // Check property added by protocol
+    cls = objc_getClass("SubProp");
+    testassert(cls);
+
+    count = 100;
+    list = class_copyProtocolList(cls, &count);
+    testassert(list);
+    testassert(count == 1);
+    testassert(0 == strcmp(protocol_getName(list[0]), "Proto4"));
+    testassert(list[1] == NULL);
+    free(list);
+
+    count = 100;
+    proplist = class_copyPropertyList(cls, &count);
+    testassert(proplist);
+    testassert(count == 1);
+    testassert(0 == strcmp(property_getName(proplist[0]), "i"));
+    testassert(proplist[1] == NULL);
+    free(proplist);    
+
+    succeed(__FILE__);
+}