]> git.saurik.com Git - apple/objc4.git/blob - test/propertyDesc.m
objc4-532.tar.gz
[apple/objc4.git] / test / propertyDesc.m
1 // TEST_CONFIG
2
3 #include "test.h"
4 #include "testroot.i"
5 #include <stdint.h>
6 #include <string.h>
7 #include <objc/runtime.h>
8
9 struct objc_property {
10 const char *name;
11 const char *attr;
12 };
13
14 #define checkattrlist(attrs, attrcount, target) \
15 do { \
16 if (target > 0) { \
17 testassert(attrs); \
18 testassert(attrcount == target); \
19 testassert(malloc_size(attrs) >= \
20 (1+target) * sizeof(objc_property_attribute_t)); \
21 testassert(attrs[target].name == NULL); \
22 testassert(attrs[target].value == NULL); \
23 } else { \
24 testassert(!attrs); \
25 testassert(attrcount == 0); \
26 } \
27 } while (0)
28
29 #define checkattr(attrs, i, n, v) \
30 do { \
31 char *attrsstart = (char *)attrs; \
32 char *attrsend = (char *)attrs + malloc_size(attrs); \
33 testassert((char*)(attrs+i+1) <= attrsend); \
34 testassert(attrs[i].name >= attrsstart); \
35 testassert(attrs[i].value >= attrsstart); \
36 testassert(attrs[i].name + strlen(attrs[i].name) + 1 <= attrsend); \
37 testassert(attrs[i].value + strlen(attrs[i].value) + 1 <= attrsend); \
38 if (n) testassert(0 == strcmp(attrs[i].name, n)); \
39 else testassert(attrs[i].name == NULL); \
40 if (v) testassert(0 == strcmp(attrs[i].value, v)); \
41 else testassert(attrs[i].value == NULL); \
42 } while (0)
43
44 int main()
45 {
46 char *value;
47 objc_property_attribute_t *attrs;
48 unsigned int attrcount;
49
50 // STRING TO ATTRIBUTE LIST (property_copyAttributeList)
51
52 struct objc_property prop;
53 prop.name = "test";
54
55 // null property
56 attrcount = 42;
57 attrs = property_copyAttributeList(NULL, &attrcount);
58 testassert(!attrs);
59 testassert(attrcount == 0);
60 attrs = property_copyAttributeList(NULL, NULL);
61 testassert(!attrs);
62
63 // null attributes
64 attrcount = 42;
65 prop.attr = NULL;
66 attrs = property_copyAttributeList(&prop, &attrcount);
67 checkattrlist(attrs, attrcount, 0);
68 attrs = property_copyAttributeList(&prop, NULL);
69 testassert(!attrs);
70
71 // empty attributes
72 attrcount = 42;
73 prop.attr = "";
74 attrs = property_copyAttributeList(&prop, &attrcount);
75 checkattrlist(attrs, attrcount, 0);
76 attrs = property_copyAttributeList(&prop, NULL);
77 testassert(!attrs);
78
79 // commas only
80 attrcount = 42;
81 prop.attr = ",,,";
82 attrs = property_copyAttributeList(&prop, &attrcount);
83 checkattrlist(attrs, attrcount, 0);
84 attrs = property_copyAttributeList(&prop, NULL);
85 testassert(!attrs);
86
87 // long and short names, with and without values
88 attrcount = 42;
89 prop.attr = "?XX,',\"?!?!\"YY,\"''''\"";
90 attrs = property_copyAttributeList(&prop, &attrcount);
91 checkattrlist(attrs, attrcount, 4);
92 checkattr(attrs, 0, "?", "XX");
93 checkattr(attrs, 1, "'", "");
94 checkattr(attrs, 2, "?!?!", "YY");
95 checkattr(attrs, 3, "''''", "");
96 free(attrs);
97
98 // all recognized attributes simultaneously, values with quotes
99 attrcount = 42;
100 prop.attr = "T11,V2222,S333333\",G\"44444444,W,P,D,R,N,C,&";
101 attrs = property_copyAttributeList(&prop, &attrcount);
102 checkattrlist(attrs, attrcount, 11);
103 checkattr(attrs, 0, "T", "11");
104 checkattr(attrs, 1, "V", "2222");
105 checkattr(attrs, 2, "S", "333333\"");
106 checkattr(attrs, 3, "G", "\"44444444");
107 checkattr(attrs, 4, "W", "");
108 checkattr(attrs, 5, "P", "");
109 checkattr(attrs, 6, "D", "");
110 checkattr(attrs, 7, "R", "");
111 checkattr(attrs, 8, "N", "");
112 checkattr(attrs, 9, "C", "");
113 checkattr(attrs,10, "&", "");
114 free(attrs);
115
116 // kitchen sink
117 attrcount = 42;
118 prop.attr = "W,T11,P,?XX,D,V2222,R,',N,S333333\",C,\"?!?!\"YY,&,G\"44444444,\"''''\"";
119 attrs = property_copyAttributeList(&prop, &attrcount);
120 checkattrlist(attrs, attrcount, 15);
121 checkattr(attrs, 0, "W", "");
122 checkattr(attrs, 1, "T", "11");
123 checkattr(attrs, 2, "P", "");
124 checkattr(attrs, 3, "?", "XX");
125 checkattr(attrs, 4, "D", "");
126 checkattr(attrs, 5, "V", "2222");
127 checkattr(attrs, 6, "R", "");
128 checkattr(attrs, 7, "'", "");
129 checkattr(attrs, 8, "N", "");
130 checkattr(attrs, 9, "S", "333333\"");
131 checkattr(attrs,10, "C", "");
132 checkattr(attrs,11, "?!?!", "YY");
133 checkattr(attrs,12, "&", "");
134 checkattr(attrs,13, "G", "\"44444444");
135 checkattr(attrs,14, "''''", "");
136 free(attrs);
137
138 // SEARCH ATTRIBUTE LIST (property_copyAttributeValue)
139
140 // null property, null name, empty name
141 value = property_copyAttributeValue(NULL, NULL);
142 testassert(!value);
143 value = property_copyAttributeValue(NULL, "foo");
144 testassert(!value);
145 value = property_copyAttributeValue(NULL, "");
146 testassert(!value);
147 value = property_copyAttributeValue(&prop, NULL);
148 testassert(!value);
149 value = property_copyAttributeValue(&prop, "");
150 testassert(!value);
151
152 // null attributes, empty attributes
153 prop.attr = NULL;
154 value = property_copyAttributeValue(&prop, "foo");
155 testassert(!value);
156 prop.attr = "";
157 value = property_copyAttributeValue(&prop, "foo");
158 testassert(!value);
159
160 // long and short names, with and without values
161 prop.attr = "?XX,',\"?!?!\"YY,\"''''\"";
162 value = property_copyAttributeValue(&prop, "missing");
163 testassert(!value);
164 value = property_copyAttributeValue(&prop, "X");
165 testassert(!value);
166 value = property_copyAttributeValue(&prop, "\"");
167 testassert(!value);
168 value = property_copyAttributeValue(&prop, "'''");
169 testassert(!value);
170 value = property_copyAttributeValue(&prop, "'''''");
171 testassert(!value);
172
173 value = property_copyAttributeValue(&prop, "?");
174 testassert(0 == strcmp(value, "XX"));
175 testassert(malloc_size(value) >= 1 + strlen(value));
176 free(value);
177 value = property_copyAttributeValue(&prop, "'");
178 testassert(0 == strcmp(value, ""));
179 testassert(malloc_size(value) >= 1 + strlen(value));
180 free(value);
181 value = property_copyAttributeValue(&prop, "?!?!");
182 testassert(0 == strcmp(value, "YY"));
183 testassert(malloc_size(value) >= 1 + strlen(value));
184 free(value);
185 value = property_copyAttributeValue(&prop, "''''");
186 testassert(0 == strcmp(value, ""));
187 testassert(malloc_size(value) >= 1 + strlen(value));
188 free(value);
189
190 // all recognized attributes simultaneously, values with quotes
191 prop.attr = "T11,V2222,S333333\",G\"44444444,W,P,D,R,N,C,&";
192 value = property_copyAttributeValue(&prop, "T");
193 testassert(0 == strcmp(value, "11"));
194 testassert(malloc_size(value) >= 1 + strlen(value));
195 free(value);
196 value = property_copyAttributeValue(&prop, "V");
197 testassert(0 == strcmp(value, "2222"));
198 testassert(malloc_size(value) >= 1 + strlen(value));
199 free(value);
200 value = property_copyAttributeValue(&prop, "S");
201 testassert(0 == strcmp(value, "333333\""));
202 testassert(malloc_size(value) >= 1 + strlen(value));
203 free(value);
204 value = property_copyAttributeValue(&prop, "G");
205 testassert(0 == strcmp(value, "\"44444444"));
206 testassert(malloc_size(value) >= 1 + strlen(value));
207 free(value);
208 value = property_copyAttributeValue(&prop, "W");
209 testassert(0 == strcmp(value, ""));
210 testassert(malloc_size(value) >= 1 + strlen(value));
211 free(value);
212 value = property_copyAttributeValue(&prop, "P");
213 testassert(0 == strcmp(value, ""));
214 testassert(malloc_size(value) >= 1 + strlen(value));
215 free(value);
216 value = property_copyAttributeValue(&prop, "D");
217 testassert(0 == strcmp(value, ""));
218 testassert(malloc_size(value) >= 1 + strlen(value));
219 free(value);
220 value = property_copyAttributeValue(&prop, "R");
221 testassert(0 == strcmp(value, ""));
222 testassert(malloc_size(value) >= 1 + strlen(value));
223 free(value);
224 value = property_copyAttributeValue(&prop, "N");
225 testassert(0 == strcmp(value, ""));
226 testassert(malloc_size(value) >= 1 + strlen(value));
227 free(value);
228 value = property_copyAttributeValue(&prop, "C");
229 testassert(0 == strcmp(value, ""));
230 testassert(malloc_size(value) >= 1 + strlen(value));
231 free(value);
232 value = property_copyAttributeValue(&prop, "&");
233 testassert(0 == strcmp(value, ""));
234 testassert(malloc_size(value) >= 1 + strlen(value));
235 free(value);
236
237 // ATTRIBUTE LIST TO STRING (class_addProperty)
238
239 BOOL ok;
240 objc_property_t prop2;
241
242 // null name
243 ok = class_addProperty([TestRoot class], NULL, (objc_property_attribute_t *)1, 1);
244 testassert(!ok);
245
246 // null description
247 ok = class_addProperty([TestRoot class], "test-null-desc", NULL, 0);
248 testassert(ok);
249 prop2 = class_getProperty([TestRoot class], "test-null-desc");
250 testassert(prop2);
251 testassert(0 == strcmp(property_getAttributes(prop2), ""));
252
253 // empty description
254 ok = class_addProperty([TestRoot class], "test-empty-desc", (objc_property_attribute_t*)1, 0);
255 testassert(ok);
256 prop2 = class_getProperty([TestRoot class], "test-empty-desc");
257 testassert(prop2);
258 testassert(0 == strcmp(property_getAttributes(prop2), ""));
259
260 // long and short names, with and without values
261 objc_property_attribute_t attrs2[] = {
262 { "!", NULL },
263 { "?", "XX" },
264 { "'", "" },
265 { "?!?!", "YY" },
266 { "''''", "" }
267 };
268 ok = class_addProperty([TestRoot class], "test-unrecognized", attrs2, 5);
269 testassert(ok);
270 prop2 = class_getProperty([TestRoot class], "test-unrecognized");
271 testassert(prop2);
272 testassert(0 == strcmp(property_getAttributes(prop2), "?XX,',\"?!?!\"YY,\"''''\""));
273
274 // all recognized attributes simultaneously, values with quotes
275 objc_property_attribute_t attrs3[] = {
276 { "&", "" },
277 { "C", "" },
278 { "N", "" },
279 { "R", "" },
280 { "D", "" },
281 { "P", "" },
282 { "W", "" },
283 { "G", "\"44444444" },
284 { "S", "333333\"" },
285 { "V", "2222" },
286 { "T", "11" },
287 };
288 ok = class_addProperty([TestRoot class], "test-recognized", attrs3, 11);
289 testassert(ok);
290 prop2 = class_getProperty([TestRoot class], "test-recognized");
291 testassert(prop2);
292 testassert(0 == strcmp(property_getAttributes(prop2),
293 "&,C,N,R,D,P,W,G\"44444444,S333333\",V2222,T11"));
294
295 // kitchen sink
296 objc_property_attribute_t attrs4[] = {
297 { "&", "" },
298 { "C", "" },
299 { "N", "" },
300 { "R", "" },
301 { "D", "" },
302 { "P", "" },
303 { "W", "" },
304 { "!", NULL },
305 { "G", "\"44444444" },
306 { "S", "333333\"" },
307 { "V", "2222" },
308 { "T", "11" },
309 { "?", "XX" },
310 { "'", "" },
311 { "?!?!", "YY" },
312 { "''''", "" }
313 };
314 ok = class_addProperty([TestRoot class], "test-sink", attrs4, 16);
315 testassert(ok);
316 prop2 = class_getProperty([TestRoot class], "test-sink");
317 testassert(prop2);
318 testassert(0 == strcmp(property_getAttributes(prop2),
319 "&,C,N,R,D,P,W,G\"44444444,S333333\",V2222,T11,"
320 "?XX,',\"?!?!\"YY,\"''''\""));
321
322 succeed(__FILE__);
323 }