]> git.saurik.com Git - apple/objc4.git/blob - test/protocol_copyPropertyList.m
objc4-756.2.tar.gz
[apple/objc4.git] / test / protocol_copyPropertyList.m
1 // TEST_CFLAGS -framework Foundation
2 // need Foundation to get NSObject compatibility additions for class Protocol
3 // because ARC calls [protocol retain]
4 /*
5 TEST_BUILD_OUTPUT
6 .*protocol_copyPropertyList.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\]
7 .*protocol_copyPropertyList.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\]
8 .*protocol_copyPropertyList.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\]
9 .*protocol_copyPropertyList.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\]
10 END
11 */
12
13 #include "test.h"
14 #include <string.h>
15 #include <malloc/malloc.h>
16 #include <objc/runtime.h>
17
18 @protocol SuperProps
19 @property int prop1;
20 @property int prop2;
21 @property(class) int prop1;
22 @property(class) int prop2;
23 @end
24
25 @protocol SubProps <SuperProps>
26 @property int prop3;
27 @property int prop4;
28 @property(class) int prop3;
29 @property(class) int prop4;
30 @end
31
32
33 @protocol FourProps
34 @property int prop1;
35 @property int prop2;
36 @property int prop3;
37 @property int prop4;
38
39 @property(class) int prop1;
40 @property(class) int prop2;
41 @property(class) int prop3;
42 @property(class) int prop4;
43 @end
44
45 @protocol NoProps @end
46
47 @protocol OneProp
48 @property int instanceProp;
49 @property(class) int classProp;
50 @end
51
52
53 static int isNamed(objc_property_t p, const char *name)
54 {
55 return (0 == strcmp(name, property_getName(p)));
56 }
57
58 void testfn(objc_property_t *(*copyPropertyList_fn)(Protocol*, unsigned int *),
59 const char *onePropName)
60 {
61 objc_property_t *props;
62 unsigned int count;
63 Protocol *proto;
64
65 proto = @protocol(SubProps);
66 testassert(proto);
67
68 count = 100;
69 props = copyPropertyList_fn(proto, &count);
70 testassert(props);
71 testassert(count == 2);
72 testassert((isNamed(props[0], "prop4") && isNamed(props[1], "prop3")) ||
73 (isNamed(props[0], "prop3") && isNamed(props[1], "prop4")));
74 // props[] should be null-terminated
75 testassert(props[2] == NULL);
76 free(props);
77
78 proto = @protocol(SuperProps);
79 testassert(proto);
80
81 count = 100;
82 props = copyPropertyList_fn(proto, &count);
83 testassert(props);
84 testassert(count == 2);
85 testassert((isNamed(props[0], "prop1") && isNamed(props[1], "prop2")) ||
86 (isNamed(props[0], "prop2") && isNamed(props[1], "prop1")));
87 // props[] should be null-terminated
88 testassert(props[2] == NULL);
89 free(props);
90
91 // Check null-termination - this property list block would be 16 bytes
92 // if it weren't for the terminator
93 proto = @protocol(FourProps);
94 testassert(proto);
95
96 count = 100;
97 props = copyPropertyList_fn(proto, &count);
98 testassert(props);
99 testassert(count == 4);
100 testassert(malloc_size(props) >= 5 * sizeof(objc_property_t));
101 testassert(props[3] != NULL);
102 testassert(props[4] == NULL);
103 free(props);
104
105 // Check NULL count parameter
106 props = copyPropertyList_fn(proto, NULL);
107 testassert(props);
108 testassert(props[4] == NULL);
109 testassert(props[3] != NULL);
110 free(props);
111
112 // Check NULL protocol parameter
113 count = 100;
114 props = copyPropertyList_fn(NULL, &count);
115 testassert(!props);
116 testassert(count == 0);
117
118 // Check NULL protocol and count
119 props = copyPropertyList_fn(NULL, NULL);
120 testassert(!props);
121
122 // Check protocol with no properties
123 proto = @protocol(NoProps);
124 testassert(proto);
125
126 count = 100;
127 props = copyPropertyList_fn(proto, &count);
128 testassert(!props);
129 testassert(count == 0);
130
131 // Check instance vs class properties
132 proto = @protocol(OneProp);
133 testassert(proto);
134
135 count = 100;
136 props = copyPropertyList_fn(proto, &count);
137 testassert(props);
138 testassert(count == 1);
139 testassert(0 == strcmp(property_getName(props[0]), onePropName));
140 free(props);
141 }
142
143 objc_property_t *protocol_copyPropertyList2_YES_YES(Protocol *proto, unsigned int *outCount)
144 {
145 return protocol_copyPropertyList2(proto, outCount, YES, YES);
146 }
147
148 objc_property_t *protocol_copyPropertyList2_YES_NO(Protocol *proto, unsigned int *outCount)
149 {
150 return protocol_copyPropertyList2(proto, outCount, YES, NO);
151 }
152
153 int main()
154 {
155 // protocol_copyPropertyList(...) is identical to
156 // protocol_copyPropertyList2(..., YES, YES)
157 testfn(protocol_copyPropertyList, "instanceProp");
158 testfn(protocol_copyPropertyList2_YES_YES, "instanceProp");
159
160 // protocol_copyPropertyList2(..., YES, NO) is also identical
161 // with the protocol definitions above, except for protocol OneProp.
162 testfn(protocol_copyPropertyList2_YES_NO, "classProp");
163
164 // Check non-functionality of optional properties
165
166 unsigned int count;
167 objc_property_t *props;
168
169 count = 100;
170 props = protocol_copyPropertyList2(@protocol(FourProps), &count, NO, YES);
171 testassert(!props);
172 testassert(count == 0);
173
174 count = 100;
175 props = protocol_copyPropertyList2(@protocol(FourProps), &count, NO, NO);
176 testassert(!props);
177 testassert(count == 0);
178
179 // Check nil count parameter
180 props = protocol_copyPropertyList2(@protocol(FourProps), nil, NO, YES);
181 testassert(!props);
182
183 props = protocol_copyPropertyList2(@protocol(FourProps), nil, NO, NO);
184 testassert(!props);
185
186 // Check nil protocol parameter
187 count = 100;
188 props = protocol_copyPropertyList2(nil, &count, NO, YES);
189 testassert(!props);
190 testassert(count == 0);
191
192 count = 100;
193 props = protocol_copyPropertyList2(nil, &count, NO, NO);
194 testassert(!props);
195 testassert(count == 0);
196
197 // Check nil protocol and count
198 props = protocol_copyPropertyList2(nil, nil, NO, YES);
199 testassert(!props);
200
201 props = protocol_copyPropertyList2(nil, nil, NO, NO);
202 testassert(!props);
203
204
205 succeed(__FILE__);
206 return 0;
207 }