Eo: Added a check if object is already deleted in eo_unref.
[profile/ivi/eobj.git] / tests / eo_test_general.c
index dfc7663..30a5cb6 100644 (file)
@@ -36,7 +36,7 @@ START_TEST(eo_data_fetch)
         NULL
    };
 
-   const Eo_Class *klass = eo_class_new(&class_desc, EO_BASE_CLASS, NULL);
+   const Eo_Class *klass = eo_class_new(&class_desc, 0, EO_BASE_CLASS, NULL);
    fail_if(!klass);
 
    Eo *obj = eo_add(klass, NULL);
@@ -47,7 +47,7 @@ START_TEST(eo_data_fetch)
    eo_unref(obj);
 
    class_desc.data_size = 0;
-   klass = eo_class_new(&class_desc, EO_BASE_CLASS, NULL);
+   klass = eo_class_new(&class_desc, 0, EO_BASE_CLASS, NULL);
    fail_if(!klass);
 
    obj = eo_add(klass, NULL);
@@ -59,6 +59,141 @@ START_TEST(eo_data_fetch)
 }
 END_TEST
 
+START_TEST(eo_composite_tests)
+{
+   eo_init();
+
+   Eo *obj = eo_add(SIMPLE_CLASS, NULL);
+   fail_if(!obj);
+   Eo *obj2 = eo_add(SIMPLE_CLASS, NULL);
+   fail_if(!obj2);
+
+   eo_composite_object_attach(obj, obj2);
+   eo_parent_set(obj2, NULL);
+   fail_if(eo_composite_is(obj2));
+
+   eo_unref(obj2);
+   eo_unref(obj);
+
+   eo_shutdown();
+}
+END_TEST
+
+START_TEST(eo_static_classes)
+{
+   eo_init();
+
+   static const Eo_Op_Description op_desc[] = {
+        EO_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "i", "Set property A"),
+        EO_OP_DESCRIPTION_SENTINEL
+   };
+
+   /* Usually should be const, not const only for the test... */
+   static Eo_Class_Description class_desc = {
+        "Simple2",
+        EO_CLASS_TYPE_REGULAR,
+        EO_CLASS_DESCRIPTION_OPS(NULL, op_desc, 1),
+        NULL,
+        0,
+        NULL,
+        NULL,
+        NULL,
+        NULL
+   };
+
+   const Eo_Class *klass = eo_class_new(&class_desc, 1, EO_BASE_CLASS, NULL);
+   fail_if(klass);
+
+   klass = eo_class_new(&class_desc, 1000, EO_BASE_CLASS, NULL);
+   fail_if(klass);
+
+   klass = eo_class_new(&class_desc, 2, EO_BASE_CLASS, NULL);
+   fail_if(!klass);
+
+   eo_shutdown();
+}
+END_TEST
+
+static void
+_man_con(Eo *obj, void *data EINA_UNUSED)
+{
+   eo_manual_free_set(obj, EINA_TRUE);
+   eo_constructor_super(obj);
+}
+
+static void
+_man_des(Eo *obj, void *data EINA_UNUSED)
+{
+   eo_destructor_super(obj);
+   eo_manual_free_set(obj, EINA_FALSE);
+}
+
+START_TEST(eo_man_free)
+{
+   eo_init();
+
+   /* Usually should be const, not const only for the test... */
+   static Eo_Class_Description class_desc = {
+        "Simple2",
+        EO_CLASS_TYPE_REGULAR,
+        EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
+        NULL,
+        10,
+        _man_con,
+        _man_des,
+        NULL,
+        NULL
+   };
+
+   const Eo_Class *klass = eo_class_new(&class_desc, 0, EO_BASE_CLASS, NULL);
+   fail_if(!klass);
+
+   Eo *obj = eo_add(klass, NULL);
+   fail_if(!obj);
+   eo_unref(obj);
+
+   obj = eo_add(klass, NULL);
+   fail_if(!obj);
+   eo_manual_free(obj);
+   eo_unref(obj);
+
+   class_desc.destructor = NULL;
+   klass = eo_class_new(&class_desc, 0, EO_BASE_CLASS, NULL);
+   fail_if(!klass);
+
+   obj = eo_add(klass, NULL);
+   fail_if(!obj);
+   eo_manual_free(obj);
+   eo_unref(obj);
+   eo_manual_free(obj);
+
+   obj = eo_add(klass, NULL);
+   fail_if(!obj);
+   eo_unref(obj);
+   eo_manual_free(obj);
+
+   class_desc.constructor = NULL;
+   klass = eo_class_new(&class_desc, 0, EO_BASE_CLASS, NULL);
+   fail_if(!klass);
+
+   obj = eo_add(klass, NULL);
+   fail_if(!obj);
+   eo_manual_free(obj);
+   eo_unref(obj);
+
+   obj = eo_add(klass, NULL);
+   fail_if(!obj);
+   eo_manual_free_set(obj, EINA_TRUE);
+   eo_unref(obj);
+   eo_ref(obj);
+   eo_unref(obj);
+   eo_unref(obj);
+   eo_manual_free(obj);
+
+   eo_shutdown();
+}
+END_TEST
+
 START_TEST(eo_refs)
 {
    eo_init();
@@ -90,15 +225,42 @@ START_TEST(eo_refs)
    fail_if(eo_ref_get(obj) != 1);
 #endif
 
+   /* Check we don't seg if there's an extra xref. */
+   eo_xref(obj, obj2);
+   eo_unref(obj);
+
    eo_unref(obj);
    eo_unref(obj2);
    eo_unref(obj3);
 
+   /* Check hierarchy */
+   obj = eo_add(SIMPLE_CLASS, NULL);
+   obj2 = eo_add(SIMPLE_CLASS, obj);
+
+   Eo *wref;
+   eo_do(obj2, eo_wref_add(&wref));
+   fail_if(!wref);
+
+   eo_unref(obj2);
+
+   fail_if(!wref); /* Parent is still holding a reference. */
+
+   eo_unref(obj);
+
+   fail_if(wref);
+
    /* Just check it doesn't seg atm. */
    obj = eo_add(SIMPLE_CLASS, NULL);
    eo_ref(obj);
-   eo_del(obj);
-   eo_del(obj);
+   eo_unref(obj);
+   eo_unref(obj);
+
+   obj = eo_add(SIMPLE_CLASS, NULL);
+   obj2 = eo_add(SIMPLE_CLASS, obj);
+   eo_unref(obj2);
+   eo_ref(obj2);
+   eo_del(obj2);
+   eo_unref(obj);
 
    eo_shutdown();
 }
