EFL 1.7 svn doobies
[profile/ivi/eina.git] / src / tests / eina_test_model.c
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 }