Eo: Improved error messages. Show op as hex.
[profile/ivi/eobj.git] / tests / eo_test_general.c
1 #ifdef HAVE_CONFIG_H
2 # include "config.h"
3 #endif
4
5 #include <stdio.h>
6
7 #include "eo_suite.h"
8 #include "Eo.h"
9
10 #include "class_simple.h"
11
12 START_TEST(eo_simple)
13 {
14    eo_init();
15    Eo *obj = eo_add(EO_BASE_CLASS, NULL);
16    fail_if(obj);
17
18    eo_shutdown();
19 }
20 END_TEST
21
22 START_TEST(eo_data_fetch)
23 {
24    eo_init();
25
26    /* Usually should be const, not const only for the test... */
27    static Eo_Class_Description class_desc = {
28         "Simple2",
29         EO_CLASS_TYPE_REGULAR,
30         EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
31         NULL,
32         10,
33         NULL,
34         NULL,
35         NULL,
36         NULL
37    };
38
39    const Eo_Class *klass = eo_class_new(&class_desc, 0, EO_BASE_CLASS, NULL);
40    fail_if(!klass);
41
42    Eo *obj = eo_add(klass, NULL);
43    fail_if(!obj);
44 #ifndef NDEBUG
45    fail_if(eo_data_get(obj, SIMPLE_CLASS));
46 #endif
47    eo_unref(obj);
48
49    class_desc.data_size = 0;
50    klass = eo_class_new(&class_desc, 0, EO_BASE_CLASS, NULL);
51    fail_if(!klass);
52
53    obj = eo_add(klass, NULL);
54    fail_if(!obj);
55    fail_if(eo_data_get(obj, klass));
56    eo_unref(obj);
57
58    eo_shutdown();
59 }
60 END_TEST
61
62 START_TEST(eo_composite_tests)
63 {
64    eo_init();
65
66    Eo *obj = eo_add(SIMPLE_CLASS, NULL);
67    fail_if(!obj);
68    Eo *obj2 = eo_add(SIMPLE_CLASS, NULL);
69    fail_if(!obj2);
70
71    eo_composite_object_attach(obj, obj2);
72    eo_parent_set(obj2, NULL);
73    fail_if(eo_composite_is(obj2));
74
75    eo_unref(obj2);
76    eo_unref(obj);
77
78    eo_shutdown();
79 }
80 END_TEST
81
82 START_TEST(eo_static_classes)
83 {
84    eo_init();
85
86    static const Eo_Op_Description op_desc[] = {
87         EO_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "i", "Set property A"),
88         EO_OP_DESCRIPTION_SENTINEL
89    };
90
91    /* Usually should be const, not const only for the test... */
92    static Eo_Class_Description class_desc = {
93         "Simple2",
94         EO_CLASS_TYPE_REGULAR,
95         EO_CLASS_DESCRIPTION_OPS(NULL, op_desc, 1),
96         NULL,
97         0,
98         NULL,
99         NULL,
100         NULL,
101         NULL
102    };
103
104    const Eo_Class *klass = eo_class_new(&class_desc, 1, EO_BASE_CLASS, NULL);
105    fail_if(klass);
106
107    klass = eo_class_new(&class_desc, 1000, EO_BASE_CLASS, NULL);
108    fail_if(klass);
109
110    klass = eo_class_new(&class_desc, 2, EO_BASE_CLASS, NULL);
111    fail_if(!klass);
112
113    eo_shutdown();
114 }
115 END_TEST
116
117 static void
118 _man_con(Eo *obj, void *data EINA_UNUSED)
119 {
120    eo_manual_free_set(obj, EINA_TRUE);
121    eo_constructor_super(obj);
122 }
123
124 static void
125 _man_des(Eo *obj, void *data EINA_UNUSED)
126 {
127    eo_destructor_super(obj);
128    eo_manual_free_set(obj, EINA_FALSE);
129 }
130
131 START_TEST(eo_man_free)
132 {
133    eo_init();
134
135    /* Usually should be const, not const only for the test... */
136    static Eo_Class_Description class_desc = {
137         "Simple2",
138         EO_CLASS_TYPE_REGULAR,
139         EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
140         NULL,
141         10,
142         _man_con,
143         _man_des,
144         NULL,
145         NULL
146    };
147
148    const Eo_Class *klass = eo_class_new(&class_desc, 0, EO_BASE_CLASS, NULL);
149    fail_if(!klass);
150
151    Eo *obj = eo_add(klass, NULL);
152    fail_if(!obj);
153    eo_unref(obj);
154
155    obj = eo_add(klass, NULL);
156    fail_if(!obj);
157    eo_manual_free(obj);
158    eo_unref(obj);
159
160    class_desc.destructor = NULL;
161    klass = eo_class_new(&class_desc, 0, EO_BASE_CLASS, NULL);
162    fail_if(!klass);
163
164    obj = eo_add(klass, NULL);
165    fail_if(!obj);
166    eo_manual_free(obj);
167    eo_unref(obj);
168    eo_manual_free(obj);
169
170    obj = eo_add(klass, NULL);
171    fail_if(!obj);
172    eo_unref(obj);
173    eo_manual_free(obj);
174
175    class_desc.constructor = NULL;
176    klass = eo_class_new(&class_desc, 0, EO_BASE_CLASS, NULL);
177    fail_if(!klass);
178
179    obj = eo_add(klass, NULL);
180    fail_if(!obj);
181    eo_manual_free(obj);
182    eo_unref(obj);
183
184    eo_shutdown();
185 }
186 END_TEST
187
188 START_TEST(eo_refs)
189 {
190    eo_init();
191    Eo *obj = eo_add(SIMPLE_CLASS, NULL);
192    Eo *obj2 = eo_add(SIMPLE_CLASS, NULL);
193    Eo *obj3 = eo_add(SIMPLE_CLASS, NULL);
194
195    eo_xref(obj, obj2);
196    fail_if(eo_ref_get(obj) != 2);
197    eo_xref(obj, obj3);
198    fail_if(eo_ref_get(obj) != 3);
199
200    eo_xunref(obj, obj2);
201    fail_if(eo_ref_get(obj) != 2);
202    eo_xunref(obj, obj3);
203    fail_if(eo_ref_get(obj) != 1);
204
205 #ifndef NDEBUG
206    eo_xunref(obj, obj3);
207    fail_if(eo_ref_get(obj) != 1);
208
209    eo_xref(obj, obj2);
210    fail_if(eo_ref_get(obj) != 2);
211
212    eo_xunref(obj, obj3);
213    fail_if(eo_ref_get(obj) != 2);
214
215    eo_xunref(obj, obj2);
216    fail_if(eo_ref_get(obj) != 1);
217 #endif
218
219    /* Check we don't seg if there's an extra xref. */
220    eo_xref(obj, obj2);
221    eo_unref(obj);
222
223    eo_unref(obj);
224    eo_unref(obj2);
225    eo_unref(obj3);
226
227    /* Check hierarchy */
228    obj = eo_add(SIMPLE_CLASS, NULL);
229    obj2 = eo_add(SIMPLE_CLASS, obj);
230
231    Eo *wref;
232    eo_do(obj2, eo_wref_add(&wref));
233    fail_if(!wref);
234
235    eo_unref(obj2);
236
237    fail_if(!wref); /* Parent is still holding a reference. */
238
239    eo_unref(obj);
240
241    fail_if(wref);
242
243    /* Just check it doesn't seg atm. */
244    obj = eo_add(SIMPLE_CLASS, NULL);
245    eo_ref(obj);
246    eo_unref(obj);
247    eo_unref(obj);
248
249    obj = eo_add(SIMPLE_CLASS, NULL);
250    obj2 = eo_add(SIMPLE_CLASS, obj);
251    eo_unref(obj2);
252    eo_ref(obj2);
253    eo_del(obj2);
254    eo_unref(obj);
255
256    eo_shutdown();
257 }
258 END_TEST
259
260 START_TEST(eo_weak_reference)
261 {
262    eo_init();
263
264    Eo *obj = eo_add(SIMPLE_CLASS, NULL);
265    Eo *obj2 = eo_add(SIMPLE_CLASS, NULL);
266    Eo *wref, *wref2, *wref3;
267    eo_do(obj, eo_wref_add(&wref));
268    fail_if(!wref);
269
270    eo_unref(obj);
271    fail_if(wref);
272
273    obj = eo_add(SIMPLE_CLASS, NULL);
274    eo_do(obj, eo_wref_add(&wref));
275
276    eo_ref(obj);
277    fail_if(!wref);
278
279    eo_unref(obj);
280    fail_if(!wref);
281
282    eo_unref(obj);
283    fail_if(wref);
284
285    obj = eo_add(SIMPLE_CLASS, NULL);
286
287    eo_do(obj, eo_wref_add(&wref));
288    eo_do(obj, eo_wref_del(&wref));
289    fail_if(wref);
290
291    eo_do(obj, eo_wref_add(&wref));
292    eo_do(obj2, eo_wref_del(&wref));
293    fail_if(!wref);
294    eo_wref_del_safe(&wref);
295    fail_if(wref);
296
297    wref = obj;
298    eo_do(obj, eo_wref_del(&wref));
299    fail_if(wref);
300
301    wref = wref2 = wref3 = NULL;
302    eo_do(obj, eo_wref_add(&wref), eo_wref_add(&wref2), eo_wref_add(&wref3));
303    fail_if(!wref);
304    fail_if(!wref2);
305    fail_if(!wref3);
306    eo_do(obj, eo_wref_del(&wref), eo_wref_del(&wref2), eo_wref_del(&wref3));
307    fail_if(wref);
308    fail_if(wref2);
309    fail_if(wref3);
310
311    eo_do(obj, eo_wref_add(&wref2), eo_wref_add(&wref3));
312    wref = obj;
313    eo_do(obj, eo_wref_del(&wref));
314    fail_if(wref);
315    eo_do(obj, eo_wref_del(&wref2), eo_wref_del(&wref3));
316
317    eo_unref(obj);
318    eo_unref(obj2);
319
320
321    eo_shutdown();
322 }
323 END_TEST
324
325 static void
326 _a_set(Eo *obj EINA_UNUSED, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
327 {
328    fail_if(EINA_TRUE);
329 }
330
331 static void
332 _op_errors_class_constructor(Eo_Class *klass)
333 {
334    const Eo_Op_Func_Description func_desc[] = {
335         EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_LAST), _a_set),
336         EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_LAST + 1), _a_set),
337         EO_OP_FUNC(0x0F010111, _a_set),
338         EO_OP_FUNC_SENTINEL
339    };
340
341    eo_class_funcs_set(klass, func_desc);
342 }
343
344 START_TEST(eo_op_errors)
345 {
346    eo_init();
347
348    static const Eo_Class_Description class_desc = {
349         "Simple",
350         EO_CLASS_TYPE_REGULAR,
351         EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
352         NULL,
353         0,
354         NULL,
355         NULL,
356         _op_errors_class_constructor,
357         NULL
358    };
359
360    const Eo_Class *klass = eo_class_new(&class_desc, 0, SIMPLE_CLASS, NULL);
361    fail_if(!klass);
362
363    Eo *obj = eo_add(klass, NULL);
364
365    /* Out of bounds op for a legal class. */
366    fail_if(eo_do(obj, EO_BASE_ID(0x0111)));
367
368    /* Ilegal class. */
369    fail_if(eo_do(obj, 0x0F010111));
370
371    fail_if(eo_ref_get(obj) != 1);
372
373    eo_ref(obj);
374    fail_if(eo_ref_get(obj) != 2);
375
376    eo_ref(obj);
377    fail_if(eo_ref_get(obj) != 3);
378
379    eo_unref(obj);
380    fail_if(eo_ref_get(obj) != 2);
381
382    eo_unref(obj);
383    fail_if(eo_ref_get(obj) != 1);
384
385    eo_unref(obj);
386
387    obj = eo_add(SIMPLE_CLASS, NULL);
388    fail_if(!eo_do(obj, simple_a_print()));
389    fail_if(!eo_query(obj, simple_a_print()));
390    fail_if(eo_query(obj, simple_a_set(1)));
391    eo_unref(obj);
392
393    eo_shutdown();
394 }
395 END_TEST
396
397 static void
398 _fake_free_func(void *data)
399 {
400    if (!data)
401       return;
402
403    int *a = data;
404    ++*a;
405 }
406
407 START_TEST(eo_generic_data)
408 {
409    eo_init();
410    Eo *obj = eo_add(SIMPLE_CLASS, NULL);
411    void *data;
412
413    eo_do(obj, eo_base_data_set("test1", (void *) 1, NULL));
414    eo_do(obj, eo_base_data_get("test1", &data));
415    fail_if(1 != (int) data);
416    eo_do(obj, eo_base_data_del("test1"));
417    eo_do(obj, eo_base_data_get("test1", &data));
418    fail_if(data);
419
420    eo_do(obj, eo_base_data_set("test1", (void *) 1, NULL));
421    eo_do(obj, eo_base_data_set("test2", (void *) 2, NULL));
422    eo_do(obj, eo_base_data_get("test1", &data));
423    fail_if(1 != (int) data);
424    eo_do(obj, eo_base_data_get("test2", &data));
425    fail_if(2 != (int) data);
426
427    eo_do(obj, eo_base_data_get("test2", &data));
428    fail_if(2 != (int) data);
429    eo_do(obj, eo_base_data_del("test2"));
430    eo_do(obj, eo_base_data_get("test2", &data));
431    fail_if(data);
432
433    eo_do(obj, eo_base_data_get("test1", &data));
434    fail_if(1 != (int) data);
435    eo_do(obj, eo_base_data_del("test1"));
436    eo_do(obj, eo_base_data_get("test1", &data));
437    fail_if(data);
438
439    int a = 0;
440    eo_do(obj, eo_base_data_set("test3", &a, _fake_free_func));
441    eo_do(obj, eo_base_data_get("test3", &data));
442    fail_if(&a != data);
443    eo_do(obj, eo_base_data_get("test3", NULL));
444    eo_do(obj, eo_base_data_del("test3"));
445    fail_if(a != 1);
446
447    a = 0;
448    eo_do(obj, eo_base_data_set("test3", &a, _fake_free_func));
449    eo_do(obj, eo_base_data_set("test3", NULL, _fake_free_func));
450    fail_if(a != 1);
451    a = 0;
452    data = (void *) 123;
453    eo_do(obj, eo_base_data_set(NULL, &a, _fake_free_func));
454    eo_do(obj, eo_base_data_get(NULL, &data));
455    fail_if(data);
456    eo_do(obj, eo_base_data_del(NULL));
457
458    a = 0;
459    eo_do(obj, eo_base_data_set("test3", &a, _fake_free_func));
460    eo_do(obj, eo_base_data_set("test3", NULL, NULL));
461    fail_if(a != 1);
462    eo_do(obj, eo_base_data_set("test3", &a, _fake_free_func));
463
464    eo_unref(obj);
465    fail_if(a != 2);
466
467    eo_shutdown();
468 }
469 END_TEST
470
471 START_TEST(eo_magic_checks)
472 {
473    char _buf[sizeof(long)]; /* Just enough to hold eina magic + a bit more. */
474    char *buf = _buf;
475    eo_init();
476
477    memset(_buf, 1, sizeof(_buf));
478
479    Eo *obj = eo_add(SIMPLE_CLASS, (Eo *) buf);
480    fail_if(obj);
481
482    while (1)
483      {
484         obj = eo_add((Eo_Class *) buf, NULL);
485         fail_if(obj);
486
487         obj = eo_add(SIMPLE_CLASS, NULL);
488         fail_if(!obj);
489
490         fail_if(eo_do((Eo *) buf, EO_NOOP));
491         fail_if(eo_do_super((Eo *) buf, EO_NOOP));
492         fail_if(eo_class_get((Eo *) buf));
493         fail_if(eo_class_name_get((Eo_Class*) buf));
494         eo_class_funcs_set((Eo_Class *) buf, NULL);
495         eo_class_do((Eo_Class *) buf, NULL);
496         eo_class_do_super((Eo_Class *) buf, EO_NOOP);
497
498         fail_if(eo_class_new(NULL, 0, (Eo_Class *) buf), NULL);
499
500         eo_xref(obj, (Eo *) buf);
501         eo_xunref(obj, (Eo *) buf);
502         eo_xref((Eo *) buf, obj);
503         eo_xunref((Eo *) buf, obj);
504
505         eo_ref((Eo *) buf);
506         eo_unref((Eo *) buf);
507         eo_del((Eo *) buf);
508
509         fail_if(0 != eo_ref_get((Eo *) buf));
510
511         Eo *wref = NULL;
512         eo_do((Eo *) buf, eo_wref_add(&wref));
513         fail_if(wref);
514
515         fail_if(eo_parent_get((Eo *) buf));
516
517         eo_error_set((Eo *) buf);
518
519         eo_constructor_super((Eo *) buf);
520         eo_destructor_super((Eo *) buf);
521
522         fail_if(eo_data_get((Eo *) buf, SIMPLE_CLASS));
523
524         eo_composite_object_attach((Eo *) buf, obj);
525         eo_composite_object_attach(obj, (Eo *) buf);
526         eo_composite_object_detach((Eo *) buf, obj);
527         eo_composite_object_detach(obj, (Eo *) buf);
528         eo_composite_is((Eo *) buf);
529
530         eo_do(obj, eo_event_callback_forwarder_add(NULL, (Eo *) buf));
531         eo_do(obj, eo_event_callback_forwarder_del(NULL, (Eo *) buf));
532
533         eo_manual_free_set((Eo *) buf, EINA_TRUE);
534         eo_manual_free((Eo *) buf);
535
536         eo_unref(obj);
537
538         if (!buf)
539            break;
540         else
541            buf = NULL;
542      }
543
544    eo_shutdown();
545 }
546 END_TEST
547
548 void eo_test_general(TCase *tc)
549 {
550    tcase_add_test(tc, eo_generic_data);
551    tcase_add_test(tc, eo_op_errors);
552    tcase_add_test(tc, eo_simple);
553    tcase_add_test(tc, eo_weak_reference);
554    tcase_add_test(tc, eo_refs);
555    tcase_add_test(tc, eo_magic_checks);
556    tcase_add_test(tc, eo_data_fetch);
557    tcase_add_test(tc, eo_man_free);
558    tcase_add_test(tc, eo_static_classes);
559    tcase_add_test(tc, eo_composite_tests);
560 }