@@ -123,8 +285,8 @@ START_TEST(eo_weak_reference)
    eo_ref(obj);
    fail_if(!wref);
 
-   eo_del(obj);
-   fail_if(wref);
+   eo_unref(obj);
+   fail_if(!wref);
 
    eo_unref(obj);
    fail_if(wref);
@@ -204,13 +366,13 @@ START_TEST(eo_op_errors)
         NULL
    };
 
-   const Eo_Class *klass = eo_class_new(&class_desc, SIMPLE_CLASS, NULL);
+   const Eo_Class *klass = eo_class_new(&class_desc, 0, SIMPLE_CLASS, NULL);
    fail_if(!klass);
 
    Eo *obj = eo_add(klass, NULL);
 
    /* Out of bounds op for a legal class. */
-   fail_if(eo_do(obj, 0x00010111));
+   fail_if(eo_do(obj, EO_BASE_ID(0x0111)));
 
    /* Ilegal class. */
    fail_if(eo_do(obj, 0x0F010111));
@@ -235,6 +397,7 @@ START_TEST(eo_op_errors)
    fail_if(!eo_do(obj, simple_a_print()));
    fail_if(!eo_query(obj, simple_a_print()));
    fail_if(eo_query(obj, simple_a_set(1)));
+   eo_unref(obj);
 
    eo_shutdown();
 }
