1 /* EINA - EFL data type library
2 * Copyright (C) 2012 ProFUSION embedded systems
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.
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.
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/>.
26 #include "eina_suite.h"
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)
34 if ((level == EINA_LOG_LEVEL_ERR) && (strcmp(fmt, "%s") == 0))
39 va_copy(cp_args, args);
40 str = va_arg(cp_args, const char *);
42 if (eina_str_has_prefix(str, "safety check failed: ") &&
43 eina_str_has_suffix(str, " == NULL"))
50 eina_log_print_cb_stderr(d, level, file, fnc, line, fmt, NULL, args);
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)
58 if ((level == EINA_LOG_LEVEL_ERR) && (strcmp(fmt, "%s") == 0))
63 va_copy(cp_args, args);
64 str = va_arg(cp_args, const char *);
66 if (eina_str_has_prefix(str, "safety check failed: ") &&
67 eina_str_has_suffix(str, " is false"))
74 eina_log_print_cb_stderr(d, level, file, fnc, line, fmt, NULL, args);
78 _eina_test_model_cb_count(void *data, Eina_Model *model, const Eina_Model_Event_Description *desc, void *event_info)
80 unsigned *count = data;
83 if ((desc->type) && (strcmp(desc->type, "u") == 0))
85 unsigned *pos = event_info;
86 printf("%2u %p %s at %u\n", *count, model, desc->name, *pos);
89 printf("%2u %p %s\n", *count, model, desc->name);
97 START_TEST(eina_model_test_properties)
99 unsigned int count_del = 0, count_pset = 0, count_pdel = 0;
101 Eina_Value inv, outv;
109 m = eina_model_new(EINA_MODEL_TYPE_GENERIC);
110 fail_unless(m != NULL);
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);
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);
124 fail_unless(eina_model_property_set(m, "abc", &inv));
126 fail_unless(eina_value_set(&inv, 5678));
127 fail_unless(eina_model_property_set(m, "xyz", &inv));
129 fail_unless(eina_value_set(&inv, 171));
130 fail_unless(eina_model_property_set(m, "value", &inv));
132 lst = eina_model_properties_names_list_get(m);
133 ck_assert_int_eq(eina_list_count(lst), 3);
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));
140 eina_model_properties_names_list_free(lst);
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);
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);
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);
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);
163 eina_value_flush(&outv);
164 eina_value_flush(&inv);
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));
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!");
175 eina_value_flush(&outv);
176 eina_value_flush(&inv);
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));
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!");
189 eina_value_flush(&outv);
190 eina_value_flush(&inv);
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}, [])");
197 fail_unless(eina_model_property_del(m, "value"));
199 /* negative test (check safety was displayed by using print_cb) */
200 eina_log_print_cb_set(_eina_test_model_check_safety_null, &ck);
203 fail_if(eina_model_property_get(m, "non-existent", &outv));
204 fail_unless(ck == EINA_TRUE);
207 fail_if(eina_model_property_get(m, NULL, &outv));
208 fail_unless(ck == EINA_TRUE);
211 fail_if(eina_model_property_del(m, "value"));
212 fail_unless(ck == EINA_TRUE);
214 /* revert print_cb to default */
215 eina_log_print_cb_set(eina_log_print_cb_stderr, NULL);
217 ck_assert_int_eq(eina_model_refcount(m), 1);
220 ck_assert_int_eq(count_del, 1);
221 ck_assert_int_eq(count_pset, 7);
222 ck_assert_int_eq(count_pdel, 1);
228 eina_model_test_children_reverse_cmp(const Eina_Model *a, const Eina_Model *b)
230 return - eina_model_compare(a, b);
233 START_TEST(eina_model_test_children)
235 unsigned int count_del = 0, count_cset = 0, count_cins = 0, count_cdel = 0;
242 m = eina_model_new(EINA_MODEL_TYPE_GENERIC);
243 fail_unless(m != NULL);
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);
254 for (i = 0; i < 10; i++)
258 c = eina_model_new(EINA_MODEL_TYPE_GENERIC);
259 fail_unless(c != NULL);
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);
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));
274 fail_unless(eina_model_child_append(m, c) >= 0);
275 ck_assert_int_eq(eina_model_refcount(c), 2);
277 eina_value_flush(&val);
281 ck_assert_int_eq(eina_model_child_count(m), 10);
283 for (i = 0; i < 10; i++)
288 c = eina_model_child_get(m, i);
289 fail_unless(c != NULL);
290 ck_assert_int_eq(eina_model_refcount(c), 2);
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);
296 eina_value_flush(&val);
300 eina_model_child_sort(m, EINA_COMPARE_CB(eina_model_test_children_reverse_cmp));
302 for (i = 0; i < 10; i++)
307 c = eina_model_child_get(m, i);
308 fail_unless(c != NULL);
309 ck_assert_int_eq(eina_model_refcount(c), 2);
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);
315 eina_value_flush(&val);
319 eina_model_child_sort(m, EINA_COMPARE_CB(eina_model_compare));
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}, [])])");
326 c = eina_model_child_get(m, 0);
327 eina_model_child_set(m, 1, c);
330 eina_model_child_del(m, 0);
331 eina_model_child_del(m, 8);
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}, [])])");
338 ck_assert_int_eq(eina_model_refcount(m), 1);
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);
350 START_TEST(eina_model_test_copy)
352 unsigned int count_del = 0;
359 m = eina_model_new(EINA_MODEL_TYPE_GENERIC);
360 fail_unless(m != NULL);
362 eina_model_event_callback_add
363 (m, "deleted", _eina_test_model_cb_count, &count_del);
365 for (i = 0; i < 5; i++)
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);
375 for (i = 0; i < 5; i++)
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));
384 eina_model_event_callback_add
385 (c, "deleted", _eina_test_model_cb_count, &count_del);
387 fail_unless(eina_model_child_append(m, c) >= 0);
389 eina_value_flush(&val);
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}, [])])");
396 cp = eina_model_copy(m);
397 fail_unless(cp != NULL);
398 fail_unless(cp != m);
400 eina_model_event_callback_add
401 (cp, "deleted", _eina_test_model_cb_count, &count_del);
403 s2 = eina_model_to_string(cp);
404 fail_unless(s2 != NULL);
405 ck_assert_str_eq(s1, s2);
407 for (i = 0; i < 5; i++)
409 Eina_Model *c1 = eina_model_child_get(m, i);
410 Eina_Model *c2 = eina_model_child_get(cp, i);
412 fail_unless(c1 != NULL);
413 fail_unless(c1 == c2);
414 ck_assert_int_eq(eina_model_refcount(c1), 4);
416 eina_model_unref(c1);
417 eina_model_unref(c2);
423 ck_assert_int_eq(eina_model_refcount(m), 1);
426 ck_assert_int_eq(eina_model_refcount(cp), 1);
427 eina_model_unref(cp);
429 ck_assert_int_eq(count_del, 2 + 5);
435 START_TEST(eina_model_test_deep_copy)
437 unsigned int count_del = 0;
444 m = eina_model_new(EINA_MODEL_TYPE_GENERIC);
445 fail_unless(m != NULL);
447 eina_model_event_callback_add
448 (m, "deleted", _eina_test_model_cb_count, &count_del);
450 for (i = 0; i < 5; i++)
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);
460 for (i = 0; i < 5; i++)
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));
469 eina_model_event_callback_add
470 (c, "deleted", _eina_test_model_cb_count, &count_del);
472 fail_unless(eina_model_child_append(m, c) >= 0);
474 eina_value_flush(&val);
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}, [])])");;
481 cp = eina_model_deep_copy(m);
482 fail_unless(cp != NULL);
483 fail_unless(cp != m);
485 eina_model_event_callback_add
486 (cp, "deleted", _eina_test_model_cb_count, &count_del);
488 s2 = eina_model_to_string(cp);
489 fail_unless(s2 != NULL);
490 ck_assert_str_eq(s1, s2);
492 for (i = 0; i < 5; i++)
494 Eina_Model *c1 = eina_model_child_get(m, i);
495 Eina_Model *c2 = eina_model_child_get(cp, i);
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);
502 eina_model_event_callback_add
503 (c2, "deleted", _eina_test_model_cb_count, &count_del);
505 eina_model_unref(c1);
506 eina_model_unref(c2);
512 ck_assert_int_eq(eina_model_refcount(m), 1);
515 ck_assert_int_eq(eina_model_refcount(cp), 1);
516 eina_model_unref(cp);
518 ck_assert_int_eq(count_del, 2 + 10);
525 eina_model_test_iterator_setup(unsigned int *count_del)
530 m = eina_model_new(EINA_MODEL_TYPE_GENERIC);
531 fail_unless(m != NULL);
533 eina_model_event_callback_add
534 (m, "deleted", _eina_test_model_cb_count, count_del);
536 for (i = 0; i < 5; i++)
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));
545 eina_model_event_callback_add
546 (c, "deleted", _eina_test_model_cb_count, count_del);
548 fail_unless(eina_model_child_append(m, c) >= 0);
550 eina_value_flush(&val);
556 START_TEST(eina_model_test_child_iterator)
558 unsigned int count_del = 0;
565 m = eina_model_test_iterator_setup(&count_del);
567 it = eina_model_child_iterator_get(m);
568 fail_unless(it != NULL);
569 EINA_ITERATOR_FOREACH(it, c)
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);
582 ck_assert_int_eq(i, 5);
583 eina_iterator_free(it);
585 ck_assert_int_eq(eina_model_refcount(m), 1);
587 ck_assert_int_eq(count_del, 6);
592 START_TEST(eina_model_test_child_reversed_iterator)
594 unsigned int count_del = 0;
601 m = eina_model_test_iterator_setup(&count_del);
603 it = eina_model_child_reversed_iterator_get(m);
604 fail_unless(it != NULL);
605 EINA_ITERATOR_FOREACH(it, c)
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);
618 ck_assert_int_eq(i, -1);
619 eina_iterator_free(it);
621 ck_assert_int_eq(eina_model_refcount(m), 1);
623 ck_assert_int_eq(count_del, 6);
628 START_TEST(eina_model_test_child_sorted_iterator)
630 unsigned int count_del = 0;
637 m = eina_model_test_iterator_setup(&count_del);
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)
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);
656 ck_assert_int_eq(i, -1);
657 eina_iterator_free(it);
659 it = eina_model_child_sorted_iterator_get
660 (m, EINA_COMPARE_CB(eina_model_compare));
661 fail_unless(it != NULL);
663 EINA_ITERATOR_FOREACH(it, c)
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);
677 ck_assert_int_eq(i, 5);
678 eina_iterator_free(it);
680 ck_assert_int_eq(eina_model_refcount(m), 1);
682 ck_assert_int_eq(count_del, 6);
688 eina_model_test_filter_event(const void *m, void *c, void *fdata)
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);
699 START_TEST(eina_model_test_child_filtered_iterator)
701 unsigned int count_del = 0;
708 m = eina_model_test_iterator_setup(&count_del);
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)
719 ck_assert_int_eq(idx % 2, 0);
720 ck_assert_int_eq(idx, i);
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);
732 ck_assert_int_eq(i, 6);
733 eina_iterator_free(it);
735 ck_assert_int_eq(eina_model_refcount(m), 1);
737 ck_assert_int_eq(count_del, 6);
742 START_TEST(eina_model_test_struct)
744 unsigned int count_del = 0, count_pset = 0, count_pdel = 0;
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)
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)
758 Eina_Value inv, outv;
766 m = eina_model_struct_new(&myst_desc);
767 fail_unless(m != NULL);
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);
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));
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));
789 lst = eina_model_properties_names_list_get(m);
790 ck_assert_int_eq(eina_list_count(lst), 2);
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));
796 eina_model_properties_names_list_free(lst);
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);
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);
810 eina_value_flush(&inv);
812 /* negative test (check safety was displayed by using print_cb) */
813 eina_log_print_cb_set(_eina_test_model_check_safety_null, &ck);
815 fail_if(eina_model_property_get(m, "non-existent", &outv));
818 fail_if(eina_model_property_get(m, NULL, &outv));
819 fail_unless(ck == EINA_TRUE);
821 fail_unless(eina_value_setup(&inv, EINA_VALUE_TYPE_STRING));
822 fail_unless(eina_value_set(&inv, "hello world"));
824 eina_log_print_cb_set(_eina_test_model_check_safety_false, &ck);
827 fail_if(eina_model_property_set(m, "i", &inv));
828 fail_unless(ck == EINA_TRUE);
831 fail_if(eina_model_property_set(m, "c", &inv));
832 fail_unless(ck == EINA_TRUE);
834 /* revert print_cb to default */
835 eina_log_print_cb_set(eina_log_print_cb_stderr, NULL);
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"));
841 eina_value_flush(&inv);
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}, [])");
848 ck_assert_int_eq(eina_model_refcount(m), 1);
851 ck_assert_int_eq(count_del, 1);
852 ck_assert_int_eq(count_pset, 2);
853 ck_assert_int_eq(count_pdel, 0);
859 _struct_complex_members_constructor(Eina_Model *m)
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)
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)
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)
884 static Eina_Value_Struct_Desc subst_desc = {
885 EINA_VALUE_STRUCT_DESC_VERSION,
886 NULL, subst_members, EINA_C_ARRAY_LENGTH(subst_members),
890 if (!myst_members[0].type)
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;
898 if (!subst_members[0].type)
900 subst_members[0].type = EINA_VALUE_TYPE_INT;
901 subst_members[1].type = EINA_VALUE_TYPE_INT;
904 if (!eina_model_type_constructor(EINA_MODEL_TYPE_STRUCT, m))
907 memset(&st, 0, sizeof(st));
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))
919 START_TEST(eina_model_test_struct_complex_members)
924 Eina_Model_Type type = EINA_MODEL_TYPE_INIT_NOPRIVATE
925 ("struct_complex_members", Eina_Model_Type, NULL, NULL, NULL);
929 type.constructor = _struct_complex_members_constructor;
930 type.parent = EINA_MODEL_TYPE_STRUCT;
932 m = eina_model_new(&type);
933 fail_unless(m != NULL);
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);
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);
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);
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);
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}}, [])");
963 ck_assert_int_eq(eina_model_refcount(m), 1);
970 typedef struct _Animal_Type
972 Eina_Model_Type parent_class;
973 void (*eat)(Eina_Model *mdl);
976 typedef struct _Human_Type
978 Animal_Type parent_class;
979 void (*talk)(Eina_Model *mdl);
982 typedef struct _Pooper_Interface
984 Eina_Model_Interface base_interface;
985 void (*poop)(Eina_Model *mdl);
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"
993 #define INHER_CB_COUNT(prefix) \
994 static int prefix ## _count = 0; \
996 prefix (Eina_Model *mdl) \
999 (prefix ## _count)++; \
1003 animal_eat(Eina_Model *mdl)
1005 void (*pf)(Eina_Model *mdl);
1006 pf = eina_model_method_resolve(mdl, Animal_Type, eat);
1007 EINA_SAFETY_ON_NULL_RETURN(pf);
1012 pooper_poop(Eina_Model *mdl)
1014 const Eina_Model_Interface *iface = NULL;
1015 iface = eina_model_interface_get(mdl, POOPER_IFACE_NAME);
1017 EINA_SAFETY_ON_NULL_RETURN(iface);
1019 void (*pf)(Eina_Model *);
1021 pf = eina_model_interface_method_resolve(iface, mdl, Pooper_Interface, poop);
1022 EINA_SAFETY_ON_NULL_RETURN(pf);
1026 INHER_CB_COUNT(_animal_poop);
1027 INHER_CB_COUNT(_human_poop);
1028 INHER_CB_COUNT(_animal_eat);
1029 INHER_CB_COUNT(_human_eat);
1031 START_TEST(eina_model_test_inheritance)
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;
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
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;
1055 const Eina_Model_Interface *ANIMAL_IFACES[] = {ANIMAL_POOPER_IFACE, NULL};
1056 const Eina_Model_Interface *HUMAN_IFACES[] = {HUMAN_POOPER_IFACE, NULL};
1058 /* Init Animal Type */
1059 Animal_Type _ANIMAL_TYPE;
1060 Eina_Model_Type *ANIMAL_TYPE = (Eina_Model_Type *) &_ANIMAL_TYPE;
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;
1071 ANIMAL_TYPE(type)->eat = _animal_eat;
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;
1084 ANIMAL_TYPE(type)->eat = _human_eat;
1086 Eina_Model *hm, *am;
1087 am = eina_model_new(ANIMAL_TYPE);
1088 hm = eina_model_new(HUMAN_TYPE);
1091 ck_assert_int_eq(_animal_eat_count, 1);
1093 ck_assert_int_eq(_human_eat_count, 1);
1096 ck_assert_int_eq(_animal_poop_count, 1);
1098 ck_assert_int_eq(_human_poop_count, 1);
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);
1105 ck_assert_int_eq(eina_model_refcount(am), 1);
1106 ck_assert_int_eq(eina_model_refcount(hm), 1);
1108 eina_model_unref(am);
1109 eina_model_unref(hm);
1116 _myproperties_load(Eina_Model *m)
1122 if (!eina_model_property_get(m, "load_count", &v))
1125 eina_value_get(&v, &count);
1127 eina_value_set(&v, count);
1129 ret = eina_model_property_set(m, "load_count", &v);
1130 eina_value_flush(&v);
1136 _myproperties_unload(Eina_Model *m)
1142 if (!eina_model_property_get(m, "load_count", &v))
1145 eina_value_get(&v, &count);
1147 eina_value_set(&v, count);
1149 ret = eina_model_property_set(m, "load_count", &v);
1150 eina_value_flush(&v);
1156 _mychildren_load(Eina_Model *m)
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);
1165 _mychildren_unload(Eina_Model *m)
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);
1172 START_TEST(eina_model_test_ifaces_load_unload)
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
1184 static Eina_Model_Type type;
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;
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;
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;
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;
1217 m = eina_model_new(&type);
1218 fail_unless(m != NULL);
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);
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);
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);
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);
1240 fail_unless(eina_model_load(m));
1241 fail_unless(eina_model_load(m));
1242 fail_unless(eina_model_load(m));
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);
1250 /* each load adds one child */
1251 ck_assert_int_eq(eina_model_child_count(m), 3);
1253 fail_unless(eina_model_unload(m));
1254 fail_unless(eina_model_unload(m));
1255 fail_unless(eina_model_unload(m));
1257 ck_assert_int_eq(count_loaded, 3);
1258 ck_assert_int_eq(count_unloaded, 3);
1260 ck_assert_int_eq(count_ploaded, 3);
1261 ck_assert_int_eq(count_punloaded, 3);
1263 ck_assert_int_eq(count_cloaded, 3);
1264 ck_assert_int_eq(count_cunloaded, 3);
1266 ck_assert_int_eq(eina_model_refcount(m), 1);
1267 eina_model_unref(m);
1274 eina_test_model(TCase *tc)
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);