X-Git-Url: https://git.saurik.com/apple/objc4.git/blobdiff_plain/7c0e6487d7b67b6bf6c632300ee4b74e8950b051..7af964d1562d70f51a8e9aca24215ac3d83d0624:/test/protocol.m diff --git a/test/protocol.m b/test/protocol.m new file mode 100644 index 0000000..33214b8 --- /dev/null +++ b/test/protocol.m @@ -0,0 +1,202 @@ +#include "test.h" + +#include +#include +#include + +@protocol Proto1 ++proto1ClassMethod; +-proto1InstanceMethod; +@end + +@protocol Proto2 ++proto2ClassMethod; +-proto2InstanceMethod; +@end + +@protocol Proto3 ++proto3ClassMethod; +-proto3InstanceMethod; +@end + +@protocol Proto4 +@property int i; +@end + +@protocol ProtoEmpty +@end + +@interface Super { 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 { 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__); +}