@@ -316,63 +479,76 @@ END_TEST
 
 START_TEST(eo_magic_checks)
 {
-   char buf[sizeof(long)]; /* Just enough to hold eina magic + a bit more. */
+   char _buf[sizeof(long)]; /* Just enough to hold eina magic + a bit more. */
+   char *buf = _buf;
    eo_init();
 
-   memset(buf, 1, sizeof(buf));
-   Eo *obj = eo_add((Eo_Class *) buf, NULL);
-   fail_if(obj);
+   memset(_buf, 1, sizeof(_buf));
 
-   obj = eo_add(SIMPLE_CLASS, (Eo *) buf);
+   Eo *obj = eo_add(SIMPLE_CLASS, (Eo *) buf);
    fail_if(obj);
 
-   obj = eo_add(SIMPLE_CLASS, NULL);
-   fail_if(!obj);
+   while (1)
+     {
+        obj = eo_add((Eo_Class *) buf, NULL);
+        fail_if(obj);
 
-   fail_if(eo_do((Eo *) buf, EO_NOOP));
-   fail_if(eo_do_super((Eo *) buf, EO_NOOP));
-   fail_if(eo_class_get((Eo *) buf));
-   fail_if(eo_class_name_get((Eo_Class*) buf));
-   eo_class_funcs_set((Eo_Class *) buf, NULL);
+        obj = eo_add(SIMPLE_CLASS, NULL);
+        fail_if(!obj);
 
-   fail_if(eo_class_new(NULL, (Eo_Class *) buf), NULL);
+        fail_if(eo_do((Eo *) buf, EO_NOOP));
+        fail_if(eo_do_super((Eo *) buf, EO_NOOP));
+        fail_if(eo_class_get((Eo *) buf));
+        fail_if(eo_class_name_get((Eo_Class*) buf));
+        eo_class_funcs_set((Eo_Class *) buf, NULL);
+        eo_class_do((Eo_Class *) buf, NULL);
+        eo_class_do_super((Eo_Class *) buf, EO_NOOP);
 
-   eo_xref(obj, (Eo *) buf);
-   eo_xunref(obj, (Eo *) buf);
-   eo_xref((Eo *) buf, obj);
-   eo_xunref((Eo *) buf, obj);
+        fail_if(eo_class_new(NULL, 0, (Eo_Class *) buf), NULL);
 
-   eo_ref((Eo *) buf);
-   eo_unref((Eo *) buf);
+        eo_xref(obj, (Eo *) buf);
+        eo_xunref(obj, (Eo *) buf);
+        eo_xref((Eo *) buf, obj);
+        eo_xunref((Eo *) buf, obj);
 
-   fail_if(0 != eo_ref_get((Eo *) buf));
+        eo_ref((Eo *) buf);
+        eo_unref((Eo *) buf);
+        eo_del((Eo *) buf);
 
-   Eo *wref = NULL;
-   eo_do((Eo *) buf, eo_wref_add(&wref));
-   fail_if(wref);
+        fail_if(0 != eo_ref_get((Eo *) buf));
 
-   eo_del((Eo *) buf);
+        Eo *wref = NULL;
+        eo_do((Eo *) buf, eo_wref_add(&wref));
+        fail_if(wref);
 
-   fail_if(eo_parent_get((Eo *) buf));
+        fail_if(eo_parent_get((Eo *) buf));
 
-   eo_constructor_error_set((Eo *) buf);
-   fail_if(!eo_constructor_error_get((Eo *) buf));
+        eo_error_set((Eo *) buf);
 
-   eo_constructor_super((Eo *) buf);
-   eo_destructor_super((Eo *) buf);
+        eo_constructor_super((Eo *) buf);
+        eo_destructor_super((Eo *) buf);
 
-   fail_if(eo_data_get((Eo *) buf, SIMPLE_CLASS));
+        fail_if(eo_data_get((Eo *) buf, SIMPLE_CLASS));
 
-   eo_composite_object_attach((Eo *) buf, obj);
-   eo_composite_object_attach(obj, (Eo *) buf);
-   eo_composite_object_detach((Eo *) buf, obj);
-   eo_composite_object_detach(obj, (Eo *) buf);
-   eo_composite_is((Eo *) buf);
+        eo_composite_object_attach((Eo *) buf, obj);
+        eo_composite_object_attach(obj, (Eo *) buf);
+        eo_composite_object_detach((Eo *) buf, obj);
+        eo_composite_object_detach(obj, (Eo *) buf);
+        eo_composite_is((Eo *) buf);
 
-   eo_do(obj, eo_event_callback_forwarder_add(NULL, (Eo *) buf));
-   eo_do(obj, eo_event_callback_forwarder_del(NULL, (Eo *) buf));
+        eo_do(obj, eo_event_callback_forwarder_add(NULL, (Eo *) buf));
+        eo_do(obj, eo_event_callback_forwarder_del(NULL, (Eo *) buf));
 
-   eo_unref(obj);
+        eo_manual_free_set((Eo *) buf, EINA_TRUE);
+        eo_manual_free((Eo *) buf);
+
+        eo_unref(obj);
+
+        if (!buf)
+           break;
+        else
+           buf = NULL;
+     }
 
    eo_shutdown();
 }
@@ -387,4 +563,7 @@ void eo_test_general(TCase *tc)
    tcase_add_test(tc, eo_refs);
    tcase_add_test(tc, eo_magic_checks);
    tcase_add_test(tc, eo_data_fetch);
+   tcase_add_test(tc, eo_man_free);
+   tcase_add_test(tc, eo_static_classes);
+   tcase_add_test(tc, eo_composite_tests);
 }