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