123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- // TEST_CFLAGS -framework Foundation
- // need Foundation to get NSObject compatibility additions for class Protocol
- // because ARC calls [protocol retain]
- /*
- TEST_BUILD_OUTPUT
- .*protocol_copyPropertyList.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\]
- .*protocol_copyPropertyList.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\]
- .*protocol_copyPropertyList.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\]
- .*protocol_copyPropertyList.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\]
- END
- */
- #include "test.h"
- #include <string.h>
- #include <malloc/malloc.h>
- #include <objc/runtime.h>
- @protocol SuperProps
- @property int prop1;
- @property int prop2;
- @property(class) int prop1;
- @property(class) int prop2;
- @end
- @protocol SubProps <SuperProps>
- @property int prop3;
- @property int prop4;
- @property(class) int prop3;
- @property(class) int prop4;
- @end
- @protocol FourProps
- @property int prop1;
- @property int prop2;
- @property int prop3;
- @property int prop4;
- @property(class) int prop1;
- @property(class) int prop2;
- @property(class) int prop3;
- @property(class) int prop4;
- @end
- @protocol NoProps @end
- @protocol OneProp
- @property int instanceProp;
- @property(class) int classProp;
- @end
- static int isNamed(objc_property_t p, const char *name)
- {
- return (0 == strcmp(name, property_getName(p)));
- }
- void testfn(objc_property_t *(*copyPropertyList_fn)(Protocol*, unsigned int *),
- const char *onePropName)
- {
- objc_property_t *props;
- unsigned int count;
- Protocol *proto;
- proto = @protocol(SubProps);
- testassert(proto);
- count = 100;
- props = copyPropertyList_fn(proto, &count);
- testassert(props);
- testassert(count == 2);
- testassert((isNamed(props[0], "prop4") && isNamed(props[1], "prop3")) ||
- (isNamed(props[0], "prop3") && isNamed(props[1], "prop4")));
- // props[] should be null-terminated
- testassert(props[2] == NULL);
- free(props);
- proto = @protocol(SuperProps);
- testassert(proto);
- count = 100;
- props = copyPropertyList_fn(proto, &count);
- testassert(props);
- testassert(count == 2);
- testassert((isNamed(props[0], "prop1") && isNamed(props[1], "prop2")) ||
- (isNamed(props[0], "prop2") && isNamed(props[1], "prop1")));
- // props[] should be null-terminated
- testassert(props[2] == NULL);
- free(props);
- // Check null-termination - this property list block would be 16 bytes
- // if it weren't for the terminator
- proto = @protocol(FourProps);
- testassert(proto);
- count = 100;
- props = copyPropertyList_fn(proto, &count);
- testassert(props);
- testassert(count == 4);
- testassert(malloc_size(props) >= 5 * sizeof(objc_property_t));
- testassert(props[3] != NULL);
- testassert(props[4] == NULL);
- free(props);
- // Check NULL count parameter
- props = copyPropertyList_fn(proto, NULL);
- testassert(props);
- testassert(props[4] == NULL);
- testassert(props[3] != NULL);
- free(props);
- // Check NULL protocol parameter
- count = 100;
- props = copyPropertyList_fn(NULL, &count);
- testassert(!props);
- testassert(count == 0);
-
- // Check NULL protocol and count
- props = copyPropertyList_fn(NULL, NULL);
- testassert(!props);
- // Check protocol with no properties
- proto = @protocol(NoProps);
- testassert(proto);
- count = 100;
- props = copyPropertyList_fn(proto, &count);
- testassert(!props);
- testassert(count == 0);
- // Check instance vs class properties
- proto = @protocol(OneProp);
- testassert(proto);
-
- count = 100;
- props = copyPropertyList_fn(proto, &count);
- testassert(props);
- testassert(count == 1);
- testassert(0 == strcmp(property_getName(props[0]), onePropName));
- free(props);
- }
- objc_property_t *protocol_copyPropertyList2_YES_YES(Protocol *proto, unsigned int *outCount)
- {
- return protocol_copyPropertyList2(proto, outCount, YES, YES);
- }
- objc_property_t *protocol_copyPropertyList2_YES_NO(Protocol *proto, unsigned int *outCount)
- {
- return protocol_copyPropertyList2(proto, outCount, YES, NO);
- }
- int main()
- {
- // protocol_copyPropertyList(...) is identical to
- // protocol_copyPropertyList2(..., YES, YES)
- testfn(protocol_copyPropertyList, "instanceProp");
- testfn(protocol_copyPropertyList2_YES_YES, "instanceProp");
- // protocol_copyPropertyList2(..., YES, NO) is also identical
- // with the protocol definitions above, except for protocol OneProp.
- testfn(protocol_copyPropertyList2_YES_NO, "classProp");
- // Check non-functionality of optional properties
- unsigned int count;
- objc_property_t *props;
- count = 100;
- props = protocol_copyPropertyList2(@protocol(FourProps), &count, NO, YES);
- testassert(!props);
- testassert(count == 0);
- count = 100;
- props = protocol_copyPropertyList2(@protocol(FourProps), &count, NO, NO);
- testassert(!props);
- testassert(count == 0);
- // Check nil count parameter
- props = protocol_copyPropertyList2(@protocol(FourProps), nil, NO, YES);
- testassert(!props);
- props = protocol_copyPropertyList2(@protocol(FourProps), nil, NO, NO);
- testassert(!props);
- // Check nil protocol parameter
- count = 100;
- props = protocol_copyPropertyList2(nil, &count, NO, YES);
- testassert(!props);
- testassert(count == 0);
- count = 100;
- props = protocol_copyPropertyList2(nil, &count, NO, NO);
- testassert(!props);
- testassert(count == 0);
-
- // Check nil protocol and count
- props = protocol_copyPropertyList2(nil, nil, NO, YES);
- testassert(!props);
- props = protocol_copyPropertyList2(nil, nil, NO, NO);
- testassert(!props);
-
- succeed(__FILE__);
- return 0;
- }
|