aboutsummaryrefslogtreecommitdiffstats
path: root/src/tests
diff options
context:
space:
mode:
authorVincent Torri <vincent.torri@gmail.com>2012-09-26 06:56:52 +0000
committerVincent Torri <vincent.torri@gmail.com>2012-09-26 06:56:52 +0000
commit3b5a3448b7dfc53c2f129bdb04bea9f7a02741a6 (patch)
tree18ad8a6b1841e9832c85a46f887b2cd6d6dacc4b /src/tests
parent195d31c73fef88cfaa803b07b2ae3cba983a4093 (diff)
downloadefl-3b5a3448b7dfc53c2f129bdb04bea9f7a02741a6.tar.gz
efl-3b5a3448b7dfc53c2f129bdb04bea9f7a02741a6.tar.xz
efl-3b5a3448b7dfc53c2f129bdb04bea9f7a02741a6.zip
merge: add eo
SVN revision: 77072
Diffstat (limited to 'src/tests')
-rw-r--r--src/tests/Makefile.am6
-rw-r--r--src/tests/eo/Makefile.am126
-rw-r--r--src/tests/eo/access/access_inherit.c49
-rw-r--r--src/tests/eo/access/access_inherit.h18
-rw-r--r--src/tests/eo/access/access_main.c27
-rw-r--r--src/tests/eo/access/access_simple.c70
-rw-r--r--src/tests/eo/access/access_simple.h26
-rw-r--r--src/tests/eo/access/access_simple_protected.h10
-rw-r--r--src/tests/eo/composite_objects/composite_objects_comp.c65
-rw-r--r--src/tests/eo/composite_objects/composite_objects_comp.h7
-rw-r--r--src/tests/eo/composite_objects/composite_objects_main.c65
-rw-r--r--src/tests/eo/composite_objects/composite_objects_simple.c71
-rw-r--r--src/tests/eo/composite_objects/composite_objects_simple.h28
-rw-r--r--src/tests/eo/constructors/constructors_main.c79
-rw-r--r--src/tests/eo/constructors/constructors_mixin.c70
-rw-r--r--src/tests/eo/constructors/constructors_mixin.h18
-rw-r--r--src/tests/eo/constructors/constructors_simple.c124
-rw-r--r--src/tests/eo/constructors/constructors_simple.h26
-rw-r--r--src/tests/eo/constructors/constructors_simple2.c42
-rw-r--r--src/tests/eo/constructors/constructors_simple2.h7
-rw-r--r--src/tests/eo/constructors/constructors_simple3.c40
-rw-r--r--src/tests/eo/constructors/constructors_simple3.h7
-rw-r--r--src/tests/eo/constructors/constructors_simple4.c24
-rw-r--r--src/tests/eo/constructors/constructors_simple4.h7
-rw-r--r--src/tests/eo/constructors/constructors_simple5.c40
-rw-r--r--src/tests/eo/constructors/constructors_simple5.h7
-rw-r--r--src/tests/eo/constructors/constructors_simple6.c42
-rw-r--r--src/tests/eo/constructors/constructors_simple6.h7
-rw-r--r--src/tests/eo/constructors/constructors_simple7.c43
-rw-r--r--src/tests/eo/constructors/constructors_simple7.h7
-rw-r--r--src/tests/eo/eunit_tests.h17
-rw-r--r--src/tests/eo/function_overrides/function_overrides_inherit.c22
-rw-r--r--src/tests/eo/function_overrides/function_overrides_inherit.h7
-rw-r--r--src/tests/eo/function_overrides/function_overrides_inherit2.c82
-rw-r--r--src/tests/eo/function_overrides/function_overrides_inherit2.h20
-rw-r--r--src/tests/eo/function_overrides/function_overrides_inherit3.c44
-rw-r--r--src/tests/eo/function_overrides/function_overrides_inherit3.h7
-rw-r--r--src/tests/eo/function_overrides/function_overrides_main.c63
-rw-r--r--src/tests/eo/function_overrides/function_overrides_simple.c82
-rw-r--r--src/tests/eo/function_overrides/function_overrides_simple.h32
-rw-r--r--src/tests/eo/interface/interface_interface.c30
-rw-r--r--src/tests/eo/interface/interface_interface.h24
-rw-r--r--src/tests/eo/interface/interface_interface2.c31
-rw-r--r--src/tests/eo/interface/interface_interface2.h24
-rw-r--r--src/tests/eo/interface/interface_main.c37
-rw-r--r--src/tests/eo/interface/interface_simple.c100
-rw-r--r--src/tests/eo/interface/interface_simple.h47
-rw-r--r--src/tests/eo/mixin/mixin_inherit.c42
-rw-r--r--src/tests/eo/mixin/mixin_inherit.h7
-rw-r--r--src/tests/eo/mixin/mixin_main.c47
-rw-r--r--src/tests/eo/mixin/mixin_mixin.c67
-rw-r--r--src/tests/eo/mixin/mixin_mixin.h24
-rw-r--r--src/tests/eo/mixin/mixin_mixin2.c70
-rw-r--r--src/tests/eo/mixin/mixin_mixin2.h12
-rw-r--r--src/tests/eo/mixin/mixin_mixin3.c70
-rw-r--r--src/tests/eo/mixin/mixin_mixin3.h12
-rw-r--r--src/tests/eo/mixin/mixin_mixin4.c26
-rw-r--r--src/tests/eo/mixin/mixin_mixin4.h7
-rw-r--r--src/tests/eo/mixin/mixin_simple.c77
-rw-r--r--src/tests/eo/mixin/mixin_simple.h47
-rw-r--r--src/tests/eo/signals/signals_main.c183
-rw-r--r--src/tests/eo/signals/signals_simple.c112
-rw-r--r--src/tests/eo/signals/signals_simple.h31
-rw-r--r--src/tests/eo/suite/eo_suite.c106
-rw-r--r--src/tests/eo/suite/eo_suite.h11
-rw-r--r--src/tests/eo/suite/eo_test_class_errors.c350
-rw-r--r--src/tests/eo/suite/eo_test_class_simple.c69
-rw-r--r--src/tests/eo/suite/eo_test_class_simple.h30
-rw-r--r--src/tests/eo/suite/eo_test_general.c752
-rw-r--r--src/tests/eo/suite/eo_test_init.c22
70 files changed, 4001 insertions, 0 deletions
diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am
index 8d718c808..4598ce34a 100644
--- a/src/tests/Makefile.am
+++ b/src/tests/Makefile.am
@@ -7,3 +7,9 @@ if EFL_BUILD_EET
SUBDIRS += eet
endif
+
+if EFL_BUILD_EO
+
+SUBDIRS += eo
+
+endif
diff --git a/src/tests/eo/Makefile.am b/src/tests/eo/Makefile.am
new file mode 100644
index 000000000..15241bb08
--- /dev/null
+++ b/src/tests/eo/Makefile.am
@@ -0,0 +1,126 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I$(top_srcdir)/src/lib/eo \
+-I$(top_builddir)/src/lib/eo \
+@EFL_EO_BUILD@ \
+@EO_CFLAGS@ \
+@CHECK_CFLAGS@
+
+check_PROGRAMS = \
+test_access \
+test_composite_objects \
+test_constructors \
+test_function_overrides \
+test_interface \
+test_mixin \
+test_signals
+
+if EFL_ENABLE_TESTS
+check_PROGRAMS += eo_suite
+endif
+
+test_access_SOURCES = \
+access/access_inherit.c \
+access/access_inherit.h \
+access/access_main.c \
+access/access_simple.c \
+access/access_simple.h \
+access/access_simple_protected.h
+
+test_access_LDADD = $(top_builddir)/src/lib/eo/libeo.la @EO_LIBS@
+
+test_composite_objects_SOURCES = \
+composite_objects/composite_objects_comp.c \
+composite_objects/composite_objects_comp.h \
+composite_objects/composite_objects_main.c \
+composite_objects/composite_objects_simple.c \
+composite_objects/composite_objects_simple.h
+
+test_composite_objects_LDADD = $(top_builddir)/src/lib/eo/libeo.la @EO_LIBS@
+
+test_constructors_SOURCES = \
+constructors/constructors_main.c \
+constructors/constructors_mixin.c \
+constructors/constructors_mixin.h \
+constructors/constructors_simple.c \
+constructors/constructors_simple.h \
+constructors/constructors_simple2.c \
+constructors/constructors_simple2.h \
+constructors/constructors_simple3.c \
+constructors/constructors_simple3.h \
+constructors/constructors_simple4.c \
+constructors/constructors_simple4.h \
+constructors/constructors_simple5.c \
+constructors/constructors_simple5.h \
+constructors/constructors_simple6.c \
+constructors/constructors_simple6.h \
+constructors/constructors_simple7.c \
+constructors/constructors_simple7.h
+
+test_constructors_LDADD = $(top_builddir)/src/lib/eo/libeo.la @EO_LIBS@
+
+if EFL_ENABLE_TESTS
+
+eo_suite_SOURCES = \
+suite/eo_test_class_simple.c \
+suite/eo_test_class_simple.h \
+suite/eo_suite.c \
+suite/eo_suite.h \
+suite/eo_test_class_errors.c \
+suite/eo_test_general.c \
+suite/eo_test_init.c
+
+eo_suite_LDADD = $(top_builddir)/src/lib/eo/libeo.la @EO_LIBS@ @CHECK_LIBS@
+
+endif
+
+test_function_overrides_SOURCES = \
+function_overrides/function_overrides_inherit.c \
+function_overrides/function_overrides_inherit.h \
+function_overrides/function_overrides_inherit2.c \
+function_overrides/function_overrides_inherit2.h \
+function_overrides/function_overrides_inherit3.c \
+function_overrides/function_overrides_inherit3.h \
+function_overrides/function_overrides_main.c \
+function_overrides/function_overrides_simple.c \
+function_overrides/function_overrides_simple.h
+
+test_function_overrides_LDADD = $(top_builddir)/src/lib/eo/libeo.la @EO_LIBS@
+
+test_interface_SOURCES = \
+interface/interface_interface.c \
+interface/interface_interface.h \
+interface/interface_interface2.c \
+interface/interface_interface2.h \
+interface/interface_main.c \
+interface/interface_simple.c \
+interface/interface_simple.h
+
+test_interface_LDADD = $(top_builddir)/src/lib/eo/libeo.la @EO_LIBS@
+
+test_mixin_SOURCES = \
+mixin/mixin_inherit.c \
+mixin/mixin_inherit.h \
+mixin/mixin_main.c \
+mixin/mixin_mixin.c \
+mixin/mixin_mixin.h \
+mixin/mixin_mixin2.c \
+mixin/mixin_mixin2.h \
+mixin/mixin_mixin3.c \
+mixin/mixin_mixin3.h \
+mixin/mixin_mixin4.c \
+mixin/mixin_mixin4.h \
+mixin/mixin_simple.c \
+mixin/mixin_simple.h
+
+test_mixin_LDADD = $(top_builddir)/src/lib/eo/libeo.la @EO_LIBS@
+
+test_signals_SOURCES = \
+signals/signals_main.c \
+signals/signals_simple.c \
+signals/signals_simple.h
+
+test_signals_LDADD = $(top_builddir)/src/lib/eo/libeo.la @EO_LIBS@
+
+EXTRA_DIST = eunit_tests.h
diff --git a/src/tests/eo/access/access_inherit.c b/src/tests/eo/access/access_inherit.c
new file mode 100644
index 000000000..4d1c81efc
--- /dev/null
+++ b/src/tests/eo/access/access_inherit.c
@@ -0,0 +1,49 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "access_simple.h"
+#include "access_simple_protected.h"
+#include "access_inherit.h"
+
+EAPI Eo_Op INHERIT_BASE_ID = 0;
+
+#define MY_CLASS INHERIT_CLASS
+
+static void
+_prot_print(Eo *obj, void *class_data EINA_UNUSED, va_list *list)
+{
+ Simple_Protected_Data *pd = eo_data_get(obj, SIMPLE_CLASS);
+ (void) list;
+ printf("%s %d\n", __func__, pd->protected_x1);
+}
+
+static void
+_class_constructor(Eo_Class *klass)
+{
+ const Eo_Op_Func_Description func_desc[] = {
+ EO_OP_FUNC(INHERIT_ID(INHERIT_SUB_ID_PROT_PRINT), _prot_print),
+ EO_OP_FUNC_SENTINEL
+ };
+
+ eo_class_funcs_set(klass, func_desc);
+}
+
+static const Eo_Op_Description op_desc[] = {
+ EO_OP_DESCRIPTION(INHERIT_SUB_ID_PROT_PRINT, "Print protected var x1."),
+ EO_OP_DESCRIPTION_SENTINEL
+};
+
+static const Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Inherit",
+ EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(&INHERIT_BASE_ID, op_desc, INHERIT_SUB_ID_LAST),
+ NULL,
+ 0,
+ _class_constructor,
+ NULL
+};
+
+EO_DEFINE_CLASS(inherit_class_get, &class_desc, SIMPLE_CLASS, NULL)
diff --git a/src/tests/eo/access/access_inherit.h b/src/tests/eo/access/access_inherit.h
new file mode 100644
index 000000000..f701dae48
--- /dev/null
+++ b/src/tests/eo/access/access_inherit.h
@@ -0,0 +1,18 @@
+#ifndef INHERIT_H
+#define INHERIT_H
+
+extern EAPI Eo_Op INHERIT_BASE_ID;
+
+enum {
+ INHERIT_SUB_ID_PROT_PRINT,
+ INHERIT_SUB_ID_LAST
+};
+
+#define INHERIT_ID(sub_id) (INHERIT_BASE_ID + sub_id)
+
+#define inherit_prot_print() INHERIT_ID(INHERIT_SUB_ID_PROT_PRINT)
+
+#define INHERIT_CLASS inherit_class_get()
+const Eo_Class *inherit_class_get(void);
+
+#endif
diff --git a/src/tests/eo/access/access_main.c b/src/tests/eo/access/access_main.c
new file mode 100644
index 000000000..474f3b9a4
--- /dev/null
+++ b/src/tests/eo/access/access_main.c
@@ -0,0 +1,27 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "access_simple.h"
+#include "access_inherit.h"
+
+int
+main(int argc, char *argv[])
+{
+ (void) argc;
+ (void) argv;
+ eo_init();
+
+ Eo *obj = eo_add(INHERIT_CLASS, NULL);
+
+ eo_do(obj, simple_a_set(1), inherit_prot_print());
+
+ Simple_Public_Data *pd = eo_data_get(obj, SIMPLE_CLASS);
+ printf("Pub: %d\n", pd->public_x2);
+
+ eo_unref(obj);
+ eo_shutdown();
+ return 0;
+}
+
diff --git a/src/tests/eo/access/access_simple.c b/src/tests/eo/access/access_simple.c
new file mode 100644
index 000000000..42fa259e4
--- /dev/null
+++ b/src/tests/eo/access/access_simple.c
@@ -0,0 +1,70 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "access_simple.h"
+#include "access_simple_protected.h"
+
+EAPI Eo_Op SIMPLE_BASE_ID = 0;
+
+typedef struct
+{
+ Simple_Protected_Data protected;
+ int a;
+} Private_Data;
+
+EAPI const Eo_Event_Description _EV_A_CHANGED =
+ EO_EVENT_DESCRIPTION("a,changed", "Called when a has changed.");
+
+#define MY_CLASS SIMPLE_CLASS
+
+static void
+_a_set(Eo *obj, void *class_data, va_list *list)
+{
+ Private_Data *pd = class_data;
+ int a;
+ a = va_arg(*list, int);
+ pd->a = a;
+ printf("%s %d\n", __func__, pd->a);
+
+ pd->protected.protected_x1 = a + 1;
+ pd->protected.public.public_x2 = a + 2;
+
+ eo_do(obj, eo_event_callback_call(EV_A_CHANGED, &pd->a, NULL));
+}
+
+static void
+_class_constructor(Eo_Class *klass)
+{
+ const Eo_Op_Func_Description func_desc[] = {
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set),
+ EO_OP_FUNC_SENTINEL
+ };
+
+ eo_class_funcs_set(klass, func_desc);
+}
+
+static const Eo_Op_Description op_desc[] = {
+ EO_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "Set property A"),
+ EO_OP_DESCRIPTION_SENTINEL
+};
+
+static const Eo_Event_Description *event_desc[] = {
+ EV_A_CHANGED,
+ NULL
+};
+
+static const Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Simple",
+ EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(&SIMPLE_BASE_ID, op_desc, SIMPLE_SUB_ID_LAST),
+ event_desc,
+ sizeof(Private_Data),
+ _class_constructor,
+ NULL
+};
+
+EO_DEFINE_CLASS(simple_class_get, &class_desc, EO_BASE_CLASS, NULL)
+
diff --git a/src/tests/eo/access/access_simple.h b/src/tests/eo/access/access_simple.h
new file mode 100644
index 000000000..11624b7d2
--- /dev/null
+++ b/src/tests/eo/access/access_simple.h
@@ -0,0 +1,26 @@
+#ifndef SIMPLE_H
+#define SIMPLE_H
+
+extern EAPI Eo_Op SIMPLE_BASE_ID;
+
+enum {
+ SIMPLE_SUB_ID_A_SET,
+ SIMPLE_SUB_ID_LAST
+};
+
+typedef struct
+{
+ int public_x2;
+} Simple_Public_Data;
+
+#define SIMPLE_ID(sub_id) (SIMPLE_BASE_ID + sub_id)
+
+#define simple_a_set(a) SIMPLE_ID(SIMPLE_SUB_ID_A_SET), EO_TYPECHECK(int, a)
+
+extern const Eo_Event_Description _EV_A_CHANGED;
+#define EV_A_CHANGED (&(_EV_A_CHANGED))
+
+#define SIMPLE_CLASS simple_class_get()
+const Eo_Class *simple_class_get(void);
+
+#endif
diff --git a/src/tests/eo/access/access_simple_protected.h b/src/tests/eo/access/access_simple_protected.h
new file mode 100644
index 000000000..3cabcd804
--- /dev/null
+++ b/src/tests/eo/access/access_simple_protected.h
@@ -0,0 +1,10 @@
+#ifndef SIMPLE_PROTECTED_H
+#define SIMPLE_PROTECTED_H
+
+typedef struct
+{
+ Simple_Public_Data public;
+ int protected_x1;
+} Simple_Protected_Data;
+
+#endif
diff --git a/src/tests/eo/composite_objects/composite_objects_comp.c b/src/tests/eo/composite_objects/composite_objects_comp.c
new file mode 100644
index 000000000..b15770c9d
--- /dev/null
+++ b/src/tests/eo/composite_objects/composite_objects_comp.c
@@ -0,0 +1,65 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "composite_objects_simple.h"
+#include "composite_objects_comp.h"
+
+#include "../eunit_tests.h"
+
+EAPI Eo_Op COMP_BASE_ID = 0;
+
+#define MY_CLASS COMP_CLASS
+
+static void
+_a_get(Eo *obj, void *class_data EINA_UNUSED, va_list *list)
+{
+ int *a;
+ a = va_arg(*list, int *);
+ eo_do_super(obj, simple_a_get(a));
+}
+
+static void
+_constructor(Eo *obj, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+ eo_do_super(obj, eo_constructor());
+
+ Eo *simple = eo_add(SIMPLE_CLASS, obj);
+ eo_composite_attach(simple, obj);
+ eo_do(simple, eo_event_callback_forwarder_add(EV_A_CHANGED, obj));
+
+ fail_if(eo_composite_is(obj));
+ fail_if(!eo_composite_is(simple));
+
+ eo_do(obj, eo_base_data_set("simple-obj", simple, NULL));
+
+ eo_unref(simple);
+}
+
+static void
+_class_constructor(Eo_Class *klass)
+{
+ const Eo_Op_Func_Description func_desc[] = {
+ EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor),
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get),
+ EO_OP_FUNC_SENTINEL
+ };
+
+ eo_class_funcs_set(klass, func_desc);
+}
+
+static const Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Comp",
+ EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
+ NULL,
+ 0,
+ _class_constructor,
+ NULL
+};
+
+EO_DEFINE_CLASS(comp_class_get, &class_desc, EO_BASE_CLASS,
+ SIMPLE_CLASS, NULL);
+
diff --git a/src/tests/eo/composite_objects/composite_objects_comp.h b/src/tests/eo/composite_objects/composite_objects_comp.h
new file mode 100644
index 000000000..95001b702
--- /dev/null
+++ b/src/tests/eo/composite_objects/composite_objects_comp.h
@@ -0,0 +1,7 @@
+#ifndef COMP_H
+#define COMP_H
+
+#define COMP_CLASS comp_class_get()
+const Eo_Class *comp_class_get(void);
+
+#endif
diff --git a/src/tests/eo/composite_objects/composite_objects_main.c b/src/tests/eo/composite_objects/composite_objects_main.c
new file mode 100644
index 000000000..2e5d9ab00
--- /dev/null
+++ b/src/tests/eo/composite_objects/composite_objects_main.c
@@ -0,0 +1,65 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "composite_objects_simple.h"
+#include "composite_objects_comp.h"
+
+#include "../eunit_tests.h"
+
+static int cb_called = EINA_FALSE;
+
+static Eina_Bool
+_a_changed_cb(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info)
+{
+ (void) desc;
+ (void) obj;
+ int new_a = *((int *) event_info);
+ printf("%s event_info:'%d' data:'%s'\n", __func__, new_a, (const char *) data);
+
+ cb_called = EINA_TRUE;
+
+ return EO_CALLBACK_CONTINUE;
+}
+
+int
+main(int argc, char *argv[])
+{
+ (void) argc;
+ (void) argv;
+ eo_init();
+
+ Eo *obj = eo_add(COMP_CLASS, NULL);
+ eo_do(obj, eo_event_callback_add(EV_A_CHANGED, _a_changed_cb, NULL));
+
+ int a;
+ eo_do(obj, simple_a_set(1));
+ fail_if(!cb_called);
+
+ eo_do(obj, simple_a_get(&a));
+ fail_if(a != 1);
+
+ /* disable the callback forwarder, and fail if it's still called. */
+ Eo *simple;
+ eo_do(obj, eo_base_data_get("simple-obj", (void **) &simple));
+ eo_ref(simple);
+ eo_do(simple, eo_event_callback_forwarder_del(EV_A_CHANGED, obj));
+
+ cb_called = EINA_FALSE;
+ eo_do(obj, simple_a_set(2));
+ fail_if(cb_called);
+
+ fail_if(!eo_composite_is(simple));
+ eo_composite_detach(simple, obj);
+ fail_if(eo_composite_is(simple));
+ eo_composite_attach(simple, obj);
+ fail_if(!eo_composite_is(simple));
+
+ eo_unref(simple);
+ eo_unref(obj);
+
+ eo_shutdown();
+ return 0;
+}
+
diff --git a/src/tests/eo/composite_objects/composite_objects_simple.c b/src/tests/eo/composite_objects/composite_objects_simple.c
new file mode 100644
index 000000000..5420ef895
--- /dev/null
+++ b/src/tests/eo/composite_objects/composite_objects_simple.c
@@ -0,0 +1,71 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "composite_objects_simple.h"
+
+EAPI Eo_Op SIMPLE_BASE_ID = 0;
+
+EAPI const Eo_Event_Description _EV_A_CHANGED =
+ EO_EVENT_DESCRIPTION("a,changed", "Called when a has changed.");
+
+#define MY_CLASS SIMPLE_CLASS
+
+static void
+_a_set(Eo *obj, void *class_data, va_list *list)
+{
+ Simple_Public_Data *pd = class_data;
+ int a;
+ a = va_arg(*list, int);
+ printf("%s %d\n", eo_class_name_get(MY_CLASS), a);
+ pd->a = a;
+
+ eo_do(obj, eo_event_callback_call(EV_A_CHANGED, &pd->a, NULL));
+}
+
+static void
+_a_get(Eo *obj EINA_UNUSED, void *class_data, va_list *list)
+{
+ const Simple_Public_Data *pd = class_data;
+ int *a;
+ a = va_arg(*list, int *);
+ *a = pd->a;
+}
+
+static void
+_class_constructor(Eo_Class *klass)
+{
+ const Eo_Op_Func_Description func_desc[] = {
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set),
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get),
+ EO_OP_FUNC_SENTINEL
+ };
+
+ eo_class_funcs_set(klass, func_desc);
+}
+
+static const Eo_Op_Description op_desc[] = {
+ EO_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "Set property A"),
+ EO_OP_DESCRIPTION(SIMPLE_SUB_ID_A_GET, "Get property A"),
+ EO_OP_DESCRIPTION_SENTINEL
+};
+
+static const Eo_Event_Description *event_desc[] = {
+ EV_A_CHANGED,
+ NULL
+};
+
+static const Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Simple",
+ EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(&SIMPLE_BASE_ID, op_desc, SIMPLE_SUB_ID_LAST),
+ event_desc,
+ sizeof(Simple_Public_Data),
+ _class_constructor,
+ NULL
+};
+
+EO_DEFINE_CLASS(simple_class_get, &class_desc, EO_BASE_CLASS, NULL);
+
diff --git a/src/tests/eo/composite_objects/composite_objects_simple.h b/src/tests/eo/composite_objects/composite_objects_simple.h
new file mode 100644
index 000000000..32a62465b
--- /dev/null
+++ b/src/tests/eo/composite_objects/composite_objects_simple.h
@@ -0,0 +1,28 @@
+#ifndef SIMPLE_H
+#define SIMPLE_H
+
+extern EAPI Eo_Op SIMPLE_BASE_ID;
+
+enum {
+ SIMPLE_SUB_ID_A_SET,
+ SIMPLE_SUB_ID_A_GET,
+ SIMPLE_SUB_ID_LAST
+};
+
+typedef struct
+{
+ int a;
+} Simple_Public_Data;
+
+#define SIMPLE_ID(sub_id) (SIMPLE_BASE_ID + sub_id)
+
+#define simple_a_set(a) SIMPLE_ID(SIMPLE_SUB_ID_A_SET), EO_TYPECHECK(int, a)
+#define simple_a_get(a) SIMPLE_ID(SIMPLE_SUB_ID_A_GET), EO_TYPECHECK(int *, a)
+
+extern const Eo_Event_Description _EV_A_CHANGED;
+#define EV_A_CHANGED (&(_EV_A_CHANGED))
+
+#define SIMPLE_CLASS simple_class_get()
+const Eo_Class *simple_class_get(void);
+
+#endif
diff --git a/src/tests/eo/constructors/constructors_main.c b/src/tests/eo/constructors/constructors_main.c
new file mode 100644
index 000000000..c7db62d39
--- /dev/null
+++ b/src/tests/eo/constructors/constructors_main.c
@@ -0,0 +1,79 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "constructors_simple.h"
+#include "constructors_simple2.h"
+#include "constructors_simple3.h"
+#include "constructors_simple4.h"
+#include "constructors_simple5.h"
+#include "constructors_simple6.h"
+#include "constructors_simple7.h"
+#include "constructors_mixin.h"
+
+#include "../eunit_tests.h"
+
+int my_init_count = 0;
+
+int
+main(int argc, char *argv[])
+{
+ int ret = 0;
+ (void) argc;
+ (void) argv;
+ eo_init();
+
+ Eo *obj = eo_add(SIMPLE_CLASS, NULL);
+
+ fail_if(my_init_count != 2);
+
+ eo_do(obj, simple_a_set(1), simple_b_set(2));
+
+ int a, b;
+ eo_do(obj, simple_a_get(&a), simple_b_get(&b), mixin_add_and_print(5));
+
+ eo_unref(obj);
+
+ fail_if(my_init_count != 0);
+
+ obj = eo_add(SIMPLE2_CLASS, NULL);
+ fail_if(obj);
+
+ obj = eo_add(SIMPLE3_CLASS, NULL);
+ fail_if(obj);
+
+ my_init_count = 0;
+ obj = eo_add(SIMPLE4_CLASS, NULL);
+
+ fail_if(my_init_count != 2);
+
+ eo_unref(obj);
+
+ fail_if(my_init_count != 0);
+
+ obj = eo_add(SIMPLE5_CLASS, NULL);
+ fail_if(!obj);
+ eo_unref(obj);
+
+ obj = eo_add(SIMPLE6_CLASS, NULL);
+ fail_if(!obj);
+ eo_unref(obj);
+
+ obj = eo_add(SIMPLE7_CLASS, NULL);
+ fail_if(obj);
+
+ my_init_count = 0;
+ obj = eo_add_custom(SIMPLE_CLASS, NULL, simple_constructor(7));
+ fail_if(!obj);
+
+ fail_if(my_init_count != 2);
+ eo_do(obj, simple_a_get(&a));
+ fail_if(a != 7);
+
+ eo_unref(obj);
+
+ eo_shutdown();
+ return ret;
+}
+
diff --git a/src/tests/eo/constructors/constructors_mixin.c b/src/tests/eo/constructors/constructors_mixin.c
new file mode 100644
index 000000000..7e4be36e5
--- /dev/null
+++ b/src/tests/eo/constructors/constructors_mixin.c
@@ -0,0 +1,70 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "constructors_mixin.h"
+#include "constructors_simple.h"
+
+EAPI Eo_Op MIXIN_BASE_ID = 0;
+
+#define MY_CLASS MIXIN_CLASS
+
+static void
+_add_and_print_set(Eo *obj, void *class_data EINA_UNUSED, va_list *list)
+{
+ int a, b, x;
+ eo_do(obj, simple_a_get(&a), simple_b_get(&b));
+ x = va_arg(*list, const int);
+ printf("%s %d\n", __func__, a + b + x);
+}
+
+extern int my_init_count;
+
+static void
+_constructor(Eo *obj, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+ eo_do_super(obj, eo_constructor());
+
+ my_init_count++;
+}
+
+static void
+_destructor(Eo *obj, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+ eo_do_super(obj, eo_destructor());
+
+ my_init_count--;
+}
+
+static void
+_class_constructor(Eo_Class *klass)
+{
+ const Eo_Op_Func_Description func_desc[] = {
+ EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor),
+ EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor),
+ EO_OP_FUNC(MIXIN_ID(MIXIN_SUB_ID_ADD_AND_SET), _add_and_print_set),
+ EO_OP_FUNC_SENTINEL
+ };
+
+ eo_class_funcs_set(klass, func_desc);
+}
+
+static const Eo_Op_Description op_desc[] = {
+ EO_OP_DESCRIPTION(MIXIN_SUB_ID_ADD_AND_SET, "Add A + B + param and print it"),
+ EO_OP_DESCRIPTION_SENTINEL
+};
+
+static const Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Mixin",
+ EO_CLASS_TYPE_MIXIN,
+ EO_CLASS_DESCRIPTION_OPS(&MIXIN_BASE_ID, op_desc, MIXIN_SUB_ID_LAST),
+ NULL,
+ 0,
+ _class_constructor,
+ NULL
+};
+
+EO_DEFINE_CLASS(mixin_class_get, &class_desc, NULL, NULL);
+
diff --git a/src/tests/eo/constructors/constructors_mixin.h b/src/tests/eo/constructors/constructors_mixin.h
new file mode 100644
index 000000000..9998b274f
--- /dev/null
+++ b/src/tests/eo/constructors/constructors_mixin.h
@@ -0,0 +1,18 @@
+#ifndef MIXIN_H
+#define MIXIN_H
+
+extern EAPI Eo_Op MIXIN_BASE_ID;
+
+enum {
+ MIXIN_SUB_ID_ADD_AND_SET,
+ MIXIN_SUB_ID_LAST
+};
+
+#define MIXIN_ID(sub_id) (MIXIN_BASE_ID + sub_id)
+
+#define mixin_add_and_print(x) MIXIN_ID(MIXIN_SUB_ID_ADD_AND_SET), EO_TYPECHECK(int, x)
+
+#define MIXIN_CLASS mixin_class_get()
+const Eo_Class *mixin_class_get(void);
+
+#endif
diff --git a/src/tests/eo/constructors/constructors_simple.c b/src/tests/eo/constructors/constructors_simple.c
new file mode 100644
index 000000000..b598650d7
--- /dev/null
+++ b/src/tests/eo/constructors/constructors_simple.c
@@ -0,0 +1,124 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "constructors_mixin.h"
+#include "constructors_simple.h"
+
+EAPI Eo_Op SIMPLE_BASE_ID = 0;
+
+typedef struct
+{
+ int a;
+ int b;
+} Private_Data;
+
+#define MY_CLASS SIMPLE_CLASS
+
+static char *class_var = NULL;
+
+#define _GET_SET_FUNC(name) \
+static void \
+_##name##_get(Eo *obj EINA_UNUSED, void *class_data, va_list *list) \
+{ \
+ const Private_Data *pd = class_data; \
+ int *name; \
+ name = va_arg(*list, int *); \
+ *name = pd->name; \
+ printf("%s %d\n", __func__, pd->name); \
+} \
+static void \
+_##name##_set(Eo *obj EINA_UNUSED, void *class_data, va_list *list) \
+{ \
+ Private_Data *pd = class_data; \
+ int name; \
+ name = va_arg(*list, int); \
+ pd->name = name; \
+ printf("%s %d\n", __func__, pd->name); \
+}
+
+_GET_SET_FUNC(a)
+_GET_SET_FUNC(b)
+
+extern int my_init_count;
+
+static void
+_simple_constructor(Eo *obj, void *class_data, va_list *list)
+{
+ Private_Data *pd = class_data;
+ int a;
+ a = va_arg(*list, int);
+
+ eo_do_super(obj, eo_constructor());
+
+ pd->a = a;
+ printf("%s %d\n", __func__, pd->a);
+
+ my_init_count++;
+}
+
+static void
+_constructor(Eo *obj, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+ eo_do_super(obj, eo_constructor());
+
+ my_init_count++;
+}
+
+static void
+_destructor(Eo *obj, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+ eo_do_super(obj, eo_destructor());
+
+ my_init_count--;
+}
+
+static void
+_class_constructor(Eo_Class *klass)
+{
+ const Eo_Op_Func_Description func_desc[] = {
+ EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor),
+ EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor),
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_CONSTRUCTOR), _simple_constructor),
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set),
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get),
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_B_SET), _b_set),
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_B_GET), _b_get),
+ EO_OP_FUNC_SENTINEL
+ };
+
+ eo_class_funcs_set(klass, func_desc);
+
+ class_var = malloc(10);
+}
+
+static void
+_class_destructor(Eo_Class *klass EINA_UNUSED)
+{
+ free(class_var);
+}
+
+static const Eo_Op_Description op_desc[] = {
+ EO_OP_DESCRIPTION(SIMPLE_SUB_ID_CONSTRUCTOR, "Construct and set A."),
+ EO_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "Set property A"),
+ EO_OP_DESCRIPTION(SIMPLE_SUB_ID_A_GET, "Get property A"),
+ EO_OP_DESCRIPTION(SIMPLE_SUB_ID_B_SET, "Set property B"),
+ EO_OP_DESCRIPTION(SIMPLE_SUB_ID_B_GET, "Get property B"),
+ EO_OP_DESCRIPTION_SENTINEL
+};
+
+static const Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Simple",
+ EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(&SIMPLE_BASE_ID, op_desc, SIMPLE_SUB_ID_LAST),
+ NULL,
+ sizeof(Private_Data),
+ _class_constructor,
+ _class_destructor
+};
+
+EO_DEFINE_CLASS(simple_class_get, &class_desc, EO_BASE_CLASS,
+ MIXIN_CLASS, NULL);
+
diff --git a/src/tests/eo/constructors/constructors_simple.h b/src/tests/eo/constructors/constructors_simple.h
new file mode 100644
index 000000000..7342d3402
--- /dev/null
+++ b/src/tests/eo/constructors/constructors_simple.h
@@ -0,0 +1,26 @@
+#ifndef SIMPLE_H
+#define SIMPLE_H
+
+extern EAPI Eo_Op SIMPLE_BASE_ID;
+
+enum {
+ SIMPLE_SUB_ID_CONSTRUCTOR,
+ SIMPLE_SUB_ID_A_SET,
+ SIMPLE_SUB_ID_A_GET,
+ SIMPLE_SUB_ID_B_SET,
+ SIMPLE_SUB_ID_B_GET,
+ SIMPLE_SUB_ID_LAST
+};
+
+#define SIMPLE_ID(sub_id) (SIMPLE_BASE_ID + sub_id)
+
+#define simple_constructor(a) SIMPLE_ID(SIMPLE_SUB_ID_CONSTRUCTOR), EO_TYPECHECK(int, a)
+#define simple_a_set(a) SIMPLE_ID(SIMPLE_SUB_ID_A_SET), EO_TYPECHECK(int, a)
+#define simple_a_get(a) SIMPLE_ID(SIMPLE_SUB_ID_A_GET), EO_TYPECHECK(int *, a)
+#define simple_b_set(b) SIMPLE_ID(SIMPLE_SUB_ID_B_SET), EO_TYPECHECK(int, b)
+#define simple_b_get(b) SIMPLE_ID(SIMPLE_SUB_ID_B_GET), EO_TYPECHECK(int *, b)
+
+#define SIMPLE_CLASS simple_class_get()
+const Eo_Class *simple_class_get(void);
+
+#endif
diff --git a/src/tests/eo/constructors/constructors_simple2.c b/src/tests/eo/constructors/constructors_simple2.c
new file mode 100644
index 000000000..8aa771719
--- /dev/null
+++ b/src/tests/eo/constructors/constructors_simple2.c
@@ -0,0 +1,42 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "constructors_mixin.h"
+#include "constructors_simple2.h"
+
+#define MY_CLASS SIMPLE2_CLASS
+
+static void
+_constructor(Eo *obj, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+ eo_do_super(obj, eo_constructor());
+
+ eo_error_set(obj);
+}
+
+static void
+_class_constructor(Eo_Class *klass)
+{
+ const Eo_Op_Func_Description func_desc[] = {
+ EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor),
+ EO_OP_FUNC_SENTINEL
+ };
+
+ eo_class_funcs_set(klass, func_desc);
+}
+
+static const Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Simple2",
+ EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
+ NULL,
+ 0,
+ _class_constructor,
+ NULL
+};
+
+EO_DEFINE_CLASS(simple2_class_get, &class_desc, EO_BASE_CLASS, NULL);
+
diff --git a/src/tests/eo/constructors/constructors_simple2.h b/src/tests/eo/constructors/constructors_simple2.h
new file mode 100644
index 000000000..e6549f3d2
--- /dev/null
+++ b/src/tests/eo/constructors/constructors_simple2.h
@@ -0,0 +1,7 @@
+#ifndef SIMPLE2_H
+#define SIMPLE2_H
+
+#define SIMPLE2_CLASS simple2_class_get()
+const Eo_Class *simple2_class_get(void);
+
+#endif
diff --git a/src/tests/eo/constructors/constructors_simple3.c b/src/tests/eo/constructors/constructors_simple3.c
new file mode 100644
index 000000000..13453b76e
--- /dev/null
+++ b/src/tests/eo/constructors/constructors_simple3.c
@@ -0,0 +1,40 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "constructors_mixin.h"
+#include "constructors_simple3.h"
+
+#define MY_CLASS SIMPLE3_CLASS
+
+static void
+_constructor(Eo *obj, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+ (void) obj;
+}
+
+static void
+_class_constructor(Eo_Class *klass)
+{
+ const Eo_Op_Func_Description func_desc[] = {
+ EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor),
+ EO_OP_FUNC_SENTINEL
+ };
+
+ eo_class_funcs_set(klass, func_desc);
+}
+
+static const Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Simple3",
+ EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
+ NULL,
+ 0,
+ _class_constructor,
+ NULL
+};
+
+EO_DEFINE_CLASS(simple3_class_get, &class_desc, EO_BASE_CLASS, NULL);
+
diff --git a/src/tests/eo/constructors/constructors_simple3.h b/src/tests/eo/constructors/constructors_simple3.h
new file mode 100644
index 000000000..e27f8f1ce
--- /dev/null
+++ b/src/tests/eo/constructors/constructors_simple3.h
@@ -0,0 +1,7 @@
+#ifndef SIMPLE3_H
+#define SIMPLE3_H
+
+#define SIMPLE3_CLASS simple3_class_get()
+const Eo_Class *simple3_class_get(void);
+
+#endif
diff --git a/src/tests/eo/constructors/constructors_simple4.c b/src/tests/eo/constructors/constructors_simple4.c
new file mode 100644
index 000000000..abce301e3
--- /dev/null
+++ b/src/tests/eo/constructors/constructors_simple4.c
@@ -0,0 +1,24 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "constructors_mixin.h"
+#include "constructors_simple.h"
+#include "constructors_simple4.h"
+
+#define MY_CLASS SIMPLE4_CLASS
+
+static const Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Simple4",
+ EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
+ NULL,
+ 0,
+ NULL,
+ NULL
+};
+
+EO_DEFINE_CLASS(simple4_class_get, &class_desc, SIMPLE_CLASS, MIXIN_CLASS, NULL);
+
diff --git a/src/tests/eo/constructors/constructors_simple4.h b/src/tests/eo/constructors/constructors_simple4.h
new file mode 100644
index 000000000..fe8e862e6
--- /dev/null
+++ b/src/tests/eo/constructors/constructors_simple4.h
@@ -0,0 +1,7 @@
+#ifndef SIMPLE4_H
+#define SIMPLE4_H
+
+#define SIMPLE4_CLASS simple4_class_get()
+const Eo_Class *simple4_class_get(void);
+
+#endif
diff --git a/src/tests/eo/constructors/constructors_simple5.c b/src/tests/eo/constructors/constructors_simple5.c
new file mode 100644
index 000000000..bd2f1a5b3
--- /dev/null
+++ b/src/tests/eo/constructors/constructors_simple5.c
@@ -0,0 +1,40 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "constructors_mixin.h"
+#include "constructors_simple5.h"
+
+#define MY_CLASS SIMPLE5_CLASS
+
+static void
+_destructor(Eo *obj, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+ (void) obj;
+}
+
+static void
+_class_constructor(Eo_Class *klass)
+{
+ const Eo_Op_Func_Description func_desc[] = {
+ EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor),
+ EO_OP_FUNC_SENTINEL
+ };
+
+ eo_class_funcs_set(klass, func_desc);
+}
+
+static const Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Simple5",
+ EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
+ NULL,
+ 0,
+ _class_constructor,
+ NULL
+};
+
+EO_DEFINE_CLASS(simple5_class_get, &class_desc, EO_BASE_CLASS, NULL);
+
diff --git a/src/tests/eo/constructors/constructors_simple5.h b/src/tests/eo/constructors/constructors_simple5.h
new file mode 100644
index 000000000..9b262d446
--- /dev/null
+++ b/src/tests/eo/constructors/constructors_simple5.h
@@ -0,0 +1,7 @@
+#ifndef SIMPLE5_H
+#define SIMPLE5_H
+
+#define SIMPLE5_CLASS simple5_class_get()
+const Eo_Class *simple5_class_get(void);
+
+#endif
diff --git a/src/tests/eo/constructors/constructors_simple6.c b/src/tests/eo/constructors/constructors_simple6.c
new file mode 100644
index 000000000..561556d4b
--- /dev/null
+++ b/src/tests/eo/constructors/constructors_simple6.c
@@ -0,0 +1,42 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "constructors_mixin.h"
+#include "constructors_simple6.h"
+
+#define MY_CLASS SIMPLE6_CLASS
+
+static void
+_destructor(Eo *obj, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+ eo_do_super(obj, eo_destructor());
+
+ eo_error_set(obj);
+}
+
+static void
+_class_constructor(Eo_Class *klass)
+{
+ const Eo_Op_Func_Description func_desc[] = {
+ EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor),
+ EO_OP_FUNC_SENTINEL
+ };
+
+ eo_class_funcs_set(klass, func_desc);
+}
+
+static const Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Simple6",
+ EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
+ NULL,
+ 0,
+ _class_constructor,
+ NULL
+};
+
+EO_DEFINE_CLASS(simple6_class_get, &class_desc, EO_BASE_CLASS, NULL);
+
diff --git a/src/tests/eo/constructors/constructors_simple6.h b/src/tests/eo/constructors/constructors_simple6.h
new file mode 100644
index 000000000..97e7b5e36
--- /dev/null
+++ b/src/tests/eo/constructors/constructors_simple6.h
@@ -0,0 +1,7 @@
+#ifndef SIMPLE6_H
+#define SIMPLE6_H
+
+#define SIMPLE6_CLASS simple6_class_get()
+const Eo_Class *simple6_class_get(void);
+
+#endif
diff --git a/src/tests/eo/constructors/constructors_simple7.c b/src/tests/eo/constructors/constructors_simple7.c
new file mode 100644
index 000000000..de197bf4f
--- /dev/null
+++ b/src/tests/eo/constructors/constructors_simple7.c
@@ -0,0 +1,43 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "constructors_mixin.h"
+#include "constructors_simple7.h"
+#include "constructors_simple2.h"
+
+#include "../eunit_tests.h"
+
+#define MY_CLASS SIMPLE7_CLASS
+
+static void
+_constructor(Eo *obj, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+ fail_if(eo_do_super(obj, eo_constructor()));
+}
+
+static void
+_class_constructor(Eo_Class *klass)
+{
+ const Eo_Op_Func_Description func_desc[] = {
+ EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor),
+ EO_OP_FUNC_SENTINEL
+ };
+
+ eo_class_funcs_set(klass, func_desc);
+}
+
+static const Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Simple7",
+ EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
+ NULL,
+ 0,
+ _class_constructor,
+ NULL
+};
+
+EO_DEFINE_CLASS(simple7_class_get, &class_desc, SIMPLE2_CLASS, NULL);
+
diff --git a/src/tests/eo/constructors/constructors_simple7.h b/src/tests/eo/constructors/constructors_simple7.h
new file mode 100644
index 000000000..a9a201e44
--- /dev/null
+++ b/src/tests/eo/constructors/constructors_simple7.h
@@ -0,0 +1,7 @@
+#ifndef SIMPLE7_H
+#define SIMPLE7_H
+
+#define SIMPLE7_CLASS simple7_class_get()
+const Eo_Class *simple7_class_get(void);
+
+#endif
diff --git a/src/tests/eo/eunit_tests.h b/src/tests/eo/eunit_tests.h
new file mode 100644
index 000000000..000d18c01
--- /dev/null
+++ b/src/tests/eo/eunit_tests.h
@@ -0,0 +1,17 @@
+#ifndef _EUNIT_TESTS_H
+#define _EUNIT_TESTS_H
+
+#define _EUNIT_EXIT_CODE 1
+
+#define fail_if(x) \
+ do { \
+ if (x) \
+ { \
+ fprintf(stderr, "%s:%d - Failure '%s' is TRUE.", \
+ __FILE__, __LINE__, # x); \
+ exit(_EUNIT_EXIT_CODE); \
+ } \
+ } while (0)
+
+#endif
+
diff --git a/src/tests/eo/function_overrides/function_overrides_inherit.c b/src/tests/eo/function_overrides/function_overrides_inherit.c
new file mode 100644
index 000000000..e2dadbec1
--- /dev/null
+++ b/src/tests/eo/function_overrides/function_overrides_inherit.c
@@ -0,0 +1,22 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "function_overrides_simple.h"
+#include "function_overrides_inherit.h"
+
+#define MY_CLASS INHERIT_CLASS
+
+static const Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Inherit",
+ EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
+ NULL,
+ 0,
+ NULL,
+ NULL
+};
+
+EO_DEFINE_CLASS(inherit_class_get, &class_desc, SIMPLE_CLASS, NULL);
diff --git a/src/tests/eo/function_overrides/function_overrides_inherit.h b/src/tests/eo/function_overrides/function_overrides_inherit.h
new file mode 100644
index 000000000..2f3364795
--- /dev/null
+++ b/src/tests/eo/function_overrides/function_overrides_inherit.h
@@ -0,0 +1,7 @@
+#ifndef INHERIT_H
+#define INHERIT_H
+
+#define INHERIT_CLASS inherit_class_get()
+const Eo_Class *inherit_class_get(void);
+
+#endif
diff --git a/src/tests/eo/function_overrides/function_overrides_inherit2.c b/src/tests/eo/function_overrides/function_overrides_inherit2.c
new file mode 100644
index 000000000..1386759bc
--- /dev/null
+++ b/src/tests/eo/function_overrides/function_overrides_inherit2.c
@@ -0,0 +1,82 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "function_overrides_simple.h"
+#include "function_overrides_inherit.h"
+#include "function_overrides_inherit2.h"
+
+#include "../eunit_tests.h"
+
+EAPI Eo_Op INHERIT2_BASE_ID = 0;
+
+#define MY_CLASS INHERIT2_CLASS
+
+static void
+_a_set(Eo *obj, void *class_data EINA_UNUSED, va_list *list)
+{
+ int a;
+ a = va_arg(*list, int);
+ printf("%s %d\n", eo_class_name_get(MY_CLASS), a);
+ eo_do(obj, simple_a_print());
+ eo_do_super(obj, simple_a_set(a + 1));
+
+ fail_if(!eo_do_super(obj, simple_a_print()));
+}
+
+static void
+_print(Eo *obj, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+ printf("Hey\n");
+ fail_if(eo_do_super(obj, inherit2_print()));
+}
+
+static void
+_print2(Eo *obj EINA_UNUSED, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+ printf("Hey2\n");
+}
+
+static void
+_class_print(const Eo_Class *klass, va_list *list)
+{
+ (void) list;
+ printf("Print %s-%s\n", eo_class_name_get(klass), eo_class_name_get(MY_CLASS));
+ fail_if(!eo_class_do_super(klass, simple_class_print()));
+ fail_if(!eo_class_do_super(klass, simple_class_print2()));
+}
+
+static void
+_class_constructor(Eo_Class *klass)
+{
+ const Eo_Op_Func_Description func_desc[] = {
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set),
+ EO_OP_FUNC(INHERIT2_ID(INHERIT2_SUB_ID_PRINT), _print),
+ EO_OP_FUNC(INHERIT2_ID(INHERIT2_SUB_ID_PRINT2), _print2),
+ EO_OP_FUNC_CLASS(SIMPLE_ID(SIMPLE_SUB_ID_CLASS_PRINT), _class_print),
+ EO_OP_FUNC_SENTINEL
+ };
+
+ eo_class_funcs_set(klass, func_desc);
+}
+
+static const Eo_Op_Description op_desc[] = {
+ EO_OP_DESCRIPTION(INHERIT2_SUB_ID_PRINT, "Print hey"),
+ EO_OP_DESCRIPTION(INHERIT2_SUB_ID_PRINT2, "Print hey2"),
+ EO_OP_DESCRIPTION_SENTINEL
+};
+
+static const Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Inherit2",
+ EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(&INHERIT2_BASE_ID, op_desc, INHERIT2_SUB_ID_LAST),
+ NULL,
+ 0,
+ _class_constructor,
+ NULL
+};
+
+EO_DEFINE_CLASS(inherit2_class_get, &class_desc, INHERIT_CLASS, NULL);
+
diff --git a/src/tests/eo/function_overrides/function_overrides_inherit2.h b/src/tests/eo/function_overrides/function_overrides_inherit2.h
new file mode 100644
index 000000000..2bc0b0d36
--- /dev/null
+++ b/src/tests/eo/function_overrides/function_overrides_inherit2.h
@@ -0,0 +1,20 @@
+#ifndef INHERIT2_H
+#define INHERIT2_H
+
+extern EAPI Eo_Op INHERIT2_BASE_ID;
+
+enum {
+ INHERIT2_SUB_ID_PRINT,
+ INHERIT2_SUB_ID_PRINT2,
+ INHERIT2_SUB_ID_LAST
+};
+
+#define INHERIT2_ID(sub_id) (INHERIT2_BASE_ID + sub_id)
+
+#define inherit2_print() INHERIT2_ID(INHERIT2_SUB_ID_PRINT)
+#define inherit2_print2() INHERIT2_ID(INHERIT2_SUB_ID_PRINT2)
+
+#define INHERIT2_CLASS inherit2_class_get()
+const Eo_Class *inherit2_class_get(void);
+
+#endif
diff --git a/src/tests/eo/function_overrides/function_overrides_inherit3.c b/src/tests/eo/function_overrides/function_overrides_inherit3.c
new file mode 100644
index 000000000..186291328
--- /dev/null
+++ b/src/tests/eo/function_overrides/function_overrides_inherit3.c
@@ -0,0 +1,44 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "function_overrides_simple.h"
+#include "function_overrides_inherit2.h"
+#include "function_overrides_inherit3.h"
+
+#define MY_CLASS INHERIT3_CLASS
+
+static void
+_a_set(Eo *obj, void *class_data EINA_UNUSED, va_list *list)
+{
+ int a;
+ a = va_arg(*list, int);
+ printf("%s %d\n", eo_class_name_get(MY_CLASS), a);
+ eo_do_super(obj, simple_a_set(a + 1));
+}
+
+static void
+_class_constructor(Eo_Class *klass)
+{
+ const Eo_Op_Func_Description func_desc[] = {
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set),
+ EO_OP_FUNC_SENTINEL
+ };
+
+ eo_class_funcs_set(klass, func_desc);
+}
+
+static const Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Inherit3",
+ EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
+ NULL,
+ 0,
+ _class_constructor,
+ NULL
+};
+
+EO_DEFINE_CLASS(inherit3_class_get, &class_desc, INHERIT2_CLASS, NULL);
+
diff --git a/src/tests/eo/function_overrides/function_overrides_inherit3.h b/src/tests/eo/function_overrides/function_overrides_inherit3.h
new file mode 100644
index 000000000..73436ba23
--- /dev/null
+++ b/src/tests/eo/function_overrides/function_overrides_inherit3.h
@@ -0,0 +1,7 @@
+#ifndef INHERIT3_H
+#define INHERIT3_H
+
+#define INHERIT3_CLASS inherit3_class_get()
+const Eo_Class *inherit3_class_get(void);
+
+#endif
diff --git a/src/tests/eo/function_overrides/function_overrides_main.c b/src/tests/eo/function_overrides/function_overrides_main.c
new file mode 100644
index 000000000..4ab695f98
--- /dev/null
+++ b/src/tests/eo/function_overrides/function_overrides_main.c
@@ -0,0 +1,63 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "function_overrides_simple.h"
+#include "function_overrides_inherit.h"
+#include "function_overrides_inherit2.h"
+#include "function_overrides_inherit3.h"
+
+#include "../eunit_tests.h"
+
+int
+main(int argc, char *argv[])
+{
+ (void) argc;
+ (void) argv;
+ eo_init();
+
+ Eo *obj = eo_add(INHERIT2_CLASS, NULL);
+
+ eo_do(obj, simple_a_set(1));
+ Simple_Public_Data *pd = eo_data_get(obj, SIMPLE_CLASS);
+ fail_if(pd->a != 2);
+
+ eo_unref(obj);
+
+ obj = eo_add(INHERIT3_CLASS, NULL);
+
+ eo_do(obj, simple_a_set(1));
+ pd = eo_data_get(obj, SIMPLE_CLASS);
+ fail_if(pd->a != 3);
+
+ eo_unref(obj);
+
+ obj = eo_add(INHERIT2_CLASS, NULL);
+ fail_if(!eo_do(obj, inherit2_print()));
+ fail_if(!eo_do(obj, inherit2_print(), inherit2_print()));
+ eo_unref(obj);
+
+ obj = eo_add(SIMPLE_CLASS, NULL);
+ fail_if(eo_do(obj, inherit2_print2()));
+
+ fail_if(eo_do_super(obj, simple_a_print()));
+
+ fail_if(eo_do(obj, simple_class_print()));
+
+ fail_if(!eo_class_do(SIMPLE_CLASS, simple_class_print()));
+ fail_if(!eo_class_do(INHERIT_CLASS, simple_class_print()));
+ fail_if(!eo_class_do(INHERIT2_CLASS, simple_class_print()));
+ fail_if(!eo_class_do(INHERIT3_CLASS, simple_class_print()));
+
+ fail_if(eo_class_do(SIMPLE_CLASS, simple_a_print()));
+
+ eo_do_super(obj, eo_constructor());
+ eo_do_super(obj, eo_destructor());
+
+ eo_unref(obj);
+
+ eo_shutdown();
+ return 0;
+}
+
diff --git a/src/tests/eo/function_overrides/function_overrides_simple.c b/src/tests/eo/function_overrides/function_overrides_simple.c
new file mode 100644
index 000000000..167294393
--- /dev/null
+++ b/src/tests/eo/function_overrides/function_overrides_simple.c
@@ -0,0 +1,82 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "function_overrides_simple.h"
+
+#include "../eunit_tests.h"
+
+EAPI Eo_Op SIMPLE_BASE_ID = 0;
+
+#define MY_CLASS SIMPLE_CLASS
+
+static void
+_a_set(Eo *obj EINA_UNUSED, void *class_data, va_list *list)
+{
+ Simple_Public_Data *pd = class_data;
+ int a;
+ a = va_arg(*list, int);
+ printf("%s %d\n", eo_class_name_get(MY_CLASS), a);
+ pd->a = a;
+}
+
+static void
+_a_print(Eo *obj EINA_UNUSED, void *class_data, va_list *list)
+{
+ const Simple_Public_Data *pd = class_data;
+ (void) list;
+ printf("Print %s %d\n", eo_class_name_get(MY_CLASS), pd->a);
+}
+
+static void
+_class_print(const Eo_Class *klass, va_list *list)
+{
+ (void) list;
+ printf("Print %s-%s\n", eo_class_name_get(klass), eo_class_name_get(MY_CLASS));
+ fail_if(eo_class_do_super(klass, simple_class_print()));
+ fail_if(eo_class_do_super(klass, simple_class_print2()));
+}
+
+static void
+_class_print2(const Eo_Class *klass, va_list *list)
+{
+ (void) list;
+ printf("Print %s-%s\n", eo_class_name_get(klass), eo_class_name_get(MY_CLASS));
+}
+
+static void
+_class_constructor(Eo_Class *klass)
+{
+ const Eo_Op_Func_Description func_desc[] = {
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set),
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT), _a_print),
+ EO_OP_FUNC_CLASS(SIMPLE_ID(SIMPLE_SUB_ID_CLASS_PRINT), _class_print),
+ EO_OP_FUNC_CLASS(SIMPLE_ID(SIMPLE_SUB_ID_CLASS_PRINT2), _class_print2),
+ EO_OP_FUNC_SENTINEL
+ };
+
+ eo_class_funcs_set(klass, func_desc);
+}
+
+static const Eo_Op_Description op_desc[] = {
+ EO_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "Set property A"),
+ EO_OP_DESCRIPTION(SIMPLE_SUB_ID_A_PRINT, "Print property A"),
+ EO_OP_DESCRIPTION_CLASS(SIMPLE_SUB_ID_CLASS_PRINT, "Print class name."),
+ EO_OP_DESCRIPTION_CLASS(SIMPLE_SUB_ID_CLASS_PRINT2, "Print2 class name."),
+ EO_OP_DESCRIPTION_SENTINEL
+};
+
+static const Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Simple",
+ EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(&SIMPLE_BASE_ID, op_desc, SIMPLE_SUB_ID_LAST),
+ NULL,
+ sizeof(Simple_Public_Data),
+ _class_constructor,
+ NULL
+};
+
+EO_DEFINE_CLASS(simple_class_get, &class_desc, EO_BASE_CLASS, NULL);
+
diff --git a/src/tests/eo/function_overrides/function_overrides_simple.h b/src/tests/eo/function_overrides/function_overrides_simple.h
new file mode 100644
index 000000000..3a620fa61
--- /dev/null
+++ b/src/tests/eo/function_overrides/function_overrides_simple.h
@@ -0,0 +1,32 @@
+#ifndef SIMPLE_H
+#define SIMPLE_H
+
+extern EAPI Eo_Op SIMPLE_BASE_ID;
+
+enum {
+ SIMPLE_SUB_ID_A_SET,
+ SIMPLE_SUB_ID_A_PRINT,
+ SIMPLE_SUB_ID_CLASS_PRINT,
+ SIMPLE_SUB_ID_CLASS_PRINT2,
+ SIMPLE_SUB_ID_LAST
+};
+
+typedef struct
+{
+ int a;
+} Simple_Public_Data;
+
+#define SIMPLE_ID(sub_id) (SIMPLE_BASE_ID + sub_id)
+
+#define simple_a_set(a) SIMPLE_ID(SIMPLE_SUB_ID_A_SET), EO_TYPECHECK(int, a)
+#define simple_a_print() SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT)
+#define simple_class_print() SIMPLE_ID(SIMPLE_SUB_ID_CLASS_PRINT)
+#define simple_class_print2() SIMPLE_ID(SIMPLE_SUB_ID_CLASS_PRINT2)
+
+extern const Eo_Event_Description _SIG_A_CHANGED;
+#define SIG_A_CHANGED (&(_SIG_A_CHANGED))
+
+#define SIMPLE_CLASS simple_class_get()
+const Eo_Class *simple_class_get(void);
+
+#endif
diff --git a/src/tests/eo/interface/interface_interface.c b/src/tests/eo/interface/interface_interface.c
new file mode 100644
index 000000000..c0dec7649
--- /dev/null
+++ b/src/tests/eo/interface/interface_interface.c
@@ -0,0 +1,30 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "interface_interface.h"
+#include "interface_simple.h"
+
+EAPI Eo_Op INTERFACE_BASE_ID = 0;
+
+#define MY_CLASS INTERFACE_CLASS
+
+static const Eo_Op_Description op_desc[] = {
+ EO_OP_DESCRIPTION(INTERFACE_SUB_ID_AB_SUM_GET, "Get the sum of a and b."),
+ EO_OP_DESCRIPTION_SENTINEL
+};
+
+static const Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Interface",
+ EO_CLASS_TYPE_INTERFACE,
+ EO_CLASS_DESCRIPTION_OPS(&INTERFACE_BASE_ID, op_desc, INTERFACE_SUB_ID_LAST),
+ NULL,
+ 0,
+ NULL,
+ NULL
+};
+
+EO_DEFINE_CLASS(interface_class_get, &class_desc, NULL, NULL)
+
diff --git a/src/tests/eo/interface/interface_interface.h b/src/tests/eo/interface/interface_interface.h
new file mode 100644
index 000000000..4e161b848
--- /dev/null
+++ b/src/tests/eo/interface/interface_interface.h
@@ -0,0 +1,24 @@
+#ifndef INTERFACE_H
+#define INTERFACE_H
+
+extern EAPI Eo_Op INTERFACE_BASE_ID;
+
+enum {
+ INTERFACE_SUB_ID_AB_SUM_GET,
+ INTERFACE_SUB_ID_LAST
+};
+
+#define INTERFACE_ID(sub_id) (INTERFACE_BASE_ID + sub_id)
+
+
+/**
+ * @def interface_ab_sum_get(sum)
+ * @brief Get sum of a,b integer elements
+ * @param[out] sum integer pointer to sum - value
+ */
+#define interface_ab_sum_get(sum) INTERFACE_ID(INTERFACE_SUB_ID_AB_SUM_GET), EO_TYPECHECK(int *, sum)
+
+#define INTERFACE_CLASS interface_class_get()
+const Eo_Class *interface_class_get(void);
+
+#endif
diff --git a/src/tests/eo/interface/interface_interface2.c b/src/tests/eo/interface/interface_interface2.c
new file mode 100644
index 000000000..14d3f1d0f
--- /dev/null
+++ b/src/tests/eo/interface/interface_interface2.c
@@ -0,0 +1,31 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "interface_interface.h"
+#include "interface_interface2.h"
+#include "interface_simple.h"
+
+EAPI Eo_Op INTERFACE2_BASE_ID = 0;
+
+#define MY_CLASS INTERFACE2_CLASS
+
+static const Eo_Op_Description op_desc[] = {
+ EO_OP_DESCRIPTION(INTERFACE2_SUB_ID_AB_SUM_GET2, "Print the sum of a and b."),
+ EO_OP_DESCRIPTION_SENTINEL
+};
+
+static const Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Interface2",
+ EO_CLASS_TYPE_INTERFACE,
+ EO_CLASS_DESCRIPTION_OPS(&INTERFACE2_BASE_ID, op_desc, INTERFACE2_SUB_ID_LAST),
+ NULL,
+ 0,
+ NULL,
+ NULL
+};
+
+EO_DEFINE_CLASS(interface2_class_get, &class_desc, INTERFACE_CLASS, NULL)
+
diff --git a/src/tests/eo/interface/interface_interface2.h b/src/tests/eo/interface/interface_interface2.h
new file mode 100644
index 000000000..5aa91f4fd
--- /dev/null
+++ b/src/tests/eo/interface/interface_interface2.h
@@ -0,0 +1,24 @@
+#ifndef INTERFACE2_H
+#define INTERFACE2_H
+
+extern EAPI Eo_Op INTERFACE2_BASE_ID;
+
+enum {
+ INTERFACE2_SUB_ID_AB_SUM_GET2,
+ INTERFACE2_SUB_ID_LAST
+};
+
+#define INTERFACE2_ID(sub_id) (INTERFACE2_BASE_ID + sub_id)
+
+
+/**
+ * @def interface2_ab_sum_get2(sum)
+ * @brief Get sum of a,b integer elements
+ * @param[out] sum integer pointer to sum - value
+ */
+#define interface2_ab_sum_get2(sum) INTERFACE2_ID(INTERFACE2_SUB_ID_AB_SUM_GET2), EO_TYPECHECK(int *, sum)
+
+#define INTERFACE2_CLASS interface2_class_get()
+const Eo_Class *interface2_class_get(void);
+
+#endif
diff --git a/src/tests/eo/interface/interface_main.c b/src/tests/eo/interface/interface_main.c
new file mode 100644
index 000000000..5fa65266f
--- /dev/null
+++ b/src/tests/eo/interface/interface_main.c
@@ -0,0 +1,37 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "interface_simple.h"
+#include "interface_interface.h"
+#include "interface_interface2.h"
+
+#include "../eunit_tests.h"
+
+int
+main(int argc, char *argv[])
+{
+ (void) argc;
+ (void) argv;
+ eo_init();
+
+ Eo *obj = eo_add(SIMPLE_CLASS, NULL);
+
+ eo_do(obj, simple_a_set(1), simple_b_set(2));
+
+ int a, b, sum = 0;
+ eo_do(obj, simple_a_get(&a), simple_b_get(&b), interface_ab_sum_get(&sum));
+ fail_if(sum != a + b);
+
+ sum = 0;
+ eo_do(obj, interface_ab_sum_get(&sum), interface_ab_sum_get(&sum));
+ fail_if(sum != a + b);
+ eo_do(obj, interface2_ab_sum_get2(&sum), interface2_ab_sum_get2(&sum));
+ fail_if(sum != a + b + 1);
+
+ eo_unref(obj);
+ eo_shutdown();
+ return 0;
+}
+
diff --git a/src/tests/eo/interface/interface_simple.c b/src/tests/eo/interface/interface_simple.c
new file mode 100644
index 000000000..e6f3c156b
--- /dev/null
+++ b/src/tests/eo/interface/interface_simple.c
@@ -0,0 +1,100 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "interface_interface.h"
+#include "interface_interface2.h"
+#include "interface_simple.h"
+
+EAPI Eo_Op SIMPLE_BASE_ID = 0;
+
+typedef struct
+{
+ int a;
+ int b;
+} Private_Data;
+
+#define MY_CLASS SIMPLE_CLASS
+
+#define _GET_SET_FUNC(name) \
+static void \
+_##name##_get(Eo *obj EINA_UNUSED, void *class_data, va_list *list) \
+{ \
+ const Private_Data *pd = class_data; \
+ int *name; \
+ name = va_arg(*list, int *); \
+ *name = pd->name; \
+ printf("%s %d\n", __func__, pd->name); \
+} \
+static void \
+_##name##_set(Eo *obj EINA_UNUSED, void *class_data, va_list *list) \
+{ \
+ Private_Data *pd = class_data; \
+ int name; \
+ name = va_arg(*list, int); \
+ pd->name = name; \
+ printf("%s %d\n", __func__, pd->name); \
+}
+
+_GET_SET_FUNC(a)
+_GET_SET_FUNC(b)
+
+static void
+_ab_sum_get(Eo *obj, void *class_data EINA_UNUSED, va_list *list)
+{
+ int a, b;
+ eo_do(obj, simple_a_get(&a), simple_b_get(&b));
+ int *sum = va_arg(*list, int *);
+ if (sum)
+ *sum = a + b;
+ printf("%s %s\n", eo_class_name_get(MY_CLASS), __func__);
+}
+
+static void
+_ab_sum_get2(Eo *obj, void *class_data EINA_UNUSED, va_list *list)
+{
+ int a, b;
+ eo_do(obj, simple_a_get(&a), simple_b_get(&b));
+ int *sum = va_arg(*list, int *);
+ if (sum)
+ *sum = a + b + 1;
+ printf("%s %s\n", eo_class_name_get(MY_CLASS), __func__);
+}
+
+static void
+_class_constructor(Eo_Class *klass)
+{
+ const Eo_Op_Func_Description func_desc[] = {
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set),
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get),
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_B_SET), _b_set),
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_B_GET), _b_get),
+ EO_OP_FUNC(INTERFACE_ID(INTERFACE_SUB_ID_AB_SUM_GET), _ab_sum_get),
+ EO_OP_FUNC(INTERFACE2_ID(INTERFACE2_SUB_ID_AB_SUM_GET2), _ab_sum_get2),
+ EO_OP_FUNC_SENTINEL
+ };
+
+ eo_class_funcs_set(klass, func_desc);
+}
+
+static const Eo_Op_Description op_desc[] = {
+ EO_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "Set property A"),
+ EO_OP_DESCRIPTION(SIMPLE_SUB_ID_A_GET, "Get property A"),
+ EO_OP_DESCRIPTION(SIMPLE_SUB_ID_B_SET, "Set property B"),
+ EO_OP_DESCRIPTION(SIMPLE_SUB_ID_B_GET, "Get property B"),
+ EO_OP_DESCRIPTION_SENTINEL
+};
+
+static const Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Simple",
+ EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(&SIMPLE_BASE_ID, op_desc, SIMPLE_SUB_ID_LAST),
+ NULL,
+ sizeof(Private_Data),
+ _class_constructor,
+ NULL
+};
+
+EO_DEFINE_CLASS(simple_class_get, &class_desc, EO_BASE_CLASS, INTERFACE2_CLASS, NULL);
diff --git a/src/tests/eo/interface/interface_simple.h b/src/tests/eo/interface/interface_simple.h
new file mode 100644
index 000000000..8df813127
--- /dev/null
+++ b/src/tests/eo/interface/interface_simple.h
@@ -0,0 +1,47 @@
+#ifndef SIMPLE_H
+#define SIMPLE_H
+
+extern EAPI Eo_Op SIMPLE_BASE_ID;
+
+enum {
+ SIMPLE_SUB_ID_A_SET,
+ SIMPLE_SUB_ID_A_GET,
+ SIMPLE_SUB_ID_B_SET,
+ SIMPLE_SUB_ID_B_GET,
+ SIMPLE_SUB_ID_LAST
+};
+
+#define SIMPLE_ID(sub_id) (SIMPLE_BASE_ID + sub_id)
+
+/**
+ * @def simple_a_set(a)
+ * @brief Set value to a-property
+ * @param[in] a integer value to set
+ */
+#define simple_a_set(a) SIMPLE_ID(SIMPLE_SUB_ID_A_SET), EO_TYPECHECK(int, a)
+
+/**
+ * @def simple_a_get(a)
+ * @brief Get value of a-property
+ * @param[out] integer pointer to a-value
+ */
+#define simple_a_get(a) SIMPLE_ID(SIMPLE_SUB_ID_A_GET), EO_TYPECHECK(int *, a)
+
+/**
+ * @def simple_b_set(b)
+ * @brief Set value to b-property
+ * @param[in] a integer value to set
+ */
+#define simple_b_set(b) SIMPLE_ID(SIMPLE_SUB_ID_B_SET), EO_TYPECHECK(int, b)
+
+/**
+ * @def simple_b_get(b)
+ * @brief Get value of b-property
+ * @param[out] integer pointer to b-value
+ */
+#define simple_b_get(b) SIMPLE_ID(SIMPLE_SUB_ID_B_GET), EO_TYPECHECK(int *, b)
+
+#define SIMPLE_CLASS simple_class_get()
+const Eo_Class *simple_class_get(void);
+
+#endif
diff --git a/src/tests/eo/mixin/mixin_inherit.c b/src/tests/eo/mixin/mixin_inherit.c
new file mode 100644
index 000000000..4dc8fd9e1
--- /dev/null
+++ b/src/tests/eo/mixin/mixin_inherit.c
@@ -0,0 +1,42 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "mixin_simple.h"
+#include "mixin_mixin4.h"
+#include "mixin_inherit.h"
+
+#define MY_CLASS INHERIT_CLASS
+
+static void
+_a_get(Eo *obj, void *class_data EINA_UNUSED, va_list *list)
+{
+ int *name = va_arg(*list, int *);
+ eo_do_super(obj, simple_a_get(name));
+ printf("%s\n", __func__);
+}
+
+static void
+_class_constructor(Eo_Class *klass)
+{
+ const Eo_Op_Func_Description func_desc[] = {
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get),
+ EO_OP_FUNC_SENTINEL
+ };
+
+ eo_class_funcs_set(klass, func_desc);
+}
+
+static const Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Inherit",
+ EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
+ NULL,
+ 0,
+ _class_constructor,
+ NULL
+};
+
+EO_DEFINE_CLASS(inherit_class_get, &class_desc, SIMPLE_CLASS, MIXIN4_CLASS, NULL);
diff --git a/src/tests/eo/mixin/mixin_inherit.h b/src/tests/eo/mixin/mixin_inherit.h
new file mode 100644
index 000000000..2f3364795
--- /dev/null
+++ b/src/tests/eo/mixin/mixin_inherit.h
@@ -0,0 +1,7 @@
+#ifndef INHERIT_H
+#define INHERIT_H
+
+#define INHERIT_CLASS inherit_class_get()
+const Eo_Class *inherit_class_get(void);
+
+#endif
diff --git a/src/tests/eo/mixin/mixin_main.c b/src/tests/eo/mixin/mixin_main.c
new file mode 100644
index 000000000..bb19e9ca1
--- /dev/null
+++ b/src/tests/eo/mixin/mixin_main.c
@@ -0,0 +1,47 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "mixin_simple.h"
+#include "mixin_inherit.h"
+#include "mixin_mixin.h"
+#include "mixin_mixin2.h"
+#include "mixin_mixin3.h"
+
+#include "../eunit_tests.h"
+
+int
+main(int argc, char *argv[])
+{
+ (void) argc;
+ (void) argv;
+ eo_init();
+
+ Eo *obj = eo_add(SIMPLE_CLASS, NULL);
+
+ eo_do(obj, simple_a_set(1), simple_b_set(2));
+
+ int a, b, sum = 0;
+ eo_do(obj, simple_a_get(&a), simple_b_get(&b), mixin_ab_sum_get(&sum));
+ fail_if(sum != a + b + 2); /* 2 for the two mixins... */
+
+ eo_do(obj, mixin_ab_sum_get(&sum), mixin_ab_sum_get(&sum));
+
+ Mixin2_Public_Data *pd2 = eo_data_get(obj, MIXIN2_CLASS);
+ fail_if(pd2->count != 6);
+
+ Mixin3_Public_Data *pd3 = eo_data_get(obj, MIXIN3_CLASS);
+ fail_if(pd3->count != 9);
+
+ eo_unref(obj);
+
+ obj = eo_add(INHERIT_CLASS, NULL);
+ eo_do(obj, simple_a_set(5), simple_a_get(&a));
+ fail_if(a != 5);
+
+ eo_unref(obj);
+ eo_shutdown();
+ return 0;
+}
+
diff --git a/src/tests/eo/mixin/mixin_mixin.c b/src/tests/eo/mixin/mixin_mixin.c
new file mode 100644
index 000000000..b6fd59e36
--- /dev/null
+++ b/src/tests/eo/mixin/mixin_mixin.c
@@ -0,0 +1,67 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "mixin_mixin.h"
+#include "mixin_simple.h"
+
+EAPI Eo_Op MIXIN_BASE_ID = 0;
+
+#define MY_CLASS MIXIN_CLASS
+
+static void
+_ab_sum_get(Eo *obj, void *class_data EINA_UNUSED, va_list *list)
+{
+ int a, b;
+ eo_do(obj, simple_a_get(&a), simple_b_get(&b));
+ int *sum = va_arg(*list, int *);
+ if (sum)
+ *sum = a + b;
+ printf("%s %s\n", eo_class_name_get(MY_CLASS), __func__);
+}
+
+static void
+_constructor(Eo *obj, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+ eo_do_super(obj, eo_constructor());
+}
+
+static void
+_destructor(Eo *obj, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+ eo_do_super(obj, eo_destructor());
+}
+
+static void
+_class_constructor(Eo_Class *klass)
+{
+ const Eo_Op_Func_Description func_desc[] = {
+ EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor),
+ EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor),
+ EO_OP_FUNC(MIXIN_ID(MIXIN_SUB_ID_AB_SUM_GET), _ab_sum_get),
+ EO_OP_FUNC_SENTINEL
+ };
+
+ eo_class_funcs_set(klass, func_desc);
+}
+
+
+static const Eo_Op_Description op_desc[] = {
+ EO_OP_DESCRIPTION(MIXIN_SUB_ID_AB_SUM_GET, "Get the sum of a and b."),
+ EO_OP_DESCRIPTION_SENTINEL
+};
+
+static const Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Mixin",
+ EO_CLASS_TYPE_MIXIN,
+ EO_CLASS_DESCRIPTION_OPS(&MIXIN_BASE_ID, op_desc, MIXIN_SUB_ID_LAST),
+ NULL,
+ 0,
+ _class_constructor,
+ NULL
+};
+
+EO_DEFINE_CLASS(mixin_class_get, &class_desc, NULL, NULL)
+
diff --git a/src/tests/eo/mixin/mixin_mixin.h b/src/tests/eo/mixin/mixin_mixin.h
new file mode 100644
index 000000000..745e5c468
--- /dev/null
+++ b/src/tests/eo/mixin/mixin_mixin.h
@@ -0,0 +1,24 @@
+#ifndef MIXIN_H
+#define MIXIN_H
+
+extern EAPI Eo_Op MIXIN_BASE_ID;
+
+enum {
+ MIXIN_SUB_ID_AB_SUM_GET,
+ MIXIN_SUB_ID_LAST
+};
+
+#define MIXIN_ID(sub_id) (MIXIN_BASE_ID + sub_id)
+
+
+/**
+ * @def mixin_ab_sum_get(sum)
+ * @brief Get sum of a,b integer elements
+ * @param[out] sum integer pointer to sum - value
+ */
+#define mixin_ab_sum_get(sum) MIXIN_ID(MIXIN_SUB_ID_AB_SUM_GET), EO_TYPECHECK(int *, sum)
+
+#define MIXIN_CLASS mixin_class_get()
+const Eo_Class *mixin_class_get(void);
+
+#endif
diff --git a/src/tests/eo/mixin/mixin_mixin2.c b/src/tests/eo/mixin/mixin_mixin2.c
new file mode 100644
index 000000000..dbd7c97d0
--- /dev/null
+++ b/src/tests/eo/mixin/mixin_mixin2.c
@@ -0,0 +1,70 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "mixin_mixin.h"
+#include "mixin_mixin2.h"
+#include "mixin_simple.h"
+
+#include "../eunit_tests.h"
+
+#define MY_CLASS MIXIN2_CLASS
+
+static void
+_ab_sum_get(Eo *obj, void *class_data, va_list *list)
+{
+ /* This cast is a hack just for the tests... */
+ Mixin2_Public_Data *pd = (Mixin2_Public_Data *) class_data;
+ int *sum = va_arg(*list, int *);
+ printf("%s %s\n", eo_class_name_get(MY_CLASS), __func__);
+ eo_do_super(obj, mixin_ab_sum_get(sum));
+
+ ++*sum;
+ pd->count += 2;
+
+ {
+ int _a, _b;
+ eo_do(obj, simple_a_get(&_a), simple_b_get(&_b));
+ fail_if(*sum != _a + _b + 1);
+ }
+}
+
+static void
+_constructor(Eo *obj, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+ eo_do_super(obj, eo_constructor());
+}
+
+static void
+_destructor(Eo *obj, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+ eo_do_super(obj, eo_destructor());
+}
+
+static void
+_class_constructor(Eo_Class *klass)
+{
+ const Eo_Op_Func_Description func_desc[] = {
+ EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor),
+ EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor),
+ EO_OP_FUNC(MIXIN_ID(MIXIN_SUB_ID_AB_SUM_GET), _ab_sum_get),
+ EO_OP_FUNC_SENTINEL
+ };
+
+ eo_class_funcs_set(klass, func_desc);
+}
+
+static const Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Mixin2",
+ EO_CLASS_TYPE_MIXIN,
+ EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
+ NULL,
+ sizeof(Mixin2_Public_Data),
+ _class_constructor,
+ NULL
+};
+
+EO_DEFINE_CLASS(mixin2_class_get, &class_desc, MIXIN_CLASS, NULL);
+
diff --git a/src/tests/eo/mixin/mixin_mixin2.h b/src/tests/eo/mixin/mixin_mixin2.h
new file mode 100644
index 000000000..6e4b692d4
--- /dev/null
+++ b/src/tests/eo/mixin/mixin_mixin2.h
@@ -0,0 +1,12 @@
+#ifndef MIXIN2_H
+#define MIXIN2_H
+
+typedef struct
+{
+ int count;
+} Mixin2_Public_Data;
+
+#define MIXIN2_CLASS mixin2_class_get()
+const Eo_Class *mixin2_class_get(void);
+
+#endif
diff --git a/src/tests/eo/mixin/mixin_mixin3.c b/src/tests/eo/mixin/mixin_mixin3.c
new file mode 100644
index 000000000..08c2b5cc7
--- /dev/null
+++ b/src/tests/eo/mixin/mixin_mixin3.c
@@ -0,0 +1,70 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "mixin_mixin.h"
+#include "mixin_mixin3.h"
+#include "mixin_simple.h"
+
+#include "../eunit_tests.h"
+
+#define MY_CLASS MIXIN3_CLASS
+
+static void
+_ab_sum_get(Eo *obj, void *class_data EINA_UNUSED, va_list *list)
+{
+ /* This cast is just a hack for the test. */
+ Mixin3_Public_Data *pd = (Mixin3_Public_Data *) class_data;
+ int *sum = va_arg(*list, int *);
+ printf("%s %s\n", eo_class_name_get(MY_CLASS), __func__);
+ eo_do_super(obj, mixin_ab_sum_get(sum));
+
+ ++*sum;
+ pd->count += 3;
+
+ {
+ int _a, _b;
+ eo_do(obj, simple_a_get(&_a), simple_b_get(&_b));
+ fail_if(*sum != _a + _b + 2);
+ }
+}
+
+static void
+_constructor(Eo *obj, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+ eo_do_super(obj, eo_constructor());
+}
+
+static void
+_destructor(Eo *obj, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+ eo_do_super(obj, eo_destructor());
+}
+
+static void
+_class_constructor(Eo_Class *klass)
+{
+ const Eo_Op_Func_Description func_desc[] = {
+ EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor),
+ EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor),
+ EO_OP_FUNC(MIXIN_ID(MIXIN_SUB_ID_AB_SUM_GET), _ab_sum_get),
+ EO_OP_FUNC_SENTINEL
+ };
+
+ eo_class_funcs_set(klass, func_desc);
+}
+
+static const Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Mixin3",
+ EO_CLASS_TYPE_MIXIN,
+ EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
+ NULL,
+ sizeof(Mixin3_Public_Data),
+ _class_constructor,
+ NULL
+};
+
+EO_DEFINE_CLASS(mixin3_class_get, &class_desc, MIXIN_CLASS, NULL);
+
diff --git a/src/tests/eo/mixin/mixin_mixin3.h b/src/tests/eo/mixin/mixin_mixin3.h
new file mode 100644
index 000000000..36b32c0aa
--- /dev/null
+++ b/src/tests/eo/mixin/mixin_mixin3.h
@@ -0,0 +1,12 @@
+#ifndef MIXIN3_H
+#define MIXIN3_H
+
+typedef struct
+{
+ int count;
+} Mixin3_Public_Data;
+
+#define MIXIN3_CLASS mixin3_class_get()
+const Eo_Class *mixin3_class_get(void);
+
+#endif
diff --git a/src/tests/eo/mixin/mixin_mixin4.c b/src/tests/eo/mixin/mixin_mixin4.c
new file mode 100644
index 000000000..cf8f16f96
--- /dev/null
+++ b/src/tests/eo/mixin/mixin_mixin4.c
@@ -0,0 +1,26 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "mixin_mixin.h"
+#include "mixin_mixin4.h"
+#include "mixin_simple.h"
+
+#include "../eunit_tests.h"
+
+#define MY_CLASS MIXIN4_CLASS
+
+static const Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Mixin4",
+ EO_CLASS_TYPE_MIXIN,
+ EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
+ NULL,
+ 0,
+ NULL,
+ NULL
+};
+
+EO_DEFINE_CLASS(mixin4_class_get, &class_desc, NULL, NULL);
+
diff --git a/src/tests/eo/mixin/mixin_mixin4.h b/src/tests/eo/mixin/mixin_mixin4.h
new file mode 100644
index 000000000..7b520fad1
--- /dev/null
+++ b/src/tests/eo/mixin/mixin_mixin4.h
@@ -0,0 +1,7 @@
+#ifndef MIXIN4_H
+#define MIXIN4_H
+
+#define MIXIN4_CLASS mixin4_class_get()
+const Eo_Class *mixin4_class_get(void);
+
+#endif
diff --git a/src/tests/eo/mixin/mixin_simple.c b/src/tests/eo/mixin/mixin_simple.c
new file mode 100644
index 000000000..ff4600d72
--- /dev/null
+++ b/src/tests/eo/mixin/mixin_simple.c
@@ -0,0 +1,77 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "mixin_mixin.h"
+#include "mixin_mixin2.h"
+#include "mixin_mixin3.h"
+#include "mixin_simple.h"
+
+EAPI Eo_Op SIMPLE_BASE_ID = 0;
+
+typedef struct
+{
+ int a;
+ int b;
+} Private_Data;
+
+#define MY_CLASS SIMPLE_CLASS
+
+#define _GET_SET_FUNC(name) \
+static void \
+_##name##_get(Eo *obj EINA_UNUSED, void *class_data, va_list *list) \
+{ \
+ const Private_Data *pd = class_data; \
+ int *name; \
+ name = va_arg(*list, int *); \
+ *name = pd->name; \
+ printf("%s %d\n", __func__, pd->name); \
+} \
+static void \
+_##name##_set(Eo *obj EINA_UNUSED, void *class_data, va_list *list) \
+{ \
+ Private_Data *pd = class_data; \
+ int name; \
+ name = va_arg(*list, int); \
+ pd->name = name; \
+ printf("%s %d\n", __func__, pd->name); \
+}
+
+_GET_SET_FUNC(a)
+_GET_SET_FUNC(b)
+
+static void
+_class_constructor(Eo_Class *klass)
+{
+ const Eo_Op_Func_Description func_desc[] = {
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set),
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get),
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_B_SET), _b_set),
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_B_GET), _b_get),
+ EO_OP_FUNC_SENTINEL
+ };
+
+ eo_class_funcs_set(klass, func_desc);
+}
+
+static const Eo_Op_Description op_desc[] = {
+ EO_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "Set property A"),
+ EO_OP_DESCRIPTION(SIMPLE_SUB_ID_A_GET, "Get property A"),
+ EO_OP_DESCRIPTION(SIMPLE_SUB_ID_B_SET, "Set property B"),
+ EO_OP_DESCRIPTION(SIMPLE_SUB_ID_B_GET, "Get property B"),
+ EO_OP_DESCRIPTION_SENTINEL
+};
+
+static const Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Simple",
+ EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(&SIMPLE_BASE_ID, op_desc, SIMPLE_SUB_ID_LAST),
+ NULL,
+ sizeof(Private_Data),
+ _class_constructor,
+ NULL
+};
+
+EO_DEFINE_CLASS(simple_class_get, &class_desc, EO_BASE_CLASS, MIXIN3_CLASS, MIXIN2_CLASS, NULL);
diff --git a/src/tests/eo/mixin/mixin_simple.h b/src/tests/eo/mixin/mixin_simple.h
new file mode 100644
index 000000000..8df813127
--- /dev/null
+++ b/src/tests/eo/mixin/mixin_simple.h
@@ -0,0 +1,47 @@
+#ifndef SIMPLE_H
+#define SIMPLE_H
+
+extern EAPI Eo_Op SIMPLE_BASE_ID;
+
+enum {
+ SIMPLE_SUB_ID_A_SET,
+ SIMPLE_SUB_ID_A_GET,
+ SIMPLE_SUB_ID_B_SET,
+ SIMPLE_SUB_ID_B_GET,
+ SIMPLE_SUB_ID_LAST
+};
+
+#define SIMPLE_ID(sub_id) (SIMPLE_BASE_ID + sub_id)
+
+/**
+ * @def simple_a_set(a)
+ * @brief Set value to a-property
+ * @param[in] a integer value to set
+ */
+#define simple_a_set(a) SIMPLE_ID(SIMPLE_SUB_ID_A_SET), EO_TYPECHECK(int, a)
+
+/**
+ * @def simple_a_get(a)
+ * @brief Get value of a-property
+ * @param[out] integer pointer to a-value
+ */
+#define simple_a_get(a) SIMPLE_ID(SIMPLE_SUB_ID_A_GET), EO_TYPECHECK(int *, a)
+
+/**
+ * @def simple_b_set(b)
+ * @brief Set value to b-property
+ * @param[in] a integer value to set
+ */
+#define simple_b_set(b) SIMPLE_ID(SIMPLE_SUB_ID_B_SET), EO_TYPECHECK(int, b)
+
+/**
+ * @def simple_b_get(b)
+ * @brief Get value of b-property
+ * @param[out] integer pointer to b-value
+ */
+#define simple_b_get(b) SIMPLE_ID(SIMPLE_SUB_ID_B_GET), EO_TYPECHECK(int *, b)
+
+#define SIMPLE_CLASS simple_class_get()
+const Eo_Class *simple_class_get(void);
+
+#endif
diff --git a/src/tests/eo/signals/signals_main.c b/src/tests/eo/signals/signals_main.c
new file mode 100644
index 000000000..4bf20caf6
--- /dev/null
+++ b/src/tests/eo/signals/signals_main.c
@@ -0,0 +1,183 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "signals_simple.h"
+
+#include "../eunit_tests.h"
+
+static int cb_count = 0;
+
+static Eina_Bool
+_null_cb(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info)
+{
+ (void) desc;
+ (void) obj;
+ (void) data;
+ (void) event_info;
+ return EO_CALLBACK_CONTINUE;
+}
+
+static Eina_Bool
+_a_changed_cb(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info)
+{
+ (void) desc;
+ (void) obj;
+ int new_a = *((int *) event_info);
+ printf("%s event_info:'%d' data:'%d'\n", __func__, new_a, (int) data);
+
+ cb_count++;
+
+ eo_do(obj, eo_event_callback_priority_add(EV_A_CHANGED, EO_CALLBACK_PRIORITY_BEFORE, _null_cb, (void *) 23423));
+ eo_do(obj, eo_event_callback_del(EV_A_CHANGED, _null_cb, (void *) 23423));
+
+ /* Stop as we reached the 3rd one. */
+ return (cb_count != 3);
+}
+
+int
+main(int argc, char *argv[])
+{
+ (void) argc;
+ (void) argv;
+ eo_init();
+
+ Eo *obj = eo_add(SIMPLE_CLASS, NULL);
+ Simple_Public_Data *pd = eo_data_get(obj, SIMPLE_CLASS);
+
+ /* The order of these two is undetermined. */
+ eo_do(obj, eo_event_callback_priority_add(EV_A_CHANGED, EO_CALLBACK_PRIORITY_BEFORE, _a_changed_cb, (void *) 2));
+ eo_do(obj, eo_event_callback_priority_add(EV_A_CHANGED, EO_CALLBACK_PRIORITY_BEFORE, _a_changed_cb, (void *) 1));
+ /* This will be called afterwards. */
+ eo_do(obj, eo_event_callback_priority_add(EV_A_CHANGED, EO_CALLBACK_PRIORITY_DEFAULT, _a_changed_cb, (void *) 3));
+ /* This will never be called because the previous callback returns NULL. */
+ eo_do(obj, eo_event_callback_priority_add(EV_A_CHANGED, EO_CALLBACK_PRIORITY_AFTER, _a_changed_cb, (void *) 4));
+
+ eo_do(obj, simple_a_set(1));
+
+ fail_if(cb_count != 3);
+
+ eo_do(obj, eo_event_callback_del(EV_A_CHANGED, _a_changed_cb, (void *) 3));
+ fail_if(pd->cb_count != 3);
+
+ eo_do(obj, eo_event_callback_del(EV_A_CHANGED, _a_changed_cb, (void *) 12));
+ fail_if(pd->cb_count != 3);
+
+ eo_do(obj, eo_event_callback_del(EV_A_CHANGED, _a_changed_cb, (void *) 4));
+ fail_if(pd->cb_count != 2);
+
+ eo_do(obj, eo_event_callback_del(EV_A_CHANGED, _a_changed_cb, (void *) 2));
+ fail_if(pd->cb_count != 1);
+
+ eo_do(obj, eo_event_callback_del(EV_A_CHANGED, _a_changed_cb, (void *) 1));
+ fail_if(pd->cb_count != 0);
+
+ /* Freeze/thaw. */
+ int fcount = 0;
+ cb_count = 0;
+ eo_do(obj, eo_event_callback_priority_add(EV_A_CHANGED, EO_CALLBACK_PRIORITY_BEFORE, _a_changed_cb, (void *) 1));
+ fail_if(pd->cb_count != 1);
+
+ eo_do(obj, eo_event_freeze_get(&fcount));
+ fail_if(fcount != 0);
+
+ eo_do(obj, eo_event_freeze());
+ eo_do(obj, eo_event_freeze_get(&fcount));
+ fail_if(fcount != 1);
+
+ eo_do(obj, eo_event_freeze());
+ eo_do(obj, eo_event_freeze_get(&fcount));
+ fail_if(fcount != 2);
+
+ eo_do(obj, eo_event_callback_priority_add(EV_A_CHANGED, EO_CALLBACK_PRIORITY_BEFORE, _a_changed_cb, (void *) 2));
+ fail_if(pd->cb_count != 1);
+
+ eo_do(obj, simple_a_set(2));
+ fail_if(cb_count != 0);
+ eo_do(obj, eo_event_thaw());
+ eo_do(obj, eo_event_freeze_get(&fcount));
+ fail_if(fcount != 1);
+
+ eo_do(obj, eo_event_thaw());
+ eo_do(obj, eo_event_freeze_get(&fcount));
+ fail_if(fcount != 0);
+
+ eo_do(obj, simple_a_set(3));
+ fail_if(cb_count != 2);
+
+ cb_count = 0;
+ eo_do(obj, eo_event_thaw());
+ eo_do(obj, eo_event_freeze_get(&fcount));
+ fail_if(fcount != 0);
+
+ eo_do(obj, eo_event_freeze());
+ eo_do(obj, eo_event_freeze_get(&fcount));
+ fail_if(fcount != 1);
+
+ eo_do(obj, simple_a_set(2));
+ fail_if(cb_count != 0);
+ eo_do(obj, eo_event_thaw());
+ eo_do(obj, eo_event_freeze_get(&fcount));
+ fail_if(fcount != 0);
+
+ eo_do(obj, eo_event_callback_del(EV_A_CHANGED, _a_changed_cb, (void *) 1));
+ fail_if(pd->cb_count != 0);
+ eo_do(obj, eo_event_callback_del(EV_A_CHANGED, _a_changed_cb, (void *) 2));
+ fail_if(pd->cb_count != -1);
+
+ /* Global Freeze/thaw. */
+ fcount = 0;
+ cb_count = 0;
+ pd->cb_count = 0;
+ eo_do(obj, eo_event_callback_priority_add(EV_A_CHANGED, EO_CALLBACK_PRIORITY_BEFORE, _a_changed_cb, (void *) 1));
+ fail_if(pd->cb_count != 1);
+
+ eo_class_do(EO_BASE_CLASS, eo_event_global_freeze_get(&fcount));
+ fail_if(fcount != 0);
+
+ eo_class_do(EO_BASE_CLASS, eo_event_global_freeze());
+ eo_class_do(EO_BASE_CLASS, eo_event_global_freeze_get(&fcount));
+ fail_if(fcount != 1);
+
+ eo_class_do(EO_BASE_CLASS, eo_event_global_freeze());
+ eo_class_do(EO_BASE_CLASS, eo_event_global_freeze_get(&fcount));
+ fail_if(fcount != 2);
+
+ eo_do(obj, eo_event_callback_priority_add(EV_A_CHANGED, EO_CALLBACK_PRIORITY_BEFORE, _a_changed_cb, (void *) 2));
+ fail_if(pd->cb_count != 1);
+
+ eo_do(obj, simple_a_set(2));
+ fail_if(cb_count != 0);
+ eo_class_do(EO_BASE_CLASS, eo_event_global_thaw());
+ eo_class_do(EO_BASE_CLASS, eo_event_global_freeze_get(&fcount));
+ fail_if(fcount != 1);
+
+ eo_class_do(EO_BASE_CLASS, eo_event_global_thaw());
+ eo_class_do(EO_BASE_CLASS, eo_event_global_freeze_get(&fcount));
+ fail_if(fcount != 0);
+
+ eo_do(obj, simple_a_set(3));
+ fail_if(cb_count != 2);
+
+ cb_count = 0;
+ eo_class_do(EO_BASE_CLASS, eo_event_global_thaw());
+ eo_class_do(EO_BASE_CLASS, eo_event_global_freeze_get(&fcount));
+ fail_if(fcount != 0);
+
+ eo_class_do(EO_BASE_CLASS, eo_event_global_freeze());
+ eo_class_do(EO_BASE_CLASS, eo_event_global_freeze_get(&fcount));
+ fail_if(fcount != 1);
+
+ eo_do(obj, simple_a_set(2));
+ fail_if(cb_count != 0);
+ eo_class_do(EO_BASE_CLASS, eo_event_global_thaw());
+ eo_class_do(EO_BASE_CLASS, eo_event_global_freeze_get(&fcount));
+ fail_if(fcount != 0);
+
+
+ eo_unref(obj);
+ eo_shutdown();
+ return 0;
+}
+
diff --git a/src/tests/eo/signals/signals_simple.c b/src/tests/eo/signals/signals_simple.c
new file mode 100644
index 000000000..506d79813
--- /dev/null
+++ b/src/tests/eo/signals/signals_simple.c
@@ -0,0 +1,112 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "signals_simple.h"
+
+EAPI Eo_Op SIMPLE_BASE_ID = 0;
+
+typedef struct
+{
+ Simple_Public_Data pub;
+ int a;
+} Private_Data;
+
+EAPI const Eo_Event_Description _EV_A_CHANGED =
+ EO_EVENT_DESCRIPTION("a,changed", "Called when a has changed.");
+
+#define MY_CLASS SIMPLE_CLASS
+
+static void
+_a_set(Eo *obj, void *class_data, va_list *list)
+{
+ Private_Data *pd = class_data;
+ int a;
+ a = va_arg(*list, int);
+ pd->a = a;
+ printf("%s %d\n", __func__, pd->a);
+
+ eo_do(obj, eo_event_callback_call(EV_A_CHANGED, &pd->a, NULL));
+}
+
+Eina_Bool
+_cb_added(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info)
+{
+ Simple_Public_Data *pd = eo_data_get(obj, MY_CLASS);
+ const Eo_Event_Description *cb_desc = event_info;
+ (void) data;
+ (void) desc;
+
+ if (cb_desc != EV_A_CHANGED)
+ return EINA_TRUE;
+
+ pd->cb_count++;
+
+ printf("Added EV_A_CHANGED callback to %p. Count: %d\n", obj, pd->cb_count);
+ return EO_CALLBACK_CONTINUE;
+}
+
+Eina_Bool
+_cb_deled(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info)
+{
+ Simple_Public_Data *pd = eo_data_get(obj, MY_CLASS);
+ const Eo_Event_Description *cb_desc = event_info;
+ (void) data;
+ (void) desc;
+
+ if (cb_desc != EV_A_CHANGED)
+ return EINA_TRUE;
+
+ pd->cb_count--;
+
+ printf("Removed EV_A_CHANGED callback from %p. Count: %d\n", obj, pd->cb_count);
+ return EO_CALLBACK_CONTINUE;
+}
+
+static void
+_constructor(Eo *obj, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+ eo_do_super(obj, eo_constructor());
+
+ eo_do(obj, eo_event_callback_add(EO_EV_CALLBACK_ADD, _cb_added, NULL));
+ eo_do(obj, eo_event_callback_add(EO_EV_CALLBACK_DEL, _cb_deled, NULL));
+
+ eo_do(obj, eo_base_data_set("cb_count", (intptr_t) 0, NULL));
+}
+
+static void
+_class_constructor(Eo_Class *klass)
+{
+ const Eo_Op_Func_Description func_desc[] = {
+ EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor),
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set),
+ EO_OP_FUNC_SENTINEL
+ };
+
+ eo_class_funcs_set(klass, func_desc);
+}
+
+static const Eo_Op_Description op_desc[] = {
+ EO_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "Set property A"),
+ EO_OP_DESCRIPTION_SENTINEL
+};
+
+static const Eo_Event_Description *event_desc[] = {
+ EV_A_CHANGED,
+ NULL
+};
+
+static const Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Simple",
+ EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(&SIMPLE_BASE_ID, op_desc, SIMPLE_SUB_ID_LAST),
+ event_desc,
+ sizeof(Private_Data),
+ _class_constructor,
+ NULL
+};
+
+EO_DEFINE_CLASS(simple_class_get, &class_desc, EO_BASE_CLASS, NULL);
+
diff --git a/src/tests/eo/signals/signals_simple.h b/src/tests/eo/signals/signals_simple.h
new file mode 100644
index 000000000..d1f63bdd0
--- /dev/null
+++ b/src/tests/eo/signals/signals_simple.h
@@ -0,0 +1,31 @@
+#ifndef SIMPLE_H
+#define SIMPLE_H
+
+extern EAPI Eo_Op SIMPLE_BASE_ID;
+
+enum {
+ SIMPLE_SUB_ID_A_SET,
+ SIMPLE_SUB_ID_LAST
+};
+
+typedef struct
+{
+ int cb_count;
+} Simple_Public_Data;
+
+#define SIMPLE_ID(sub_id) (SIMPLE_BASE_ID + sub_id)
+
+/**
+ * @def simple_a_set(a)
+ * @brief Set value to a - property
+ * @param[in] a integer value to set
+ */
+#define simple_a_set(a) SIMPLE_ID(SIMPLE_SUB_ID_A_SET), EO_TYPECHECK(int, a)
+
+extern const Eo_Event_Description _EV_A_CHANGED;
+#define EV_A_CHANGED (&(_EV_A_CHANGED))
+
+#define SIMPLE_CLASS simple_class_get()
+const Eo_Class *simple_class_get(void);
+
+#endif
diff --git a/src/tests/eo/suite/eo_suite.c b/src/tests/eo/suite/eo_suite.c
new file mode 100644
index 000000000..0494136ce
--- /dev/null
+++ b/src/tests/eo/suite/eo_suite.c
@@ -0,0 +1,106 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "Eo.h"
+#include "eo_suite.h"
+
+typedef struct _Eo_Test_Case Eo_Test_Case;
+
+struct _Eo_Test_Case
+{
+ const char *test_case;
+ void (*build)(TCase *tc);
+};
+
+static const Eo_Test_Case etc[] = {
+ { "Eo init", eo_test_init },
+ { "Eo general", eo_test_general },
+ { "Eo class errors", eo_test_class_errors },
+ { NULL, NULL }
+};
+
+static void
+_list_tests(void)
+{
+ const Eo_Test_Case *itr;
+
+ itr = etc;
+ fputs("Available Test Cases:\n", stderr);
+ for (; itr->test_case; itr++)
+ fprintf(stderr, "\t%s\n", itr->test_case);
+}
+static Eina_Bool
+_use_test(int argc, const char **argv, const char *test_case)
+{
+ if (argc < 1)
+ return 1;
+
+ for (; argc > 0; argc--, argv++)
+ if (strcmp(test_case, *argv) == 0)
+ return 1;
+ return 0;
+}
+
+static Suite *
+eo_suite_build(int argc, const char **argv)
+{
+ TCase *tc;
+ Suite *s;
+ int i;
+
+ s = suite_create("Eo");
+
+ for (i = 0; etc[i].test_case; ++i)
+ {
+ if (!_use_test(argc, argv, etc[i].test_case)) continue;
+ tc = tcase_create(etc[i].test_case);
+
+ etc[i].build(tc);
+
+ suite_add_tcase(s, tc);
+ tcase_set_timeout(tc, 0);
+ }
+
+ return s;
+}
+
+int
+main(int argc, char **argv)
+{
+ Suite *s;
+ SRunner *sr;
+ int i, failed_count;
+ eo_init();
+ setenv("CK_FORK", "no", 0);
+
+ for (i = 1; i < argc; i++)
+ if ((strcmp(argv[i], "-h") == 0) ||
+ (strcmp(argv[i], "--help") == 0))
+ {
+ fprintf(stderr, "Usage:\n\t%s [test_case1 .. [test_caseN]]\n",
+ argv[0]);
+ _list_tests();
+ return 0;
+ }
+ else if ((strcmp(argv[i], "-l") == 0) ||
+ (strcmp(argv[i], "--list") == 0))
+ {
+ _list_tests();
+ return 0;
+ }
+
+ s = eo_suite_build(argc - 1, (const char **)argv + 1);
+ sr = srunner_create(s);
+
+ srunner_run_all(sr, CK_ENV);
+ failed_count = srunner_ntests_failed(sr);
+ srunner_free(sr);
+
+ eo_shutdown();
+
+ return (failed_count == 0) ? 0 : 255;
+}
diff --git a/src/tests/eo/suite/eo_suite.h b/src/tests/eo/suite/eo_suite.h
new file mode 100644
index 000000000..9d79f42f8
--- /dev/null
+++ b/src/tests/eo/suite/eo_suite.h
@@ -0,0 +1,11 @@
+#ifndef _EO_SUITE_H
+#define _EO_SUITE_H
+
+#include <check.h>
+
+void eo_test_init(TCase *tc);
+void eo_test_general(TCase *tc);
+void eo_test_class_errors(TCase *tc);
+
+
+#endif /* _EO_SUITE_H */
diff --git a/src/tests/eo/suite/eo_test_class_errors.c b/src/tests/eo/suite/eo_test_class_errors.c
new file mode 100644
index 000000000..77d9ef9c7
--- /dev/null
+++ b/src/tests/eo/suite/eo_test_class_errors.c
@@ -0,0 +1,350 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+
+#include "Eo.h"
+#include "eo_suite.h"
+#include "eo_test_class_simple.h"
+
+START_TEST(eo_incomplete_desc)
+{
+ eo_init();
+
+ const Eo_Class *klass;
+ static Eo_Op TMP_BASE_ID = EO_NOOP;
+
+ enum {
+ TEST_SUB_ID_FOO,
+ TEST_SUB_ID_FOO2,
+ TEST_SUB_ID_LAST
+ };
+
+ static const Eo_Op_Description op_desc[] = {
+ EO_OP_DESCRIPTION(TEST_SUB_ID_FOO, "Foo"),
+ EO_OP_DESCRIPTION(TEST_SUB_ID_FOO2, "Foo2"),
+ EO_OP_DESCRIPTION_SENTINEL
+ };
+
+ static const Eo_Op_Description op_desc_wrong[] = {
+ EO_OP_DESCRIPTION(TEST_SUB_ID_FOO2, "Foo2"),
+ EO_OP_DESCRIPTION(TEST_SUB_ID_FOO, "Foo"),
+ EO_OP_DESCRIPTION_SENTINEL
+ };
+
+ /* XXX: In real life this should be const, this is just for testing. */
+ static Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Simple",
+ EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(NULL, op_desc, 1),
+ NULL,
+ 0,
+ NULL,
+ NULL
+ };
+
+ klass = eo_class_new(&class_desc, NULL, NULL);
+ fail_if(klass);
+
+ class_desc.ops.base_op_id = &TMP_BASE_ID;
+ class_desc.ops.descs = NULL;
+
+ klass = eo_class_new(&class_desc, NULL, NULL);
+ fail_if(klass);
+
+ class_desc.ops.descs = op_desc;
+ class_desc.ops.count = TEST_SUB_ID_LAST + 1;
+
+ klass = eo_class_new(&class_desc, NULL, NULL);
+ fail_if(klass);
+
+ class_desc.ops.count = 0;
+
+ klass = eo_class_new(&class_desc, NULL, NULL);
+ fail_if(klass);
+
+ class_desc.ops.count = TEST_SUB_ID_LAST;
+ class_desc.ops.descs = op_desc_wrong;
+
+ klass = eo_class_new(&class_desc, NULL, NULL);
+ fail_if(klass);
+
+ class_desc.ops.descs = op_desc;
+ class_desc.name = NULL;
+
+ klass = eo_class_new(&class_desc, NULL, NULL);
+ fail_if(klass);
+
+ class_desc.name = "Simple";
+
+
+ klass = eo_class_new(NULL, NULL, NULL);
+ fail_if(klass);
+
+ /* Should create a class. */
+ klass = eo_class_new(&class_desc, EO_BASE_CLASS, NULL);
+ fail_if(!klass);
+
+ (void) klass;
+
+ eo_shutdown();
+}
+END_TEST
+
+START_TEST(eo_inherit_errors)
+{
+ eo_init();
+
+ const Eo_Class *klass;
+ const Eo_Class *klass_mixin;
+ const Eo_Class *klass_simple;
+
+ static const Eo_Class_Description class_desc_simple = {
+ EO_VERSION,
+ "Simple",
+ EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
+ NULL,
+ 0,
+ NULL,
+ NULL
+ };
+
+ static const Eo_Class_Description class_desc_mixin = {
+ EO_VERSION,
+ "Mixin",
+ EO_CLASS_TYPE_MIXIN,
+ EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
+ NULL,
+ 0,
+ NULL,
+ NULL
+ };
+
+ static Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "General",
+ EO_CLASS_TYPE_MIXIN,
+ EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
+ NULL,
+ 0,
+ NULL,
+ NULL
+ };
+
+ klass_mixin = eo_class_new(&class_desc_mixin, NULL, NULL);
+ fail_if(!klass_mixin);
+
+ klass_simple = eo_class_new(&class_desc_simple, EO_BASE_CLASS, NULL);
+ fail_if(!klass_simple);
+
+ klass = eo_class_new(&class_desc, klass_simple, NULL);
+ fail_if(klass);
+
+ class_desc.type = EO_CLASS_TYPE_REGULAR;
+
+ klass = eo_class_new(&class_desc, klass_mixin, NULL);
+ fail_if(klass);
+
+ (void) klass;
+
+ eo_shutdown();
+}
+END_TEST
+
+START_TEST(eo_inconsistent_mro)
+{
+ eo_init();
+
+ const Eo_Class *klass;
+ const Eo_Class *klass_mixin;
+ const Eo_Class *klass_mixin2;
+ const Eo_Class *klass_mixin3;
+
+ static const Eo_Class_Description class_desc_simple = {
+ EO_VERSION,
+ "Simple",
+ EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
+ NULL,
+ 0,
+ NULL,
+ NULL
+ };
+
+ static const Eo_Class_Description class_desc_mixin = {
+ EO_VERSION,
+ "Mixin",
+ EO_CLASS_TYPE_MIXIN,
+ EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
+ NULL,
+ 0,
+ NULL,
+ NULL
+ };
+
+ static const Eo_Class_Description class_desc_mixin2 = {
+ EO_VERSION,
+ "Mixin2",
+ EO_CLASS_TYPE_MIXIN,
+ EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
+ NULL,
+ 0,
+ NULL,
+ NULL
+ };
+
+ static const Eo_Class_Description class_desc_mixin3 = {
+ EO_VERSION,
+ "Mixin3",
+ EO_CLASS_TYPE_MIXIN,
+ EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
+ NULL,
+ 0,
+ NULL,
+ NULL
+ };
+
+ klass_mixin = eo_class_new(&class_desc_mixin, NULL, NULL);
+ fail_if(!klass_mixin);
+
+ klass_mixin2 = eo_class_new(&class_desc_mixin2, klass_mixin, NULL);
+ fail_if(!klass_mixin2);
+
+ klass_mixin3 = eo_class_new(&class_desc_mixin3, klass_mixin, NULL);
+ fail_if(!klass_mixin3);
+
+ klass = eo_class_new(&class_desc_simple, EO_BASE_CLASS, klass_mixin, klass_mixin2, NULL);
+ fail_if(klass);
+
+ klass = eo_class_new(&class_desc_simple, EO_BASE_CLASS, klass_mixin2, klass_mixin, NULL);
+ fail_if(!klass);
+
+ klass = eo_class_new(&class_desc_simple, EO_BASE_CLASS, klass_mixin2, klass_mixin3, NULL);
+ fail_if(!klass);
+
+ eo_shutdown();
+}
+END_TEST
+
+static void _stub_class_constructor(Eo_Class *klass EINA_UNUSED) {}
+
+START_TEST(eo_bad_interface)
+{
+ eo_init();
+
+ const Eo_Class *klass;
+
+ static Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Interface",
+ EO_CLASS_TYPE_INTERFACE,
+ EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
+ NULL,
+ 10,
+ NULL,
+ NULL
+ };
+
+ klass = eo_class_new(&class_desc, NULL, NULL);
+ fail_if(klass);
+
+ class_desc.data_size = 0;
+ class_desc.class_constructor = _stub_class_constructor;
+
+ klass = eo_class_new(&class_desc, NULL, NULL);
+ fail_if(!klass);
+
+ class_desc.class_constructor = NULL;
+ class_desc.class_destructor = _stub_class_constructor;
+
+ klass = eo_class_new(&class_desc, NULL, NULL);
+ fail_if(!klass);
+
+ class_desc.class_destructor = NULL;
+
+ klass = eo_class_new(&class_desc, NULL, NULL);
+ fail_if(!klass);
+
+ eo_shutdown();
+}
+END_TEST
+
+static int _const_ops_counter = 0;
+
+static void
+_const_ops_a_set(Eo *obj EINA_UNUSED, void *class_data EINA_UNUSED, va_list *list)
+{
+ int a = va_arg(*list, int);
+ (void) a;
+ _const_ops_counter++;
+}
+
+static void
+_const_ops_a_print(Eo *obj EINA_UNUSED, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+ _const_ops_counter++;
+}
+
+static void
+_const_ops_class_hi_print(Eo *obj EINA_UNUSED, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+ _const_ops_counter++;
+}
+
+static void
+_const_ops_class_constructor(Eo_Class *klass)
+{
+ const Eo_Op_Func_Description func_desc[] = {
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), (eo_op_func_type) _const_ops_a_set),
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT), (eo_op_func_type) _const_ops_a_print),
+ EO_OP_FUNC_CLASS(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), (eo_op_func_type_class) _const_ops_a_set),
+ EO_OP_FUNC_CLASS(SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT), (eo_op_func_type_class) _const_ops_a_print),
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_CLASS_HI_PRINT), (eo_op_func_type) _const_ops_class_hi_print),
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_CLASS_HI_PRINT), (eo_op_func_type) _const_ops_class_hi_print),
+ EO_OP_FUNC_SENTINEL
+ };
+
+ eo_class_funcs_set(klass, func_desc);
+}
+
+START_TEST(eo_op_types)
+{
+ eo_init();
+
+ const Eo_Class *klass;
+
+ static Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Simple",
+ EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
+ NULL,
+ 0,
+ _const_ops_class_constructor,
+ NULL
+ };
+
+ klass = eo_class_new(&class_desc, SIMPLE_CLASS, NULL);
+ fail_if(!klass);
+
+ /* Add class checks here... */
+ Eo *obj = eo_add(klass, NULL);
+ eo_do(obj, simple_a_set(7), simple_a_print(), simple_class_hi_print());
+
+ eo_unref(obj);
+
+ eo_shutdown();
+}
+END_TEST
+
+void eo_test_class_errors(TCase *tc)
+{
+ tcase_add_test(tc, eo_incomplete_desc);
+ tcase_add_test(tc, eo_inherit_errors);
+ tcase_add_test(tc, eo_inconsistent_mro);
+ tcase_add_test(tc, eo_bad_interface);
+ tcase_add_test(tc, eo_op_types);
+}
diff --git a/src/tests/eo/suite/eo_test_class_simple.c b/src/tests/eo/suite/eo_test_class_simple.c
new file mode 100644
index 000000000..224f5b5a5
--- /dev/null
+++ b/src/tests/eo/suite/eo_test_class_simple.c
@@ -0,0 +1,69 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eo.h"
+#include "eo_test_class_simple.h"
+
+#define MY_CLASS SIMPLE_CLASS
+
+EAPI Eo_Op SIMPLE_BASE_ID = 0;
+
+static void
+_a_set(Eo *obj EINA_UNUSED, void *class_data, va_list *list)
+{
+ Simple_Public_Data *pd = class_data;
+ int a;
+ a = va_arg(*list, int);
+ printf("%s %d\n", eo_class_name_get(MY_CLASS), a);
+ pd->a = a;
+}
+
+static void
+_a_print(Eo *obj EINA_UNUSED, void *class_data, va_list *list)
+{
+ const Simple_Public_Data *pd = class_data;
+ (void) list;
+ printf("Print %s %d\n", eo_class_name_get(MY_CLASS), pd->a);
+}
+
+static void
+_class_hi_print(const Eo_Class *klass, va_list *list)
+{
+ (void) list;
+ printf("Hi Print %s\n", eo_class_name_get(klass));
+}
+
+static void
+_class_constructor(Eo_Class *klass)
+{
+ const Eo_Op_Func_Description func_desc[] = {
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set),
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT), _a_print),
+ EO_OP_FUNC_CLASS(SIMPLE_ID(SIMPLE_SUB_ID_CLASS_HI_PRINT), _class_hi_print),
+ EO_OP_FUNC_SENTINEL
+ };
+
+ eo_class_funcs_set(klass, func_desc);
+}
+
+static const Eo_Op_Description op_desc[] = {
+ EO_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "Set property A"),
+ EO_OP_DESCRIPTION(SIMPLE_SUB_ID_A_PRINT, "Print property A"),
+ EO_OP_DESCRIPTION_CLASS(SIMPLE_SUB_ID_CLASS_HI_PRINT, "Print Hi"),
+ EO_OP_DESCRIPTION_SENTINEL
+};
+
+static const Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Simple",
+ EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(&SIMPLE_BASE_ID, op_desc, SIMPLE_SUB_ID_LAST),
+ NULL,
+ sizeof(Simple_Public_Data),
+ _class_constructor,
+ NULL
+};
+
+EO_DEFINE_CLASS(simple_class_get, &class_desc, EO_BASE_CLASS, NULL)
+
diff --git a/src/tests/eo/suite/eo_test_class_simple.h b/src/tests/eo/suite/eo_test_class_simple.h
new file mode 100644
index 000000000..9980b7b93
--- /dev/null
+++ b/src/tests/eo/suite/eo_test_class_simple.h
@@ -0,0 +1,30 @@
+#ifndef SIMPLE_H
+#define SIMPLE_H
+
+extern EAPI Eo_Op SIMPLE_BASE_ID;
+
+enum {
+ SIMPLE_SUB_ID_A_SET,
+ SIMPLE_SUB_ID_A_PRINT,
+ SIMPLE_SUB_ID_CLASS_HI_PRINT,
+ SIMPLE_SUB_ID_LAST
+};
+
+typedef struct
+{
+ int a;
+} Simple_Public_Data;
+
+#define SIMPLE_ID(sub_id) (SIMPLE_BASE_ID + sub_id)
+
+#define simple_a_set(a) SIMPLE_ID(SIMPLE_SUB_ID_A_SET), EO_TYPECHECK(int, a)
+#define simple_a_print() SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT)
+#define simple_class_hi_print() SIMPLE_ID(SIMPLE_SUB_ID_CLASS_HI_PRINT)
+
+extern const Eo_Event_Description _SIG_A_CHANGED;
+#define SIG_A_CHANGED (&(_SIG_A_CHANGED))
+
+#define SIMPLE_CLASS simple_class_get()
+const Eo_Class *simple_class_get(void);
+
+#endif
diff --git a/src/tests/eo/suite/eo_test_general.c b/src/tests/eo/suite/eo_test_general.c
new file mode 100644
index 000000000..095261388
--- /dev/null
+++ b/src/tests/eo/suite/eo_test_general.c
@@ -0,0 +1,752 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+
+#include "Eo.h"
+#include "eo_suite.h"
+#include "eo_test_class_simple.h"
+
+START_TEST(eo_simple)
+{
+ eo_init();
+ Eo *obj = eo_add(EO_BASE_CLASS, NULL);
+ fail_if(obj);
+
+ obj = eo_add(SIMPLE_CLASS, NULL);
+ fail_if(!obj);
+ eo_do(obj, eo_constructor());
+ eo_do(obj, eo_destructor());
+ eo_unref(obj);
+
+ eo_shutdown();
+}
+END_TEST
+
+START_TEST(eo_data_fetch)
+{
+ eo_init();
+
+ /* Usually should be const, not const only for the test... */
+ static Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Simple2",
+ EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
+ NULL,
+ 10,
+ NULL,
+ NULL
+ };
+
+ const Eo_Class *klass = eo_class_new(&class_desc, EO_BASE_CLASS, NULL);
+ fail_if(!klass);
+
+ Eo *obj = eo_add(klass, NULL);
+ fail_if(!obj);
+#ifndef NDEBUG
+ fail_if(eo_data_get(obj, SIMPLE_CLASS));
+#endif
+ eo_unref(obj);
+
+ class_desc.data_size = 0;
+ klass = eo_class_new(&class_desc, EO_BASE_CLASS, NULL);
+ fail_if(!klass);
+
+ obj = eo_add(klass, NULL);
+ fail_if(!obj);
+ fail_if(eo_data_get(obj, klass));
+ eo_unref(obj);
+
+ eo_shutdown();
+}
+END_TEST
+
+START_TEST(eo_isa_tests)
+{
+ eo_init();
+
+ const Eo_Class *klass, *iface, *mixin;
+
+ {
+ /* Usually should be const, not const only for the test... */
+ static Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Iface",
+ EO_CLASS_TYPE_INTERFACE,
+ EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
+ NULL,
+ 0,
+ NULL,
+ NULL
+ };
+
+ iface = eo_class_new(&class_desc, NULL, NULL);
+ fail_if(!iface);
+ }
+
+ {
+ /* Usually should be const, not const only for the test... */
+ static Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Mixin",
+ EO_CLASS_TYPE_MIXIN,
+ EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
+ NULL,
+ 0,
+ NULL,
+ NULL
+ };
+
+ mixin = eo_class_new(&class_desc, NULL, NULL);
+ fail_if(!mixin);
+ }
+
+ {
+ /* Usually should be const, not const only for the test... */
+ static Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Simple2",
+ EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
+ NULL,
+ 10,
+ NULL,
+ NULL
+ };
+
+ klass = eo_class_new(&class_desc, EO_BASE_CLASS, iface, mixin, NULL);
+ fail_if(!klass);
+ }
+
+ Eo *obj = eo_add(klass, NULL);
+ fail_if(!obj);
+ fail_if(eo_isa(obj, SIMPLE_CLASS));
+ fail_if(!eo_isa(obj, iface));
+ fail_if(!eo_isa(obj, mixin));
+ fail_if(!eo_isa(obj, klass));
+ fail_if(!eo_isa(obj, EO_BASE_CLASS));
+ eo_unref(obj);
+
+ obj = eo_add(SIMPLE_CLASS, NULL);
+ fail_if(!obj);
+ fail_if(eo_isa(obj, klass));
+ fail_if(eo_isa(obj, iface));
+ fail_if(eo_isa(obj, mixin));
+ fail_if(!eo_isa(obj, SIMPLE_CLASS));
+ fail_if(!eo_isa(obj, EO_BASE_CLASS));
+ eo_unref(obj);
+
+ eo_shutdown();
+}
+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_attach(obj2, obj);
+ eo_parent_set(obj2, NULL);
+ fail_if(eo_composite_is(obj2));
+
+ eo_unref(obj2);
+ eo_unref(obj);
+
+ eo_shutdown();
+}
+END_TEST
+
+static Eina_Bool _man_should_con = EINA_TRUE;
+static Eina_Bool _man_should_des = EINA_TRUE;
+
+static void
+_man_con(Eo *obj, void *data EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+ if (_man_should_con)
+ eo_manual_free_set(obj, EINA_TRUE);
+ eo_do_super(obj, eo_constructor());
+}
+
+static void
+_man_des(Eo *obj, void *data EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+ eo_do_super(obj, eo_destructor());
+ if (_man_should_des)
+ eo_manual_free_set(obj, EINA_FALSE);
+}
+
+
+static void
+_man_class_constructor(Eo_Class *klass)
+{
+ const Eo_Op_Func_Description func_desc[] = {
+ EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _man_con),
+ EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _man_des),
+ EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _man_des),
+ EO_OP_FUNC_SENTINEL
+ };
+
+ eo_class_funcs_set(klass, func_desc);
+}
+
+START_TEST(eo_man_free)
+{
+ eo_init();
+
+ /* Usually should be const, not const only for the test... */
+ static Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Simple2",
+ EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
+ NULL,
+ 10,
+ _man_class_constructor,
+ NULL
+ };
+
+ const Eo_Class *klass = eo_class_new(&class_desc, 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);
+
+ _man_should_des = EINA_FALSE;
+ klass = eo_class_new(&class_desc, EO_BASE_CLASS, NULL);
+ fail_if(!klass);
+
+ obj = eo_add(klass, NULL);
+ fail_if(!obj);
+ eo_manual_free(obj);
+ fail_if(eo_destructed_is(obj));
+ eo_unref(obj);
+ fail_if(!eo_destructed_is(obj));
+ eo_manual_free(obj);
+
+ obj = eo_add(klass, NULL);
+ fail_if(!obj);
+ eo_unref(obj);
+ fail_if(!eo_destructed_is(obj));
+ eo_manual_free(obj);
+
+ _man_should_con = EINA_FALSE;
+ klass = eo_class_new(&class_desc, 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);
+
+ 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_unref(obj);
+ eo_unref(obj);
+ eo_manual_free(obj);
+
+ eo_shutdown();
+}
+END_TEST
+
+START_TEST(eo_refs)
+{
+ eo_init();
+ Eo *obj = eo_add(SIMPLE_CLASS, NULL);
+ Eo *obj2 = eo_add(SIMPLE_CLASS, NULL);
+ Eo *obj3 = eo_add(SIMPLE_CLASS, NULL);
+
+ eo_xref(obj, obj2);
+ fail_if(eo_ref_get(obj) != 2);
+ eo_xref(obj, obj3);
+ fail_if(eo_ref_get(obj) != 3);
+
+ eo_xunref(obj, obj2);
+ fail_if(eo_ref_get(obj) != 2);
+ eo_xunref(obj, obj3);
+ fail_if(eo_ref_get(obj) != 1);
+
+#ifndef NDEBUG
+ eo_xunref(obj, obj3);
+ fail_if(eo_ref_get(obj) != 1);
+
+ eo_xref(obj, obj2);
+ fail_if(eo_ref_get(obj) != 2);
+
+ eo_xunref(obj, obj3);
+ fail_if(eo_ref_get(obj) != 2);
+
+ eo_xunref(obj, obj2);
+ 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_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();
+}
+END_TEST
+
+START_TEST(eo_weak_reference)
+{
+ eo_init();
+
+ Eo *obj = eo_add(SIMPLE_CLASS, NULL);
+ Eo *obj2 = eo_add(SIMPLE_CLASS, NULL);
+ Eo *wref, *wref2, *wref3;
+ eo_do(obj, eo_wref_add(&wref));
+ fail_if(!wref);
+
+ eo_unref(obj);
+ fail_if(wref);
+
+ obj = eo_add(SIMPLE_CLASS, NULL);
+ eo_do(obj, eo_wref_add(&wref));
+
+ eo_ref(obj);
+ fail_if(!wref);
+
+ eo_unref(obj);
+ fail_if(!wref);
+
+ eo_unref(obj);
+ fail_if(wref);
+
+ obj = eo_add(SIMPLE_CLASS, NULL);
+
+ eo_do(obj, eo_wref_add(&wref));
+ eo_do(obj, eo_wref_del(&wref));
+ fail_if(wref);
+
+ eo_do(obj, eo_wref_add(&wref));
+ eo_do(obj2, eo_wref_del(&wref));
+ fail_if(!wref);
+ eo_wref_del_safe(&wref);
+ fail_if(wref);
+
+ wref = obj;
+ eo_do(obj, eo_wref_del(&wref));
+ fail_if(wref);
+
+ wref = wref2 = wref3 = NULL;
+ eo_do(obj, eo_wref_add(&wref), eo_wref_add(&wref2), eo_wref_add(&wref3));
+ fail_if(!wref);
+ fail_if(!wref2);
+ fail_if(!wref3);
+ eo_do(obj, eo_wref_del(&wref), eo_wref_del(&wref2), eo_wref_del(&wref3));
+ fail_if(wref);
+ fail_if(wref2);
+ fail_if(wref3);
+
+ eo_do(obj, eo_wref_add(&wref2), eo_wref_add(&wref3));
+ wref = obj;
+ eo_do(obj, eo_wref_del(&wref));
+ fail_if(wref);
+ eo_do(obj, eo_wref_del(&wref2), eo_wref_del(&wref3));
+
+ eo_unref(obj);
+ eo_unref(obj2);
+
+
+ eo_shutdown();
+}
+END_TEST
+
+static void
+_a_set(Eo *obj EINA_UNUSED, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+ fail_if(EINA_TRUE);
+}
+
+static void
+_op_errors_class_constructor(Eo_Class *klass)
+{
+ const Eo_Op_Func_Description func_desc[] = {
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_LAST), _a_set),
+ EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_LAST + 1), _a_set),
+ EO_OP_FUNC(0x0F010111, _a_set),
+ EO_OP_FUNC_SENTINEL
+ };
+
+ eo_class_funcs_set(klass, func_desc);
+}
+
+START_TEST(eo_op_errors)
+{
+ eo_init();
+
+ static const Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Simple",
+ EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
+ NULL,
+ 0,
+ _op_errors_class_constructor,
+ NULL
+ };
+
+ const Eo_Class *klass = eo_class_new(&class_desc, 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, EO_BASE_ID(0x0111)));
+
+ /* Ilegal class. */
+ fail_if(eo_do(obj, 0x0F010111));
+
+ fail_if(eo_ref_get(obj) != 1);
+
+ eo_ref(obj);
+ fail_if(eo_ref_get(obj) != 2);
+
+ eo_ref(obj);
+ fail_if(eo_ref_get(obj) != 3);
+
+ eo_unref(obj);
+ fail_if(eo_ref_get(obj) != 2);
+
+ eo_unref(obj);
+ fail_if(eo_ref_get(obj) != 1);
+
+ eo_unref(obj);
+
+ obj = eo_add(SIMPLE_CLASS, NULL);
+ fail_if(!eo_do(obj, simple_a_print()));
+ fail_if(!eo_do(obj, simple_a_print()));
+ fail_if(!eo_do(obj, simple_a_set(1)));
+ eo_unref(obj);
+
+ eo_shutdown();
+}
+END_TEST
+
+static void
+_fake_free_func(void *data)
+{
+ if (!data)
+ return;
+
+ int *a = data;
+ ++*a;
+}
+
+START_TEST(eo_generic_data)
+{
+ eo_init();
+ Eo *obj = eo_add(SIMPLE_CLASS, NULL);
+ void *data;
+
+ eo_do(obj, eo_base_data_set("test1", (void *) 1, NULL));
+ eo_do(obj, eo_base_data_get("test1", &data));
+ fail_if(1 != (int) data);
+ eo_do(obj, eo_base_data_del("test1"));
+ eo_do(obj, eo_base_data_get("test1", &data));
+ fail_if(data);
+
+ eo_do(obj, eo_base_data_set("test1", (void *) 1, NULL));
+ eo_do(obj, eo_base_data_set("test2", (void *) 2, NULL));
+ eo_do(obj, eo_base_data_get("test1", &data));
+ fail_if(1 != (int) data);
+ eo_do(obj, eo_base_data_get("test2", &data));
+ fail_if(2 != (int) data);
+
+ eo_do(obj, eo_base_data_get("test2", &data));
+ fail_if(2 != (int) data);
+ eo_do(obj, eo_base_data_del("test2"));
+ eo_do(obj, eo_base_data_get("test2", &data));
+ fail_if(data);
+
+ eo_do(obj, eo_base_data_get("test1", &data));
+ fail_if(1 != (int) data);
+ eo_do(obj, eo_base_data_del("test1"));
+ eo_do(obj, eo_base_data_get("test1", &data));
+ fail_if(data);
+
+ int a = 0;
+ eo_do(obj, eo_base_data_set("test3", &a, _fake_free_func));
+ eo_do(obj, eo_base_data_get("test3", &data));
+ fail_if(&a != data);
+ eo_do(obj, eo_base_data_get("test3", NULL));
+ eo_do(obj, eo_base_data_del("test3"));
+ fail_if(a != 1);
+
+ a = 0;
+ eo_do(obj, eo_base_data_set("test3", &a, _fake_free_func));
+ eo_do(obj, eo_base_data_set("test3", NULL, _fake_free_func));
+ fail_if(a != 1);
+ a = 0;
+ data = (void *) 123;
+ eo_do(obj, eo_base_data_set(NULL, &a, _fake_free_func));
+ eo_do(obj, eo_base_data_get(NULL, &data));
+ fail_if(data);
+ eo_do(obj, eo_base_data_del(NULL));
+
+ a = 0;
+ eo_do(obj, eo_base_data_set("test3", &a, _fake_free_func));
+ eo_do(obj, eo_base_data_set("test3", NULL, NULL));
+ fail_if(a != 1);
+ eo_do(obj, eo_base_data_set("test3", &a, _fake_free_func));
+
+ eo_unref(obj);
+ fail_if(a != 2);
+
+ eo_shutdown();
+}
+END_TEST
+
+START_TEST(eo_magic_checks)
+{
+ 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(SIMPLE_CLASS, (Eo *) buf);
+ fail_if(obj);
+
+ while (1)
+ {
+ obj = eo_add((Eo_Class *) buf, NULL);
+ fail_if(obj);
+
+ obj = eo_add(SIMPLE_CLASS, 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);
+ eo_class_do((Eo_Class *) buf, NULL);
+ eo_class_do_super((Eo_Class *) buf, EO_NOOP);
+
+ fail_if(eo_class_new(NULL, (Eo_Class *) buf), NULL);
+
+ eo_xref(obj, (Eo *) buf);
+ eo_xunref(obj, (Eo *) buf);
+ eo_xref((Eo *) buf, obj);
+ eo_xunref((Eo *) buf, obj);
+
+ eo_ref((Eo *) buf);
+ eo_unref((Eo *) buf);
+ eo_del((Eo *) buf);
+
+ eo_isa((Eo *) buf, SIMPLE_CLASS);
+ eo_isa(obj, (Eo_Class *) buf);
+
+ fail_if(0 != eo_ref_get((Eo *) buf));
+
+ Eo *wref = NULL;
+ eo_do((Eo *) buf, eo_wref_add(&wref));
+ fail_if(wref);
+
+ fail_if(eo_parent_get((Eo *) buf));
+
+ eo_error_set((Eo *) buf);
+
+ fail_if(eo_data_get((Eo *) buf, SIMPLE_CLASS));
+
+ eo_composite_attach((Eo *) buf, obj);
+ eo_composite_attach(obj, (Eo *) buf);
+ eo_composite_detach((Eo *) buf, obj);
+ eo_composite_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_manual_free_set((Eo *) buf, EINA_TRUE);
+ eo_manual_free((Eo *) buf);
+ eo_destructed_is((Eo *) buf);
+
+ eo_unref(obj);
+
+ if (!buf)
+ break;
+ else
+ buf = NULL;
+ }
+
+ eo_shutdown();
+}
+END_TEST
+
+/* MULTI */
+static Eo_Op MULTI_BASE_ID;
+#define MULTI_ID(sub_id) (MULTI_BASE_ID + sub_id)
+#define multi_a_print() MULTI_ID(MULTI_SUB_ID_A_PRINT)
+#define multi_class_hi_print() MULTI_ID(MULTI_SUB_ID_CLASS_HI_PRINT)
+
+static void
+_a_print(Eo *obj EINA_UNUSED, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+ printf("Hey\n");
+}
+
+static void
+_class_hi_print(const Eo_Class *klass EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+ printf("Hi\n");
+}
+
+enum {
+ MULTI_SUB_ID_A_PRINT,
+ MULTI_SUB_ID_CLASS_HI_PRINT,
+ MULTI_SUB_ID_LAST
+};
+
+static void
+_eo_multiple_do_class_constructor(Eo_Class *klass)
+{
+ const Eo_Op_Func_Description func_desc[] = {
+ EO_OP_FUNC(MULTI_ID(MULTI_SUB_ID_A_PRINT), _a_print),
+ EO_OP_FUNC_CLASS(MULTI_ID(MULTI_SUB_ID_CLASS_HI_PRINT), _class_hi_print),
+ EO_OP_FUNC_SENTINEL
+ };
+
+ eo_class_funcs_set(klass, func_desc);
+}
+
+static const Eo_Op_Description _eo_multiple_do_op_desc[] = {
+ EO_OP_DESCRIPTION(MULTI_SUB_ID_A_PRINT, "Print property A"),
+ EO_OP_DESCRIPTION_CLASS(MULTI_SUB_ID_CLASS_HI_PRINT, "Print Hi"),
+ EO_OP_DESCRIPTION_SENTINEL
+};
+
+
+START_TEST(eo_multiple_do)
+{
+ eo_init();
+
+ /* Usually should be const, not const only for the test... */
+ static Eo_Class_Description class_desc = {
+ EO_VERSION,
+ "Inherit",
+ EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(&MULTI_BASE_ID, _eo_multiple_do_op_desc, MULTI_SUB_ID_LAST),
+ NULL,
+ 0,
+ _eo_multiple_do_class_constructor,
+ NULL
+ };
+
+ const Eo_Class *klass = eo_class_new(&class_desc, SIMPLE_CLASS, NULL);
+ fail_if(!klass);
+
+ Eo *obj = eo_add(klass, NULL);
+ fail_if(!obj);
+
+ fail_if(!eo_do(obj, simple_a_print(), multi_a_print(), multi_a_print()));
+ fail_if(!eo_class_do(klass, simple_class_hi_print(), multi_class_hi_print(), multi_class_hi_print()));
+
+ eo_unref(obj);
+
+ eo_shutdown();
+}
+END_TEST
+
+START_TEST(eo_add_do_and_custom)
+{
+ Simple_Public_Data *pd = NULL;
+ Eo *obj = NULL;
+ eo_init();
+
+ obj = eo_add_custom(SIMPLE_CLASS, NULL, eo_constructor());
+ fail_if(!obj);
+ eo_unref(obj);
+
+ obj = eo_add(SIMPLE_CLASS, NULL, simple_a_set(7));
+ fail_if(!obj);
+ pd = eo_data_get(obj, SIMPLE_CLASS);
+ fail_if(pd->a != 7);
+ eo_unref(obj);
+
+ obj = eo_add_custom(SIMPLE_CLASS, NULL, eo_constructor(), simple_a_set(7));
+ fail_if(!obj);
+ pd = eo_data_get(obj, SIMPLE_CLASS);
+ fail_if(pd->a != 7);
+ eo_unref(obj);
+
+ eo_shutdown();
+}
+END_TEST
+
+void eo_test_general(TCase *tc)
+{
+ tcase_add_test(tc, eo_generic_data);
+ tcase_add_test(tc, eo_op_errors);
+ tcase_add_test(tc, eo_simple);
+ tcase_add_test(tc, eo_weak_reference);
+ 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_composite_tests);
+ tcase_add_test(tc, eo_isa_tests);
+ tcase_add_test(tc, eo_multiple_do);
+ tcase_add_test(tc, eo_add_do_and_custom);
+}
diff --git a/src/tests/eo/suite/eo_test_init.c b/src/tests/eo/suite/eo_test_init.c
new file mode 100644
index 000000000..3bf4b49cb
--- /dev/null
+++ b/src/tests/eo/suite/eo_test_init.c
@@ -0,0 +1,22 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+
+#include "Eo.h"
+#include "eo_suite.h"
+
+START_TEST(eo_simple)
+{
+ fail_if(!eo_init()); /* one init by test suite */
+ fail_if(eo_init() != 1);
+ fail_if(eo_shutdown() != 1);
+ fail_if(!eo_shutdown());
+}
+END_TEST
+
+void eo_test_init(TCase *tc)
+{
+ tcase_add_test(tc, eo_simple);
+}