diff options
author | David Walter Seikel | 2012-04-22 09:20:32 +1000 |
---|---|---|
committer | David Walter Seikel | 2012-04-22 09:20:32 +1000 |
commit | 3ad3455551be0d7859ecb02290376206d5e66498 (patch) | |
tree | 497917e12b4d7f458dff9765d9b53f64c4e03fc3 /libraries/eina/src/tests | |
parent | Update EFL to latest beta. (diff) | |
download | SledjHamr-3ad3455551be0d7859ecb02290376206d5e66498.zip SledjHamr-3ad3455551be0d7859ecb02290376206d5e66498.tar.gz SledjHamr-3ad3455551be0d7859ecb02290376206d5e66498.tar.bz2 SledjHamr-3ad3455551be0d7859ecb02290376206d5e66498.tar.xz |
And actually include new files, plus elementary libraries.
Diffstat (limited to 'libraries/eina/src/tests')
-rw-r--r-- | libraries/eina/src/tests/eina_test_model.c | 1288 |
1 files changed, 1288 insertions, 0 deletions
diff --git a/libraries/eina/src/tests/eina_test_model.c b/libraries/eina/src/tests/eina_test_model.c new file mode 100644 index 0000000..54a2258 --- /dev/null +++ b/libraries/eina/src/tests/eina_test_model.c | |||
@@ -0,0 +1,1288 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2012 ProFUSION embedded systems | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include "config.h" | ||
21 | #endif | ||
22 | |||
23 | #include <stdio.h> | ||
24 | #include <inttypes.h> | ||
25 | |||
26 | #include "eina_suite.h" | ||
27 | #include "Eina.h" | ||
28 | |||
29 | static void | ||
30 | _eina_test_model_check_safety_null(const Eina_Log_Domain *d, Eina_Log_Level level, const char *file, const char *fnc, int line, const char *fmt, void *data, va_list args) | ||
31 | { | ||
32 | Eina_Bool *ck = data; | ||
33 | |||
34 | if ((level == EINA_LOG_LEVEL_ERR) && (strcmp(fmt, "%s") == 0)) | ||
35 | { | ||
36 | const char *str; | ||
37 | va_list cp_args; | ||
38 | |||
39 | va_copy(cp_args, args); | ||
40 | str = va_arg(cp_args, const char *); | ||
41 | va_end(cp_args); | ||
42 | if (eina_str_has_prefix(str, "safety check failed: ") && | ||
43 | eina_str_has_suffix(str, " == NULL")) | ||
44 | { | ||
45 | *ck = EINA_TRUE; | ||
46 | return; | ||
47 | } | ||
48 | } | ||
49 | *ck = EINA_FALSE; | ||
50 | eina_log_print_cb_stderr(d, level, file, fnc, line, fmt, NULL, args); | ||
51 | } | ||
52 | |||
53 | static void | ||
54 | _eina_test_model_check_safety_false(const Eina_Log_Domain *d, Eina_Log_Level level, const char *file, const char *fnc, int line, const char *fmt, void *data, va_list args) | ||
55 | { | ||
56 | Eina_Bool *ck = data; | ||
57 | |||
58 | if ((level == EINA_LOG_LEVEL_ERR) && (strcmp(fmt, "%s") == 0)) | ||
59 | { | ||
60 | const char *str; | ||
61 | va_list cp_args; | ||
62 | |||
63 | va_copy(cp_args, args); | ||
64 | str = va_arg(cp_args, const char *); | ||
65 | va_end(cp_args); | ||
66 | if (eina_str_has_prefix(str, "safety check failed: ") && | ||
67 | eina_str_has_suffix(str, " is false")) | ||
68 | { | ||
69 | *ck = EINA_TRUE; | ||
70 | return; | ||
71 | } | ||
72 | } | ||
73 | *ck = EINA_FALSE; | ||
74 | eina_log_print_cb_stderr(d, level, file, fnc, line, fmt, NULL, args); | ||
75 | } | ||
76 | |||
77 | static void | ||
78 | _eina_test_model_cb_count(void *data, Eina_Model *model, const Eina_Model_Event_Description *desc, void *event_info) | ||
79 | { | ||
80 | unsigned *count = data; | ||
81 | (*count)++; | ||
82 | #if SHOW_LOG | ||
83 | if ((desc->type) && (strcmp(desc->type, "u") == 0)) | ||
84 | { | ||
85 | unsigned *pos = event_info; | ||
86 | printf("%2u %p %s at %u\n", *count, model, desc->name, *pos); | ||
87 | } | ||
88 | else | ||
89 | printf("%2u %p %s\n", *count, model, desc->name); | ||
90 | #else | ||
91 | (void)model; | ||
92 | (void)desc; | ||
93 | (void)event_info; | ||
94 | #endif | ||
95 | } | ||
96 | |||
97 | START_TEST(eina_model_test_properties) | ||
98 | { | ||
99 | unsigned int count_del = 0, count_pset = 0, count_pdel = 0; | ||
100 | Eina_Model *m; | ||
101 | Eina_Value inv, outv; | ||
102 | int i; | ||
103 | char *s; | ||
104 | Eina_List *lst; | ||
105 | Eina_Bool ck; | ||
106 | |||
107 | eina_init(); | ||
108 | |||
109 | m = eina_model_new(EINA_MODEL_TYPE_GENERIC); | ||
110 | fail_unless(m != NULL); | ||
111 | |||
112 | eina_model_event_callback_add | ||
113 | (m, "deleted", _eina_test_model_cb_count, &count_del); | ||
114 | eina_model_event_callback_add | ||
115 | (m, "property,set", _eina_test_model_cb_count, &count_pset); | ||
116 | eina_model_event_callback_add | ||
117 | (m, "property,deleted", _eina_test_model_cb_count, &count_pdel); | ||
118 | |||
119 | fail_unless(eina_value_setup(&inv, EINA_VALUE_TYPE_INT)); | ||
120 | fail_unless(eina_value_set(&inv, 1234)); | ||
121 | fail_unless(eina_value_get(&inv, &i)); | ||
122 | ck_assert_int_eq(i, 1234); | ||
123 | |||
124 | fail_unless(eina_model_property_set(m, "abc", &inv)); | ||
125 | |||
126 | fail_unless(eina_value_set(&inv, 5678)); | ||
127 | fail_unless(eina_model_property_set(m, "xyz", &inv)); | ||
128 | |||
129 | fail_unless(eina_value_set(&inv, 171)); | ||
130 | fail_unless(eina_model_property_set(m, "value", &inv)); | ||
131 | |||
132 | lst = eina_model_properties_names_list_get(m); | ||
133 | ck_assert_int_eq(eina_list_count(lst), 3); | ||
134 | |||
135 | lst = eina_list_sort(lst, 0, EINA_COMPARE_CB(strcmp)); | ||
136 | ck_assert_str_eq("abc", eina_list_nth(lst, 0)); | ||
137 | ck_assert_str_eq("value", eina_list_nth(lst, 1)); | ||
138 | ck_assert_str_eq("xyz", eina_list_nth(lst, 2)); | ||
139 | |||
140 | eina_model_properties_names_list_free(lst); | ||
141 | |||
142 | fail_unless(eina_model_property_get(m, "abc", &outv)); | ||
143 | fail_unless(eina_value_get(&outv, &i)); | ||
144 | ck_assert_int_eq(i, 1234); | ||
145 | eina_value_flush(&outv); | ||
146 | |||
147 | fail_unless(eina_model_property_get(m, "xyz", &outv)); | ||
148 | fail_unless(eina_value_get(&outv, &i)); | ||
149 | ck_assert_int_eq(i, 5678); | ||
150 | eina_value_flush(&outv); | ||
151 | |||
152 | fail_unless(eina_model_property_get(m, "value", &outv)); | ||
153 | fail_unless(eina_value_get(&outv, &i)); | ||
154 | ck_assert_int_eq(i, 171); | ||
155 | eina_value_flush(&outv); | ||
156 | |||
157 | fail_unless(eina_value_set(&inv, 666)); | ||
158 | fail_unless(eina_model_property_set(m, "value", &inv)); | ||
159 | fail_unless(eina_model_property_get(m, "value", &outv)); | ||
160 | fail_unless(eina_value_get(&outv, &i)); | ||
161 | ck_assert_int_eq(i, 666); | ||
162 | |||
163 | eina_value_flush(&outv); | ||
164 | eina_value_flush(&inv); | ||
165 | |||
166 | fail_unless(eina_value_setup(&inv, EINA_VALUE_TYPE_STRING)); | ||
167 | fail_unless(eina_value_set(&inv, "Hello world!")); | ||
168 | fail_unless(eina_model_property_set(m, "string", &inv)); | ||
169 | |||
170 | fail_unless(eina_model_property_get(m, "string", &outv)); | ||
171 | fail_unless(eina_value_get(&outv, &s)); | ||
172 | fail_unless(s != NULL); | ||
173 | ck_assert_str_eq(s, "Hello world!"); | ||
174 | |||
175 | eina_value_flush(&outv); | ||
176 | eina_value_flush(&inv); | ||
177 | |||
178 | fail_unless(eina_value_setup(&inv, EINA_VALUE_TYPE_STRINGSHARE)); | ||
179 | fail_unless(eina_value_set(&inv, "Hello world-STRINGSHARED!")); | ||
180 | fail_unless(eina_model_property_set(m, "stringshare", &inv)); | ||
181 | /* set twice to see if references drop to zero before new add, shouldn't */ | ||
182 | fail_unless(eina_model_property_set(m, "stringshare", &inv)); | ||
183 | |||
184 | fail_unless(eina_model_property_get(m, "stringshare", &outv)); | ||
185 | fail_unless(eina_value_get(&outv, &s)); | ||
186 | fail_unless(s != NULL); | ||
187 | ck_assert_str_eq(s, "Hello world-STRINGSHARED!"); | ||
188 | |||
189 | eina_value_flush(&outv); | ||
190 | eina_value_flush(&inv); | ||
191 | |||
192 | s = eina_model_to_string(m); | ||
193 | fail_unless(s != NULL); | ||
194 | ck_assert_str_eq(s, "Eina_Model_Type_Generic({abc: 1234, string: Hello world!, stringshare: Hello world-STRINGSHARED!, value: 666, xyz: 5678}, [])"); | ||
195 | free(s); | ||
196 | |||
197 | fail_unless(eina_model_property_del(m, "value")); | ||
198 | |||
199 | /* negative test (check safety was displayed by using print_cb) */ | ||
200 | eina_log_print_cb_set(_eina_test_model_check_safety_null, &ck); | ||
201 | |||
202 | ck = EINA_FALSE; | ||
203 | fail_if(eina_model_property_get(m, "non-existent", &outv)); | ||
204 | fail_unless(ck == EINA_TRUE); | ||
205 | |||
206 | ck = EINA_FALSE; | ||
207 | fail_if(eina_model_property_get(m, NULL, &outv)); | ||
208 | fail_unless(ck == EINA_TRUE); | ||
209 | |||
210 | ck = EINA_FALSE; | ||
211 | fail_if(eina_model_property_del(m, "value")); | ||
212 | fail_unless(ck == EINA_TRUE); | ||
213 | |||
214 | /* revert print_cb to default */ | ||
215 | eina_log_print_cb_set(eina_log_print_cb_stderr, NULL); | ||
216 | |||
217 | ck_assert_int_eq(eina_model_refcount(m), 1); | ||
218 | |||
219 | eina_model_unref(m); | ||
220 | ck_assert_int_eq(count_del, 1); | ||
221 | ck_assert_int_eq(count_pset, 7); | ||
222 | ck_assert_int_eq(count_pdel, 1); | ||
223 | eina_shutdown(); | ||
224 | } | ||
225 | END_TEST | ||
226 | |||
227 | static int | ||
228 | eina_model_test_children_reverse_cmp(const Eina_Model *a, const Eina_Model *b) | ||
229 | { | ||
230 | return - eina_model_compare(a, b); | ||
231 | } | ||
232 | |||
233 | START_TEST(eina_model_test_children) | ||
234 | { | ||
235 | unsigned int count_del = 0, count_cset = 0, count_cins = 0, count_cdel = 0; | ||
236 | Eina_Model *m, *c; | ||
237 | char *s; | ||
238 | int i; | ||
239 | |||
240 | eina_init(); | ||
241 | |||
242 | m = eina_model_new(EINA_MODEL_TYPE_GENERIC); | ||
243 | fail_unless(m != NULL); | ||
244 | |||
245 | eina_model_event_callback_add | ||
246 | (m, "deleted", _eina_test_model_cb_count, &count_del); | ||
247 | eina_model_event_callback_add | ||
248 | (m, "child,set", _eina_test_model_cb_count, &count_cset); | ||
249 | eina_model_event_callback_add | ||
250 | (m, "child,inserted", _eina_test_model_cb_count, &count_cins); | ||
251 | eina_model_event_callback_add | ||
252 | (m, "child,deleted", _eina_test_model_cb_count, &count_cdel); | ||
253 | |||
254 | for (i = 0; i < 10; i++) | ||
255 | { | ||
256 | Eina_Value val; | ||
257 | |||
258 | c = eina_model_new(EINA_MODEL_TYPE_GENERIC); | ||
259 | fail_unless(c != NULL); | ||
260 | |||
261 | eina_model_event_callback_add | ||
262 | (c, "deleted", _eina_test_model_cb_count, &count_del); | ||
263 | eina_model_event_callback_add | ||
264 | (c, "child,set", _eina_test_model_cb_count, &count_cset); | ||
265 | eina_model_event_callback_add | ||
266 | (c, "child,inserted", _eina_test_model_cb_count, &count_cins); | ||
267 | eina_model_event_callback_add | ||
268 | (c, "child,deleted", _eina_test_model_cb_count, &count_cdel); | ||
269 | |||
270 | fail_unless(eina_value_setup(&val, EINA_VALUE_TYPE_INT)); | ||
271 | fail_unless(eina_value_set(&val, i)); | ||
272 | fail_unless(eina_model_property_set(c, "value", &val)); | ||
273 | |||
274 | fail_unless(eina_model_child_append(m, c) >= 0); | ||
275 | ck_assert_int_eq(eina_model_refcount(c), 2); | ||
276 | |||
277 | eina_value_flush(&val); | ||
278 | eina_model_unref(c); | ||
279 | } | ||
280 | |||
281 | ck_assert_int_eq(eina_model_child_count(m), 10); | ||
282 | |||
283 | for (i = 0; i < 10; i++) | ||
284 | { | ||
285 | Eina_Value val; | ||
286 | int x; | ||
287 | |||
288 | c = eina_model_child_get(m, i); | ||
289 | fail_unless(c != NULL); | ||
290 | ck_assert_int_eq(eina_model_refcount(c), 2); | ||
291 | |||
292 | fail_unless(eina_model_property_get(c, "value", &val)); | ||
293 | fail_unless(eina_value_get(&val, &x)); | ||
294 | ck_assert_int_eq(x, i); | ||
295 | |||
296 | eina_value_flush(&val); | ||
297 | eina_model_unref(c); | ||
298 | } | ||
299 | |||
300 | eina_model_child_sort(m, EINA_COMPARE_CB(eina_model_test_children_reverse_cmp)); | ||
301 | |||
302 | for (i = 0; i < 10; i++) | ||
303 | { | ||
304 | Eina_Value val; | ||
305 | int x; | ||
306 | |||
307 | c = eina_model_child_get(m, i); | ||
308 | fail_unless(c != NULL); | ||
309 | ck_assert_int_eq(eina_model_refcount(c), 2); | ||
310 | |||
311 | fail_unless(eina_model_property_get(c, "value", &val)); | ||
312 | fail_unless(eina_value_get(&val, &x)); | ||
313 | ck_assert_int_eq(x, 10 - i - 1); | ||
314 | |||
315 | eina_value_flush(&val); | ||
316 | eina_model_unref(c); | ||
317 | } | ||
318 | |||
319 | eina_model_child_sort(m, EINA_COMPARE_CB(eina_model_compare)); | ||
320 | |||
321 | s = eina_model_to_string(m); | ||
322 | fail_unless(s != NULL); | ||
323 | ck_assert_str_eq(s, "Eina_Model_Type_Generic({}, [Eina_Model_Type_Generic({value: 0}, []), Eina_Model_Type_Generic({value: 1}, []), Eina_Model_Type_Generic({value: 2}, []), Eina_Model_Type_Generic({value: 3}, []), Eina_Model_Type_Generic({value: 4}, []), Eina_Model_Type_Generic({value: 5}, []), Eina_Model_Type_Generic({value: 6}, []), Eina_Model_Type_Generic({value: 7}, []), Eina_Model_Type_Generic({value: 8}, []), Eina_Model_Type_Generic({value: 9}, [])])"); | ||
324 | free(s); | ||
325 | |||
326 | c = eina_model_child_get(m, 0); | ||
327 | eina_model_child_set(m, 1, c); | ||
328 | eina_model_unref(c); | ||
329 | |||
330 | eina_model_child_del(m, 0); | ||
331 | eina_model_child_del(m, 8); | ||
332 | |||
333 | s = eina_model_to_string(m); | ||
334 | fail_unless(s != NULL); | ||
335 | ck_assert_str_eq(s, "Eina_Model_Type_Generic({}, [Eina_Model_Type_Generic({value: 0}, []), Eina_Model_Type_Generic({value: 2}, []), Eina_Model_Type_Generic({value: 3}, []), Eina_Model_Type_Generic({value: 4}, []), Eina_Model_Type_Generic({value: 5}, []), Eina_Model_Type_Generic({value: 6}, []), Eina_Model_Type_Generic({value: 7}, []), Eina_Model_Type_Generic({value: 8}, [])])"); | ||
336 | free(s); | ||
337 | |||
338 | ck_assert_int_eq(eina_model_refcount(m), 1); | ||
339 | eina_model_unref(m); | ||
340 | |||
341 | ck_assert_int_eq(count_del, 11); | ||
342 | ck_assert_int_eq(count_cins, 10); | ||
343 | ck_assert_int_eq(count_cset, 1); | ||
344 | ck_assert_int_eq(count_cdel, 2); | ||
345 | |||
346 | eina_shutdown(); | ||
347 | } | ||
348 | END_TEST | ||
349 | |||
350 | START_TEST(eina_model_test_copy) | ||
351 | { | ||
352 | unsigned int count_del = 0; | ||
353 | Eina_Model *m, *cp; | ||
354 | char *s1, *s2; | ||
355 | int i; | ||
356 | |||
357 | eina_init(); | ||
358 | |||
359 | m = eina_model_new(EINA_MODEL_TYPE_GENERIC); | ||
360 | fail_unless(m != NULL); | ||
361 | |||
362 | eina_model_event_callback_add | ||
363 | (m, "deleted", _eina_test_model_cb_count, &count_del); | ||
364 | |||
365 | for (i = 0; i < 5; i++) | ||
366 | { | ||
367 | Eina_Value val; | ||
368 | char name[2] = {'a'+ i, 0}; | ||
369 | fail_unless(eina_value_setup(&val, EINA_VALUE_TYPE_INT)); | ||
370 | fail_unless(eina_value_set(&val, i)); | ||
371 | fail_unless(eina_model_property_set(m, name, &val)); | ||
372 | eina_value_flush(&val); | ||
373 | } | ||
374 | |||
375 | for (i = 0; i < 5; i++) | ||
376 | { | ||
377 | Eina_Value val; | ||
378 | Eina_Model *c = eina_model_new(EINA_MODEL_TYPE_GENERIC); | ||
379 | fail_unless(c != NULL); | ||
380 | fail_unless(eina_value_setup(&val, EINA_VALUE_TYPE_INT)); | ||
381 | fail_unless(eina_value_set(&val, i)); | ||
382 | fail_unless(eina_model_property_set(c, "x", &val)); | ||
383 | |||
384 | eina_model_event_callback_add | ||
385 | (c, "deleted", _eina_test_model_cb_count, &count_del); | ||
386 | |||
387 | fail_unless(eina_model_child_append(m, c) >= 0); | ||
388 | eina_model_unref(c); | ||
389 | eina_value_flush(&val); | ||
390 | } | ||
391 | |||
392 | s1 = eina_model_to_string(m); | ||
393 | fail_unless(s1 != NULL); | ||
394 | ck_assert_str_eq(s1, "Eina_Model_Type_Generic({a: 0, b: 1, c: 2, d: 3, e: 4}, [Eina_Model_Type_Generic({x: 0}, []), Eina_Model_Type_Generic({x: 1}, []), Eina_Model_Type_Generic({x: 2}, []), Eina_Model_Type_Generic({x: 3}, []), Eina_Model_Type_Generic({x: 4}, [])])"); | ||
395 | |||
396 | cp = eina_model_copy(m); | ||
397 | fail_unless(cp != NULL); | ||
398 | fail_unless(cp != m); | ||
399 | |||
400 | eina_model_event_callback_add | ||
401 | (cp, "deleted", _eina_test_model_cb_count, &count_del); | ||
402 | |||
403 | s2 = eina_model_to_string(cp); | ||
404 | fail_unless(s2 != NULL); | ||
405 | ck_assert_str_eq(s1, s2); | ||
406 | |||
407 | for (i = 0; i < 5; i++) | ||
408 | { | ||
409 | Eina_Model *c1 = eina_model_child_get(m, i); | ||
410 | Eina_Model *c2 = eina_model_child_get(cp, i); | ||
411 | |||
412 | fail_unless(c1 != NULL); | ||
413 | fail_unless(c1 == c2); | ||
414 | ck_assert_int_eq(eina_model_refcount(c1), 4); | ||
415 | |||
416 | eina_model_unref(c1); | ||
417 | eina_model_unref(c2); | ||
418 | } | ||
419 | |||
420 | free(s1); | ||
421 | free(s2); | ||
422 | |||
423 | ck_assert_int_eq(eina_model_refcount(m), 1); | ||
424 | eina_model_unref(m); | ||
425 | |||
426 | ck_assert_int_eq(eina_model_refcount(cp), 1); | ||
427 | eina_model_unref(cp); | ||
428 | |||
429 | ck_assert_int_eq(count_del, 2 + 5); | ||
430 | |||
431 | eina_shutdown(); | ||
432 | } | ||
433 | END_TEST | ||
434 | |||
435 | START_TEST(eina_model_test_deep_copy) | ||
436 | { | ||
437 | unsigned int count_del = 0; | ||
438 | Eina_Model *m, *cp; | ||
439 | char *s1, *s2; | ||
440 | int i; | ||
441 | |||
442 | eina_init(); | ||
443 | |||
444 | m = eina_model_new(EINA_MODEL_TYPE_GENERIC); | ||
445 | fail_unless(m != NULL); | ||
446 | |||
447 | eina_model_event_callback_add | ||
448 | (m, "deleted", _eina_test_model_cb_count, &count_del); | ||
449 | |||
450 | for (i = 0; i < 5; i++) | ||
451 | { | ||
452 | Eina_Value val; | ||
453 | char name[2] = {'a'+ i, 0}; | ||
454 | fail_unless(eina_value_setup(&val, EINA_VALUE_TYPE_INT)); | ||
455 | fail_unless(eina_value_set(&val, i)); | ||
456 | fail_unless(eina_model_property_set(m, name, &val)); | ||
457 | eina_value_flush(&val); | ||
458 | } | ||
459 | |||
460 | for (i = 0; i < 5; i++) | ||
461 | { | ||
462 | Eina_Value val; | ||
463 | Eina_Model *c = eina_model_new(EINA_MODEL_TYPE_GENERIC); | ||
464 | fail_unless(c != NULL); | ||
465 | fail_unless(eina_value_setup(&val, EINA_VALUE_TYPE_INT)); | ||
466 | fail_unless(eina_value_set(&val, i)); | ||
467 | fail_unless(eina_model_property_set(c, "x", &val)); | ||
468 | |||
469 | eina_model_event_callback_add | ||
470 | (c, "deleted", _eina_test_model_cb_count, &count_del); | ||
471 | |||
472 | fail_unless(eina_model_child_append(m, c) >= 0); | ||
473 | eina_model_unref(c); | ||
474 | eina_value_flush(&val); | ||
475 | } | ||
476 | |||
477 | s1 = eina_model_to_string(m); | ||
478 | fail_unless(s1 != NULL); | ||
479 | ck_assert_str_eq(s1, "Eina_Model_Type_Generic({a: 0, b: 1, c: 2, d: 3, e: 4}, [Eina_Model_Type_Generic({x: 0}, []), Eina_Model_Type_Generic({x: 1}, []), Eina_Model_Type_Generic({x: 2}, []), Eina_Model_Type_Generic({x: 3}, []), Eina_Model_Type_Generic({x: 4}, [])])");; | ||
480 | |||
481 | cp = eina_model_deep_copy(m); | ||
482 | fail_unless(cp != NULL); | ||
483 | fail_unless(cp != m); | ||
484 | |||
485 | eina_model_event_callback_add | ||
486 | (cp, "deleted", _eina_test_model_cb_count, &count_del); | ||
487 | |||
488 | s2 = eina_model_to_string(cp); | ||
489 | fail_unless(s2 != NULL); | ||
490 | ck_assert_str_eq(s1, s2); | ||
491 | |||
492 | for (i = 0; i < 5; i++) | ||
493 | { | ||
494 | Eina_Model *c1 = eina_model_child_get(m, i); | ||
495 | Eina_Model *c2 = eina_model_child_get(cp, i); | ||
496 | |||
497 | fail_unless(c1 != NULL); | ||
498 | fail_unless(c1 != c2); | ||
499 | ck_assert_int_eq(eina_model_refcount(c1), 2); | ||
500 | ck_assert_int_eq(eina_model_refcount(c2), 2); | ||
501 | |||
502 | eina_model_event_callback_add | ||
503 | (c2, "deleted", _eina_test_model_cb_count, &count_del); | ||
504 | |||
505 | eina_model_unref(c1); | ||
506 | eina_model_unref(c2); | ||
507 | } | ||
508 | |||
509 | free(s1); | ||
510 | free(s2); | ||
511 | |||
512 | ck_assert_int_eq(eina_model_refcount(m), 1); | ||
513 | eina_model_unref(m); | ||
514 | |||
515 | ck_assert_int_eq(eina_model_refcount(cp), 1); | ||
516 | eina_model_unref(cp); | ||
517 | |||
518 | ck_assert_int_eq(count_del, 2 + 10); | ||
519 | |||
520 | eina_shutdown(); | ||
521 | } | ||
522 | END_TEST | ||
523 | |||
524 | static Eina_Model * | ||
525 | eina_model_test_iterator_setup(unsigned int *count_del) | ||
526 | { | ||
527 | Eina_Model *m; | ||
528 | int i; | ||
529 | |||
530 | m = eina_model_new(EINA_MODEL_TYPE_GENERIC); | ||
531 | fail_unless(m != NULL); | ||
532 | |||
533 | eina_model_event_callback_add | ||
534 | (m, "deleted", _eina_test_model_cb_count, count_del); | ||
535 | |||
536 | for (i = 0; i < 5; i++) | ||
537 | { | ||
538 | Eina_Value val; | ||
539 | Eina_Model *c = eina_model_new(EINA_MODEL_TYPE_GENERIC); | ||
540 | fail_unless(c != NULL); | ||
541 | fail_unless(eina_value_setup(&val, EINA_VALUE_TYPE_INT)); | ||
542 | fail_unless(eina_value_set(&val, i)); | ||
543 | fail_unless(eina_model_property_set(c, "x", &val)); | ||
544 | |||
545 | eina_model_event_callback_add | ||
546 | (c, "deleted", _eina_test_model_cb_count, count_del); | ||
547 | |||
548 | fail_unless(eina_model_child_append(m, c) >= 0); | ||
549 | eina_model_unref(c); | ||
550 | eina_value_flush(&val); | ||
551 | } | ||
552 | |||
553 | return m; | ||
554 | } | ||
555 | |||
556 | START_TEST(eina_model_test_child_iterator) | ||
557 | { | ||
558 | unsigned int count_del = 0; | ||
559 | Eina_Iterator *it; | ||
560 | Eina_Model *m, *c; | ||
561 | int i = 0; | ||
562 | |||
563 | eina_init(); | ||
564 | |||
565 | m = eina_model_test_iterator_setup(&count_del); | ||
566 | |||
567 | it = eina_model_child_iterator_get(m); | ||
568 | fail_unless(it != NULL); | ||
569 | EINA_ITERATOR_FOREACH(it, c) | ||
570 | { | ||
571 | Eina_Value tmp; | ||
572 | int x; | ||
573 | |||
574 | ck_assert_int_eq(eina_model_refcount(c), 2); | ||
575 | fail_unless(eina_model_property_get(c, "x", &tmp)); | ||
576 | fail_unless(eina_value_get(&tmp, &x)); | ||
577 | ck_assert_int_eq(x, i); | ||
578 | |||
579 | eina_model_unref(c); | ||
580 | i++; | ||
581 | } | ||
582 | ck_assert_int_eq(i, 5); | ||
583 | eina_iterator_free(it); | ||
584 | |||
585 | ck_assert_int_eq(eina_model_refcount(m), 1); | ||
586 | eina_model_unref(m); | ||
587 | ck_assert_int_eq(count_del, 6); | ||
588 | eina_shutdown(); | ||
589 | } | ||
590 | END_TEST | ||
591 | |||
592 | START_TEST(eina_model_test_child_reversed_iterator) | ||
593 | { | ||
594 | unsigned int count_del = 0; | ||
595 | Eina_Iterator *it; | ||
596 | Eina_Model *m, *c; | ||
597 | int i = 4; | ||
598 | |||
599 | eina_init(); | ||
600 | |||
601 | m = eina_model_test_iterator_setup(&count_del); | ||
602 | |||
603 | it = eina_model_child_reversed_iterator_get(m); | ||
604 | fail_unless(it != NULL); | ||
605 | EINA_ITERATOR_FOREACH(it, c) | ||
606 | { | ||
607 | Eina_Value tmp; | ||
608 | int x; | ||
609 | |||
610 | ck_assert_int_eq(eina_model_refcount(c), 2); | ||
611 | fail_unless(eina_model_property_get(c, "x", &tmp)); | ||
612 | fail_unless(eina_value_get(&tmp, &x)); | ||
613 | ck_assert_int_eq(x, i); | ||
614 | |||
615 | eina_model_unref(c); | ||
616 | i--; | ||
617 | } | ||
618 | ck_assert_int_eq(i, -1); | ||
619 | eina_iterator_free(it); | ||
620 | |||
621 | ck_assert_int_eq(eina_model_refcount(m), 1); | ||
622 | eina_model_unref(m); | ||
623 | ck_assert_int_eq(count_del, 6); | ||
624 | eina_shutdown(); | ||
625 | } | ||
626 | END_TEST | ||
627 | |||
628 | START_TEST(eina_model_test_child_sorted_iterator) | ||
629 | { | ||
630 | unsigned int count_del = 0; | ||
631 | Eina_Iterator *it; | ||
632 | Eina_Model *m, *c; | ||
633 | int i = 4; | ||
634 | |||
635 | eina_init(); | ||
636 | |||
637 | m = eina_model_test_iterator_setup(&count_del); | ||
638 | |||
639 | it = eina_model_child_sorted_iterator_get | ||
640 | (m, EINA_COMPARE_CB(eina_model_test_children_reverse_cmp)); | ||
641 | fail_unless(it != NULL); | ||
642 | EINA_ITERATOR_FOREACH(it, c) | ||
643 | { | ||
644 | Eina_Value tmp; | ||
645 | int x; | ||
646 | |||
647 | /* 3 because sort takes an extra reference for its temp array */ | ||
648 | ck_assert_int_eq(eina_model_refcount(c), 3); | ||
649 | fail_unless(eina_model_property_get(c, "x", &tmp)); | ||
650 | fail_unless(eina_value_get(&tmp, &x)); | ||
651 | ck_assert_int_eq(x, i); | ||
652 | |||
653 | eina_model_unref(c); | ||
654 | i--; | ||
655 | } | ||
656 | ck_assert_int_eq(i, -1); | ||
657 | eina_iterator_free(it); | ||
658 | |||
659 | it = eina_model_child_sorted_iterator_get | ||
660 | (m, EINA_COMPARE_CB(eina_model_compare)); | ||
661 | fail_unless(it != NULL); | ||
662 | i = 0; | ||
663 | EINA_ITERATOR_FOREACH(it, c) | ||
664 | { | ||
665 | Eina_Value tmp; | ||
666 | int x; | ||
667 | |||
668 | /* 3 because sort takes an extra reference for its temp array */ | ||
669 | ck_assert_int_eq(eina_model_refcount(c), 3); | ||
670 | fail_unless(eina_model_property_get(c, "x", &tmp)); | ||
671 | fail_unless(eina_value_get(&tmp, &x)); | ||
672 | ck_assert_int_eq(x, i); | ||
673 | |||
674 | eina_model_unref(c); | ||
675 | i++; | ||
676 | } | ||
677 | ck_assert_int_eq(i, 5); | ||
678 | eina_iterator_free(it); | ||
679 | |||
680 | ck_assert_int_eq(eina_model_refcount(m), 1); | ||
681 | eina_model_unref(m); | ||
682 | ck_assert_int_eq(count_del, 6); | ||
683 | eina_shutdown(); | ||
684 | } | ||
685 | END_TEST | ||
686 | |||
687 | static Eina_Bool | ||
688 | eina_model_test_filter_event(const void *m, void *c, void *fdata) | ||
689 | { | ||
690 | Eina_Value tmp; | ||
691 | int x; | ||
692 | fail_unless(m == fdata); | ||
693 | fail_unless(eina_model_property_get(c, "x", &tmp)); | ||
694 | fail_unless(eina_value_get(&tmp, &x)); | ||
695 | eina_value_flush(&tmp); | ||
696 | return x % 2 == 0; | ||
697 | } | ||
698 | |||
699 | START_TEST(eina_model_test_child_filtered_iterator) | ||
700 | { | ||
701 | unsigned int count_del = 0; | ||
702 | Eina_Iterator *it; | ||
703 | Eina_Model *m; | ||
704 | int i = 0, idx; | ||
705 | |||
706 | eina_init(); | ||
707 | |||
708 | m = eina_model_test_iterator_setup(&count_del); | ||
709 | |||
710 | it = eina_model_child_filtered_iterator_get | ||
711 | (m, eina_model_test_filter_event, m); | ||
712 | fail_unless(it != NULL); | ||
713 | EINA_ITERATOR_FOREACH(it, idx) | ||
714 | { | ||
715 | Eina_Model *c; | ||
716 | Eina_Value tmp; | ||
717 | int x; | ||
718 | |||
719 | ck_assert_int_eq(idx % 2, 0); | ||
720 | ck_assert_int_eq(idx, i); | ||
721 | |||
722 | c = eina_model_child_get(m, idx); | ||
723 | fail_unless(c != NULL); | ||
724 | ck_assert_int_eq(eina_model_refcount(c), 2); | ||
725 | fail_unless(eina_model_property_get(c, "x", &tmp)); | ||
726 | fail_unless(eina_value_get(&tmp, &x)); | ||
727 | ck_assert_int_eq(x, i); | ||
728 | |||
729 | eina_model_unref(c); | ||
730 | i += 2; | ||
731 | } | ||
732 | ck_assert_int_eq(i, 6); | ||
733 | eina_iterator_free(it); | ||
734 | |||
735 | ck_assert_int_eq(eina_model_refcount(m), 1); | ||
736 | eina_model_unref(m); | ||
737 | ck_assert_int_eq(count_del, 6); | ||
738 | eina_shutdown(); | ||
739 | } | ||
740 | END_TEST | ||
741 | |||
742 | START_TEST(eina_model_test_struct) | ||
743 | { | ||
744 | unsigned int count_del = 0, count_pset = 0, count_pdel = 0; | ||
745 | Eina_Model *m; | ||
746 | struct myst { | ||
747 | int i; | ||
748 | char c; | ||
749 | }; | ||
750 | const Eina_Value_Struct_Member myst_members[] = { | ||
751 | EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_INT, struct myst, i), | ||
752 | EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_CHAR, struct myst, c) | ||
753 | }; | ||
754 | const Eina_Value_Struct_Desc myst_desc = { | ||
755 | EINA_VALUE_STRUCT_DESC_VERSION, | ||
756 | NULL, myst_members, EINA_C_ARRAY_LENGTH(myst_members), sizeof(struct myst) | ||
757 | }; | ||
758 | Eina_Value inv, outv; | ||
759 | int i; | ||
760 | char c, *s; | ||
761 | Eina_List *lst; | ||
762 | Eina_Bool ck; | ||
763 | |||
764 | eina_init(); | ||
765 | |||
766 | m = eina_model_struct_new(&myst_desc); | ||
767 | fail_unless(m != NULL); | ||
768 | |||
769 | eina_model_event_callback_add | ||
770 | (m, "deleted", _eina_test_model_cb_count, &count_del); | ||
771 | eina_model_event_callback_add | ||
772 | (m, "property,set", _eina_test_model_cb_count, &count_pset); | ||
773 | eina_model_event_callback_add | ||
774 | (m, "property,deleted", _eina_test_model_cb_count, &count_pdel); | ||
775 | |||
776 | fail_unless(eina_value_setup(&inv, EINA_VALUE_TYPE_INT)); | ||
777 | fail_unless(eina_value_set(&inv, 1234)); | ||
778 | fail_unless(eina_value_get(&inv, &i)); | ||
779 | ck_assert_int_eq(i, 1234); | ||
780 | fail_unless(eina_model_property_set(m, "i", &inv)); | ||
781 | |||
782 | eina_value_flush(&inv); | ||
783 | fail_unless(eina_value_setup(&inv, EINA_VALUE_TYPE_CHAR)); | ||
784 | fail_unless(eina_value_set(&inv, 33)); | ||
785 | fail_unless(eina_value_get(&inv, &c)); | ||
786 | ck_assert_int_eq(c, 33); | ||
787 | fail_unless(eina_model_property_set(m, "c", &inv)); | ||
788 | |||
789 | lst = eina_model_properties_names_list_get(m); | ||
790 | ck_assert_int_eq(eina_list_count(lst), 2); | ||
791 | |||
792 | lst = eina_list_sort(lst, 0, EINA_COMPARE_CB(strcmp)); | ||
793 | ck_assert_str_eq("c", eina_list_nth(lst, 0)); | ||
794 | ck_assert_str_eq("i", eina_list_nth(lst, 1)); | ||
795 | |||
796 | eina_model_properties_names_list_free(lst); | ||
797 | |||
798 | fail_unless(eina_model_property_get(m, "i", &outv)); | ||
799 | fail_unless(outv.type == EINA_VALUE_TYPE_INT); | ||
800 | fail_unless(eina_value_get(&outv, &i)); | ||
801 | ck_assert_int_eq(i, 1234); | ||
802 | eina_value_flush(&outv); | ||
803 | |||
804 | fail_unless(eina_model_property_get(m, "c", &outv)); | ||
805 | fail_unless(outv.type == EINA_VALUE_TYPE_CHAR); | ||
806 | fail_unless(eina_value_get(&outv, &c)); | ||
807 | ck_assert_int_eq(c, 33); | ||
808 | eina_value_flush(&outv); | ||
809 | |||
810 | eina_value_flush(&inv); | ||
811 | |||
812 | /* negative test (check safety was displayed by using print_cb) */ | ||
813 | eina_log_print_cb_set(_eina_test_model_check_safety_null, &ck); | ||
814 | |||
815 | fail_if(eina_model_property_get(m, "non-existent", &outv)); | ||
816 | |||
817 | ck = EINA_FALSE; | ||
818 | fail_if(eina_model_property_get(m, NULL, &outv)); | ||
819 | fail_unless(ck == EINA_TRUE); | ||
820 | |||
821 | fail_unless(eina_value_setup(&inv, EINA_VALUE_TYPE_STRING)); | ||
822 | fail_unless(eina_value_set(&inv, "hello world")); | ||
823 | |||
824 | eina_log_print_cb_set(_eina_test_model_check_safety_false, &ck); | ||
825 | |||
826 | ck = EINA_FALSE; | ||
827 | fail_if(eina_model_property_set(m, "i", &inv)); | ||
828 | fail_unless(ck == EINA_TRUE); | ||
829 | |||
830 | ck = EINA_FALSE; | ||
831 | fail_if(eina_model_property_set(m, "c", &inv)); | ||
832 | fail_unless(ck == EINA_TRUE); | ||
833 | |||
834 | /* revert print_cb to default */ | ||
835 | eina_log_print_cb_set(eina_log_print_cb_stderr, NULL); | ||
836 | |||
837 | fail_if(eina_model_property_del(m, "value")); | ||
838 | fail_if(eina_model_property_del(m, "i")); | ||
839 | fail_if(eina_model_property_del(m, "c")); | ||
840 | |||
841 | eina_value_flush(&inv); | ||
842 | |||
843 | s = eina_model_to_string(m); | ||
844 | fail_unless(s != NULL); | ||
845 | ck_assert_str_eq(s, "Eina_Model_Type_Struct({c: 33, i: 1234}, [])"); | ||
846 | free(s); | ||
847 | |||
848 | ck_assert_int_eq(eina_model_refcount(m), 1); | ||
849 | |||
850 | eina_model_unref(m); | ||
851 | ck_assert_int_eq(count_del, 1); | ||
852 | ck_assert_int_eq(count_pset, 2); | ||
853 | ck_assert_int_eq(count_pdel, 0); | ||
854 | eina_shutdown(); | ||
855 | } | ||
856 | END_TEST | ||
857 | |||
858 | static Eina_Bool | ||
859 | _struct_complex_members_constructor(Eina_Model *m) | ||
860 | { | ||
861 | struct myst { | ||
862 | Eina_Value_Array a; | ||
863 | Eina_Value_List l; | ||
864 | Eina_Value_Hash h; | ||
865 | Eina_Value_Struct s; | ||
866 | } st; | ||
867 | struct subst { | ||
868 | int i, j; | ||
869 | }; | ||
870 | static Eina_Value_Struct_Member myst_members[] = { | ||
871 | EINA_VALUE_STRUCT_MEMBER(NULL, struct myst, a), | ||
872 | EINA_VALUE_STRUCT_MEMBER(NULL, struct myst, l), | ||
873 | EINA_VALUE_STRUCT_MEMBER(NULL, struct myst, h), | ||
874 | EINA_VALUE_STRUCT_MEMBER(NULL, struct myst, s) | ||
875 | }; | ||
876 | static Eina_Value_Struct_Desc myst_desc = { | ||
877 | EINA_VALUE_STRUCT_DESC_VERSION, | ||
878 | NULL, myst_members, EINA_C_ARRAY_LENGTH(myst_members), sizeof(struct myst) | ||
879 | }; | ||
880 | static Eina_Value_Struct_Member subst_members[] = { | ||
881 | EINA_VALUE_STRUCT_MEMBER(NULL, struct subst, i), | ||
882 | EINA_VALUE_STRUCT_MEMBER(NULL, struct subst, j) | ||
883 | }; | ||
884 | static Eina_Value_Struct_Desc subst_desc = { | ||
885 | EINA_VALUE_STRUCT_DESC_VERSION, | ||
886 | NULL, subst_members, EINA_C_ARRAY_LENGTH(subst_members), | ||
887 | sizeof(struct subst) | ||
888 | }; | ||
889 | |||
890 | if (!myst_members[0].type) | ||
891 | { | ||
892 | myst_members[0].type = EINA_VALUE_TYPE_ARRAY; | ||
893 | myst_members[1].type = EINA_VALUE_TYPE_LIST; | ||
894 | myst_members[2].type = EINA_VALUE_TYPE_HASH; | ||
895 | myst_members[3].type = EINA_VALUE_TYPE_STRUCT; | ||
896 | } | ||
897 | |||
898 | if (!subst_members[0].type) | ||
899 | { | ||
900 | subst_members[0].type = EINA_VALUE_TYPE_INT; | ||
901 | subst_members[1].type = EINA_VALUE_TYPE_INT; | ||
902 | } | ||
903 | |||
904 | if (!eina_model_type_constructor(EINA_MODEL_TYPE_STRUCT, m)) | ||
905 | return EINA_FALSE; | ||
906 | |||
907 | memset(&st, 0, sizeof(st)); | ||
908 | |||
909 | st.a.subtype = EINA_VALUE_TYPE_STRING; | ||
910 | st.l.subtype = EINA_VALUE_TYPE_STRING; | ||
911 | st.h.subtype = EINA_VALUE_TYPE_STRING; | ||
912 | st.s.desc = &subst_desc; | ||
913 | if (!eina_model_struct_set(m, &myst_desc, &st)) | ||
914 | return EINA_FALSE; | ||
915 | |||
916 | return EINA_TRUE; | ||
917 | } | ||
918 | |||
919 | START_TEST(eina_model_test_struct_complex_members) | ||
920 | { | ||
921 | Eina_Model *m; | ||
922 | Eina_Value outv; | ||
923 | char *s; | ||
924 | Eina_Model_Type type = EINA_MODEL_TYPE_INIT_NOPRIVATE | ||
925 | ("struct_complex_members", Eina_Model_Type, NULL, NULL, NULL); | ||
926 | |||
927 | eina_init(); | ||
928 | |||
929 | type.constructor = _struct_complex_members_constructor; | ||
930 | type.parent = EINA_MODEL_TYPE_STRUCT; | ||
931 | |||
932 | m = eina_model_new(&type); | ||
933 | fail_unless(m != NULL); | ||
934 | |||
935 | fail_unless(eina_model_property_get(m, "a", &outv)); | ||
936 | fail_unless(eina_value_array_append(&outv, "Hello")); | ||
937 | fail_unless(eina_value_array_append(&outv, "World")); | ||
938 | fail_unless(eina_model_property_set(m, "a", &outv)); | ||
939 | eina_value_flush(&outv); | ||
940 | |||
941 | fail_unless(eina_model_property_get(m, "l", &outv)); | ||
942 | fail_unless(eina_value_list_append(&outv, "Some")); | ||
943 | fail_unless(eina_value_list_append(&outv, "Thing")); | ||
944 | fail_unless(eina_model_property_set(m, "l", &outv)); | ||
945 | eina_value_flush(&outv); | ||
946 | |||
947 | fail_unless(eina_model_property_get(m, "h", &outv)); | ||
948 | fail_unless(eina_value_hash_set(&outv, "key", "value")); | ||
949 | fail_unless(eina_model_property_set(m, "h", &outv)); | ||
950 | eina_value_flush(&outv); | ||
951 | |||
952 | fail_unless(eina_model_property_get(m, "s", &outv)); | ||
953 | fail_unless(eina_value_struct_set(&outv, "i", 1234)); | ||
954 | fail_unless(eina_value_struct_set(&outv, "j", 44)); | ||
955 | fail_unless(eina_model_property_set(m, "s", &outv)); | ||
956 | eina_value_flush(&outv); | ||
957 | |||
958 | s = eina_model_to_string(m); | ||
959 | fail_unless(s != NULL); | ||
960 | ck_assert_str_eq(s, "struct_complex_members({a: [Hello, World], h: {key: value}, l: [Some, Thing], s: {i: 1234, j: 44}}, [])"); | ||
961 | free(s); | ||
962 | |||
963 | ck_assert_int_eq(eina_model_refcount(m), 1); | ||
964 | |||
965 | eina_model_unref(m); | ||
966 | eina_shutdown(); | ||
967 | } | ||
968 | END_TEST | ||
969 | |||
970 | typedef struct _Animal_Type | ||
971 | { | ||
972 | Eina_Model_Type parent_class; | ||
973 | void (*eat)(Eina_Model *mdl); | ||
974 | } Animal_Type; | ||
975 | |||
976 | typedef struct _Human_Type | ||
977 | { | ||
978 | Animal_Type parent_class; | ||
979 | void (*talk)(Eina_Model *mdl); | ||
980 | } Human_Type; | ||
981 | |||
982 | typedef struct _Pooper_Interface | ||
983 | { | ||
984 | Eina_Model_Interface base_interface; | ||
985 | void (*poop)(Eina_Model *mdl); | ||
986 | } Pooper_Interface; | ||
987 | |||
988 | #define ANIMAL_TYPE(x) ((Animal_Type *) x) | ||
989 | #define HUMAN_TYPE(x) ((Human_Type *) x) | ||
990 | #define POOPER_IFACE(x) ((Pooper_Interface *) x) | ||
991 | #define POOPER_IFACE_NAME "Pooper_Interace" | ||
992 | |||
993 | #define INHER_CB_COUNT(prefix) \ | ||
994 | static int prefix ## _count = 0; \ | ||
995 | static void \ | ||
996 | prefix (Eina_Model *mdl) \ | ||
997 | { \ | ||
998 | (void) mdl; \ | ||
999 | (prefix ## _count)++; \ | ||
1000 | } | ||
1001 | |||
1002 | static void | ||
1003 | animal_eat(Eina_Model *mdl) | ||
1004 | { | ||
1005 | void (*pf)(Eina_Model *mdl); | ||
1006 | pf = eina_model_method_resolve(mdl, Animal_Type, eat); | ||
1007 | EINA_SAFETY_ON_NULL_RETURN(pf); | ||
1008 | pf(mdl); | ||
1009 | } | ||
1010 | |||
1011 | static void | ||
1012 | pooper_poop(Eina_Model *mdl) | ||
1013 | { | ||
1014 | const Eina_Model_Interface *iface = NULL; | ||
1015 | iface = eina_model_interface_get(mdl, POOPER_IFACE_NAME); | ||
1016 | |||
1017 | EINA_SAFETY_ON_NULL_RETURN(iface); | ||
1018 | |||
1019 | void (*pf)(Eina_Model *); | ||
1020 | |||
1021 | pf = eina_model_interface_method_resolve(iface, mdl, Pooper_Interface, poop); | ||
1022 | EINA_SAFETY_ON_NULL_RETURN(pf); | ||
1023 | pf(mdl); | ||
1024 | } | ||
1025 | |||
1026 | INHER_CB_COUNT(_animal_poop); | ||
1027 | INHER_CB_COUNT(_human_poop); | ||
1028 | INHER_CB_COUNT(_animal_eat); | ||
1029 | INHER_CB_COUNT(_human_eat); | ||
1030 | |||
1031 | START_TEST(eina_model_test_inheritance) | ||
1032 | { | ||
1033 | eina_init(); | ||
1034 | |||
1035 | Pooper_Interface _ANIMAL_POOPER_IFACE; | ||
1036 | Eina_Model_Interface *ANIMAL_POOPER_IFACE = (Eina_Model_Interface *) &_ANIMAL_POOPER_IFACE; | ||
1037 | memset(&_ANIMAL_POOPER_IFACE, 0, sizeof(_ANIMAL_POOPER_IFACE)); | ||
1038 | ANIMAL_POOPER_IFACE->version = EINA_MODEL_INTERFACE_VERSION; | ||
1039 | ANIMAL_POOPER_IFACE->interface_size = sizeof(Pooper_Interface); | ||
1040 | ANIMAL_POOPER_IFACE->name = POOPER_IFACE_NAME; | ||
1041 | POOPER_IFACE(ANIMAL_POOPER_IFACE)->poop = _animal_poop; | ||
1042 | |||
1043 | Pooper_Interface _HUMAN_POOPER_IFACE; | ||
1044 | Eina_Model_Interface *HUMAN_POOPER_IFACE = (Eina_Model_Interface *) &_HUMAN_POOPER_IFACE; | ||
1045 | const Eina_Model_Interface *HUMAN_POOPER_IFACES[] = { | ||
1046 | ANIMAL_POOPER_IFACE, NULL | ||
1047 | }; | ||
1048 | memset(&_HUMAN_POOPER_IFACE, 0, sizeof(_HUMAN_POOPER_IFACE)); | ||
1049 | HUMAN_POOPER_IFACE->version = EINA_MODEL_INTERFACE_VERSION; | ||
1050 | HUMAN_POOPER_IFACE->interface_size = sizeof(Pooper_Interface); | ||
1051 | HUMAN_POOPER_IFACE->name = POOPER_IFACE_NAME; | ||
1052 | HUMAN_POOPER_IFACE->interfaces = HUMAN_POOPER_IFACES; | ||
1053 | POOPER_IFACE(HUMAN_POOPER_IFACE)->poop = _human_poop; | ||
1054 | |||
1055 | const Eina_Model_Interface *ANIMAL_IFACES[] = {ANIMAL_POOPER_IFACE, NULL}; | ||
1056 | const Eina_Model_Interface *HUMAN_IFACES[] = {HUMAN_POOPER_IFACE, NULL}; | ||
1057 | |||
1058 | /* Init Animal Type */ | ||
1059 | Animal_Type _ANIMAL_TYPE; | ||
1060 | Eina_Model_Type *ANIMAL_TYPE = (Eina_Model_Type *) &_ANIMAL_TYPE; | ||
1061 | |||
1062 | memset(&_ANIMAL_TYPE, 0, sizeof(_ANIMAL_TYPE)); | ||
1063 | Eina_Model_Type *type = (Eina_Model_Type *) &_ANIMAL_TYPE; | ||
1064 | type->version = EINA_MODEL_TYPE_VERSION; | ||
1065 | type->parent = EINA_MODEL_TYPE_BASE; | ||
1066 | type->type_size = sizeof(Animal_Type); | ||
1067 | type->name = "Animal_Type"; | ||
1068 | type->parent = EINA_MODEL_TYPE_GENERIC; | ||
1069 | type->interfaces = ANIMAL_IFACES; | ||
1070 | |||
1071 | ANIMAL_TYPE(type)->eat = _animal_eat; | ||
1072 | |||
1073 | /* Init Human Type */ | ||
1074 | Animal_Type _HUMAN_TYPE; | ||
1075 | Eina_Model_Type *HUMAN_TYPE = (Eina_Model_Type *) &_HUMAN_TYPE; | ||
1076 | memset(&_HUMAN_TYPE, 0, sizeof(_HUMAN_TYPE)); | ||
1077 | type = (Eina_Model_Type *) &_HUMAN_TYPE; | ||
1078 | type->version = EINA_MODEL_TYPE_VERSION; | ||
1079 | type->parent = ANIMAL_TYPE; | ||
1080 | type->type_size = sizeof(Human_Type); | ||
1081 | type->name = "Human_Type"; | ||
1082 | type->interfaces = HUMAN_IFACES; | ||
1083 | |||
1084 | ANIMAL_TYPE(type)->eat = _human_eat; | ||
1085 | |||
1086 | Eina_Model *hm, *am; | ||
1087 | am = eina_model_new(ANIMAL_TYPE); | ||
1088 | hm = eina_model_new(HUMAN_TYPE); | ||
1089 | |||
1090 | animal_eat(am); | ||
1091 | ck_assert_int_eq(_animal_eat_count, 1); | ||
1092 | animal_eat(hm); | ||
1093 | ck_assert_int_eq(_human_eat_count, 1); | ||
1094 | |||
1095 | pooper_poop(am); | ||
1096 | ck_assert_int_eq(_animal_poop_count, 1); | ||
1097 | pooper_poop(hm); | ||
1098 | ck_assert_int_eq(_human_poop_count, 1); | ||
1099 | |||
1100 | ck_assert_int_eq(_animal_eat_count, 1); | ||
1101 | ck_assert_int_eq(_human_eat_count, 1); | ||
1102 | ck_assert_int_eq(_animal_poop_count, 1); | ||
1103 | ck_assert_int_eq(_human_poop_count, 1); | ||
1104 | |||
1105 | ck_assert_int_eq(eina_model_refcount(am), 1); | ||
1106 | ck_assert_int_eq(eina_model_refcount(hm), 1); | ||
1107 | |||
1108 | eina_model_unref(am); | ||
1109 | eina_model_unref(hm); | ||
1110 | |||
1111 | eina_shutdown(); | ||
1112 | } | ||
1113 | END_TEST | ||
1114 | |||
1115 | static Eina_Bool | ||
1116 | _myproperties_load(Eina_Model *m) | ||
1117 | { | ||
1118 | Eina_Value v; | ||
1119 | Eina_Bool ret; | ||
1120 | int count; | ||
1121 | |||
1122 | if (!eina_model_property_get(m, "load_count", &v)) | ||
1123 | return EINA_FALSE; | ||
1124 | |||
1125 | eina_value_get(&v, &count); | ||
1126 | count++; | ||
1127 | eina_value_set(&v, count); | ||
1128 | |||
1129 | ret = eina_model_property_set(m, "load_count", &v); | ||
1130 | eina_value_flush(&v); | ||
1131 | |||
1132 | return ret; | ||
1133 | } | ||
1134 | |||
1135 | static Eina_Bool | ||
1136 | _myproperties_unload(Eina_Model *m) | ||
1137 | { | ||
1138 | Eina_Value v; | ||
1139 | Eina_Bool ret; | ||
1140 | int count; | ||
1141 | |||
1142 | if (!eina_model_property_get(m, "load_count", &v)) | ||
1143 | return EINA_FALSE; | ||
1144 | |||
1145 | eina_value_get(&v, &count); | ||
1146 | count--; | ||
1147 | eina_value_set(&v, count); | ||
1148 | |||
1149 | ret = eina_model_property_set(m, "load_count", &v); | ||
1150 | eina_value_flush(&v); | ||
1151 | |||
1152 | return ret; | ||
1153 | } | ||
1154 | |||
1155 | static Eina_Bool | ||
1156 | _mychildren_load(Eina_Model *m) | ||
1157 | { | ||
1158 | Eina_Model *c = eina_model_new(EINA_MODEL_TYPE_GENERIC); | ||
1159 | int ret = eina_model_child_append(m, c); | ||
1160 | eina_model_unref(c); | ||
1161 | return ret >= 0; | ||
1162 | } | ||
1163 | |||
1164 | static Eina_Bool | ||
1165 | _mychildren_unload(Eina_Model *m) | ||
1166 | { | ||
1167 | int count = eina_model_child_count(m); | ||
1168 | EINA_SAFETY_ON_FALSE_RETURN_VAL(count > 0, EINA_FALSE); | ||
1169 | return eina_model_child_del(m, count - 1); | ||
1170 | } | ||
1171 | |||
1172 | START_TEST(eina_model_test_ifaces_load_unload) | ||
1173 | { | ||
1174 | unsigned int count_loaded = 0, count_unloaded = 0; | ||
1175 | unsigned int count_ploaded = 0, count_punloaded = 0; | ||
1176 | unsigned int count_cloaded = 0, count_cunloaded = 0; | ||
1177 | static Eina_Model_Interface_Properties piface; | ||
1178 | static Eina_Model_Interface_Children ciface; | ||
1179 | static const Eina_Model_Interface *piface_parents[2] = {NULL, NULL}; | ||
1180 | static const Eina_Model_Interface *ciface_parents[2] = {NULL, NULL}; | ||
1181 | static const Eina_Model_Interface *type_ifaces[3] = { | ||
1182 | &piface.base, &ciface.base, NULL | ||
1183 | }; | ||
1184 | static Eina_Model_Type type; | ||
1185 | Eina_Model *m; | ||
1186 | Eina_Value v; | ||
1187 | int count; | ||
1188 | |||
1189 | eina_init(); | ||
1190 | |||
1191 | /* do after eina_init() otherwise interfaces are not set */ | ||
1192 | piface_parents[0] = EINA_MODEL_INTERFACE_PROPERTIES_HASH; | ||
1193 | ciface_parents[0] = EINA_MODEL_INTERFACE_CHILDREN_INARRAY; | ||
1194 | |||
1195 | memset(&piface, 0, sizeof(piface)); | ||
1196 | piface.base.version = EINA_MODEL_INTERFACE_VERSION; | ||
1197 | piface.base.interface_size = sizeof(piface); | ||
1198 | piface.base.name = EINA_MODEL_INTERFACE_NAME_PROPERTIES; | ||
1199 | piface.base.interfaces = piface_parents; | ||
1200 | piface.load = _myproperties_load; | ||
1201 | piface.unload = _myproperties_unload; | ||
1202 | |||
1203 | memset(&ciface, 0, sizeof(ciface)); | ||
1204 | ciface.base.version = EINA_MODEL_INTERFACE_VERSION; | ||
1205 | ciface.base.interface_size = sizeof(ciface); | ||
1206 | ciface.base.name = EINA_MODEL_INTERFACE_NAME_CHILDREN; | ||
1207 | ciface.base.interfaces = ciface_parents; | ||
1208 | ciface.load = _mychildren_load; | ||
1209 | ciface.unload = _mychildren_unload; | ||
1210 | |||
1211 | type.version = EINA_MODEL_TYPE_VERSION; | ||
1212 | type.private_size = 0; | ||
1213 | type.name = "MyType"; | ||
1214 | eina_model_type_subclass_setup(&type, EINA_MODEL_TYPE_GENERIC); | ||
1215 | type.interfaces = type_ifaces; | ||
1216 | |||
1217 | m = eina_model_new(&type); | ||
1218 | fail_unless(m != NULL); | ||
1219 | |||
1220 | eina_model_event_callback_add | ||
1221 | (m, "loaded", _eina_test_model_cb_count, &count_loaded); | ||
1222 | eina_model_event_callback_add | ||
1223 | (m, "unloaded", _eina_test_model_cb_count, &count_unloaded); | ||
1224 | |||
1225 | eina_model_event_callback_add | ||
1226 | (m, "properties,loaded", _eina_test_model_cb_count, &count_ploaded); | ||
1227 | eina_model_event_callback_add | ||
1228 | (m, "properties,unloaded", _eina_test_model_cb_count, &count_punloaded); | ||
1229 | |||
1230 | eina_model_event_callback_add | ||
1231 | (m, "children,loaded", _eina_test_model_cb_count, &count_cloaded); | ||
1232 | eina_model_event_callback_add | ||
1233 | (m, "children,unloaded", _eina_test_model_cb_count, &count_cunloaded); | ||
1234 | |||
1235 | fail_unless(eina_value_setup(&v, EINA_VALUE_TYPE_INT)); | ||
1236 | fail_unless(eina_value_set(&v, 0)); | ||
1237 | fail_unless(eina_model_property_set(m, "load_count", &v)); | ||
1238 | eina_value_flush(&v); | ||
1239 | |||
1240 | fail_unless(eina_model_load(m)); | ||
1241 | fail_unless(eina_model_load(m)); | ||
1242 | fail_unless(eina_model_load(m)); | ||
1243 | |||
1244 | /* each load increments one for load_count property */ | ||
1245 | fail_unless(eina_model_property_get(m, "load_count", &v)); | ||
1246 | fail_unless(eina_value_pget(&v, &count)); | ||
1247 | ck_assert_int_eq(count, 3); | ||
1248 | eina_value_flush(&v); | ||
1249 | |||
1250 | /* each load adds one child */ | ||
1251 | ck_assert_int_eq(eina_model_child_count(m), 3); | ||
1252 | |||
1253 | fail_unless(eina_model_unload(m)); | ||
1254 | fail_unless(eina_model_unload(m)); | ||
1255 | fail_unless(eina_model_unload(m)); | ||
1256 | |||
1257 | ck_assert_int_eq(count_loaded, 3); | ||
1258 | ck_assert_int_eq(count_unloaded, 3); | ||
1259 | |||
1260 | ck_assert_int_eq(count_ploaded, 3); | ||
1261 | ck_assert_int_eq(count_punloaded, 3); | ||
1262 | |||
1263 | ck_assert_int_eq(count_cloaded, 3); | ||
1264 | ck_assert_int_eq(count_cunloaded, 3); | ||
1265 | |||
1266 | ck_assert_int_eq(eina_model_refcount(m), 1); | ||
1267 | eina_model_unref(m); | ||
1268 | |||
1269 | eina_shutdown(); | ||
1270 | } | ||
1271 | END_TEST | ||
1272 | |||
1273 | void | ||
1274 | eina_test_model(TCase *tc) | ||
1275 | { | ||
1276 | tcase_add_test(tc, eina_model_test_properties); | ||
1277 | tcase_add_test(tc, eina_model_test_children); | ||
1278 | tcase_add_test(tc, eina_model_test_copy); | ||
1279 | tcase_add_test(tc, eina_model_test_deep_copy); | ||
1280 | tcase_add_test(tc, eina_model_test_child_iterator); | ||
1281 | tcase_add_test(tc, eina_model_test_child_reversed_iterator); | ||
1282 | tcase_add_test(tc, eina_model_test_child_sorted_iterator); | ||
1283 | tcase_add_test(tc, eina_model_test_child_filtered_iterator); | ||
1284 | tcase_add_test(tc, eina_model_test_struct); | ||
1285 | tcase_add_test(tc, eina_model_test_struct_complex_members); | ||
1286 | tcase_add_test(tc, eina_model_test_inheritance); | ||
1287 | tcase_add_test(tc, eina_model_test_ifaces_load_unload); | ||
1288 | } | ||