aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am16
-rw-r--r--cmakeconfig/EsoapModelConfig.cmake.in32
-rw-r--r--cmakeconfig/EsoapModelCxxConfig.cmake.in30
-rw-r--r--configure.ac51
-rw-r--r--pc/esoap_model-cxx.pc.in12
-rw-r--r--pc/esoap_model.pc.in12
-rw-r--r--src/Makefile.am2
-rw-r--r--src/Makefile_EsoapModel.am84
-rw-r--r--src/Makefile_EsoapModel_Cxx.am22
-rw-r--r--src/lib/esoap_model/Esoap_Model.h63
-rw-r--r--src/lib/esoap_model/esoap_model.c470
-rw-r--r--src/lib/esoap_model/esoap_model.eo36
-rw-r--r--src/lib/esoap_model/esoap_model_private.h35
-rw-r--r--src/tests/esoap_model/esoap_model_suite.c119
-rw-r--r--src/tests/esoap_model/esoap_model_suite.h16
-rw-r--r--src/tests/esoap_model/esoap_model_test_esoap_model.c238
-rw-r--r--src/tests/esoap_model/esoap_model_test_esoap_model.h6
17 files changed, 1242 insertions, 2 deletions
diff --git a/Makefile.am b/Makefile.am
index 1fc5897382..22a191227d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -152,7 +152,8 @@ pc/emotion.pc \
pc/ethumb.pc \
pc/ethumb_client.pc \
pc/elocation.pc \
-pc/eflat_xml_model.pc
+pc/eflat_xml_model.pc \
+pc/esoap_model.pc
if HAVE_CXX11
pkgconfig_DATA += \
@@ -165,7 +166,8 @@ pc/edje-cxx.pc \
pc/eet-cxx.pc \
pc/eo-cxx.pc \
pc/eio-cxx.pc \
-pc/eflat_xml_model-cxx.pc
+pc/eflat_xml_model-cxx.pc \
+pc/esoap_model-cxx.pc
endif
if HAVE_ELUA
@@ -394,6 +396,16 @@ eflat_xml_model_cmakeconfig_DATA = \
cmakeconfig/EflatXmlModelConfig.cmake \
cmakeconfig/EflatXmlModelConfigVersion.cmake
+esoap_model_cxx_cmakeconfigdir = $(libdir)/cmake/EsoapModelCxx/
+esoap_model_cxx_cmakeconfig_DATA = \
+cmakeconfig/EsoapModelCxxConfig.cmake \
+cmakeconfig/EsoapModelCxxConfigVersion.cmake
+
+esoap_model_cmakeconfigdir = $(libdir)/cmake/EsoapModel/
+esoap_model_cmakeconfig_DATA = \
+cmakeconfig/EsoapModelConfig.cmake \
+cmakeconfig/EsoapModelConfigVersion.cmake
+
# D-Bus services:
servicedir = @dbusservicedir@
diff --git a/cmakeconfig/EsoapModelConfig.cmake.in b/cmakeconfig/EsoapModelConfig.cmake.in
new file mode 100644
index 0000000000..701d07054e
--- /dev/null
+++ b/cmakeconfig/EsoapModelConfig.cmake.in
@@ -0,0 +1,32 @@
+# - Try to find esoap_model
+# Once done this will define
+# ESOAP_MODEL_FOUND - System has esoap_model
+# ESOAP_MODEL_INCLUDE_DIRS - The esoap_model include directories
+# ESOAP_MODEL_LIBRARIES - The libraries needed to use esoap_model
+# ESOAP_MODEL_DEFINITIONS - Compiler switches required for using esoap_model
+
+set(MY_PKG esoap_model)
+
+find_package(PkgConfig)
+if ("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_GREATER "2.8.1")
+ # "QUIET" was introduced in 2.8.2
+ set(_QUIET QUIET)
+endif ()
+pkg_check_modules(PC_LIBESOAP_MODEL ${_QUIET} ${MY_PKG})
+
+find_library(ESOAP_MODEL_LIBRARY
+ NAMES ${PC_LIBESOAP_MODEL_LIBRARIES}
+ HINTS ${PC_LIBESOAP_MODEL_LIBDIR} ${PC_LIBESOAP_MODEL_LIBRARY_DIRS} )
+
+set(ESOAP_MODEL_DEFINITIONS ${PC_LIBESOAP_MODEL_CFLAGS_OTHER})
+set(ESOAP_MODEL_LIBRARIES ${ESOAP_MODEL_LIBRARY})
+set(ESOAP_MODEL_INCLUDE_DIRS ${PC_LIBESOAP_MODEL_INCLUDE_DIRS})
+
+include(FindPackageHandleStandardArgs)
+# handle the QUIETLY and REQUIRED arguments and set ESOAP_MODEL_FOUND to TRUE
+# if all listed variables are TRUE
+find_package_handle_standard_args(${MY_PKG} DEFAULT_MSG
+ ESOAP_MODEL_LIBRARIES ESOAP_MODEL_INCLUDE_DIRS)
+
+mark_as_advanced(ESOAP_MODEL_INCLUDE_DIRS ESOAP_MODEL_LIBRARY ESOAP_MODEL_LIBRARIES ESOAP_MODEL_DEFINITIONS)
+
diff --git a/cmakeconfig/EsoapModelCxxConfig.cmake.in b/cmakeconfig/EsoapModelCxxConfig.cmake.in
new file mode 100644
index 0000000000..4a91e04b73
--- /dev/null
+++ b/cmakeconfig/EsoapModelCxxConfig.cmake.in
@@ -0,0 +1,30 @@
+# - Try to find esoap_model
+# Once done this will define
+# ESOAP_MODEL_CXX_FOUND - System has esoap_model
+# ESOAP_MODEL_CXX_INCLUDE_DIRS - The esoap_model include directories
+# ESOAP_MODEL_CXX_LIBRARIES - The libraries needed to use esoap_model
+# ESOAP_MODEL_CXX_DEFINITIONS - Compiler switches required for using esoap_model
+
+set(MY_PKG esoap_model_cxx)
+
+find_package(PkgConfig)
+if ("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_GREATER "2.8.1")
+ # "QUIET" was introduced in 2.8.2
+ set(_QUIET QUIET)
+endif ()
+pkg_check_modules(PC_ESOAP_MODEL_CXX ${_QUIET} ${MY_PKG})
+find_library(ESOAP_MODEL_CXX_LIBRARY
+ NAMES ${PC_ESOAP_MODEL_CXX_LIBRARIES}
+ HINTS ${PC_ESOAP_MODEL_CXX_LIBDIR} ${PC_ESOAP_MODEL_CXX_LIBRARY_DIRS} )
+
+set(ESOAP_MODEL_CXX_DEFINITIONS ${PC_ESOAP_MODEL_CXX_CFLAGS_OTHER})
+set(ESOAP_MODEL_CXX_LIBRARIES ${ESOAP_MODEL_CXX_LIBRARY})
+set(ESOAP_MODEL_CXX_INCLUDE_DIRS ${PC_ESOAP_MODEL_CXX_INCLUDE_DIRS})
+
+include(FindPackageHandleStandardArgs)
+# handle the QUIETLY and REQUIRED arguments and set ESOAP_MODEL_CXX_FOUND to TRUE
+# if all listed variables are TRUE
+find_package_handle_standard_args(${MY_PKG} DEFAULT_MSG
+ ESOAP_MODEL_CXX_LIBRARIES ESOAP_MODEL_CXX_INCLUDE_DIRS)
+
+mark_as_advanced(ESOAP_MODEL_CXX_INCLUDE_DIRS ESOAP_MODEL_CXX_LIBRARY ESOAP_MODEL_CXX_LIBRARIES ESOAP_MODEL_CXX_DEFINITIONS)
diff --git a/configure.ac b/configure.ac
index 3937baaa9e..f883701d1b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4608,6 +4608,50 @@ EFL_LIB_END([Eflat_Xml_Model_Cxx])
#### End of Eflat_Xml_Model CXX
+
+#### Esoap_Model
+EFL_LIB_START([Esoap_Model])
+
+### Additional options to configure
+
+### Default values
+
+### Checks for programs
+
+### Checks for libraries
+EFL_INTERNAL_DEPEND_PKG([ESOAP_MODEL], [eo])
+EFL_INTERNAL_DEPEND_PKG([ESOAP_MODEL], [efl])
+EFL_INTERNAL_DEPEND_PKG([ESOAP_MODEL], [ecore])
+EFL_INTERNAL_DEPEND_PKG([ESOAP_MODEL], [eflat_xml_model])
+
+EFL_DEPEND_PKG([ESOAP_MODEL], [CURL], [libcurl >= 7.40])
+
+EFL_EVAL_PKGS([ESOAP_MODEL])
+
+### Checks for header files
+
+### Checks for types
+
+### Checks for structures
+
+### Checks for compiler characteristics
+
+### Checks for linker characteristics
+
+### Checks for library functions
+
+EFL_LIB_END([Esoap_Model])
+#### End of Esoap_Model
+
+#### Esoap_Model CXX
+EFL_LIB_START([Esoap_Model_Cxx])
+
+EFL_EVAL_PKGS([ESOAP_MODEL_CXX])
+
+EFL_LIB_END([Esoap_Model_Cxx])
+#### End of Esoap_Model CXX
+
+
### Add Wayland server library if test is enabled
if test "x${want_tests}" = "xyes" -a "x${want_wayland}" = "xyes"; then
EFL_DEPEND_PKG([ECORE_WAYLAND_SRV], [WAYLAND], [wayland-server >= 1.8.0])
@@ -4798,6 +4842,8 @@ pc/elocation.pc
pc/elua.pc
pc/eflat_xml_model.pc
pc/eflat_xml_model-cxx.pc
+pc/esoap_model.pc
+pc/esoap_model-cxx.pc
dbus-services/org.enlightenment.Ethumb.service
systemd-services/ethumb.service
$po_makefile_in
@@ -4851,6 +4897,10 @@ cmakeconfig/EflatXmlModelConfig.cmake
cmakeconfig/EflatXmlModelConfigVersion.cmake:cmakeconfig/EFLConfigVersion.cmake.in
cmakeconfig/EflatXmlModelCxxConfig.cmake
cmakeconfig/EflatXmlModelCxxConfigVersion.cmake:cmakeconfig/EFLConfigVersion.cmake.in
+cmakeconfig/EsoapModelConfig.cmake
+cmakeconfig/EsoapModelConfigVersion.cmake:cmakeconfig/EFLConfigVersion.cmake.in
+cmakeconfig/EsoapModelCxxConfig.cmake
+cmakeconfig/EsoapModelCxxConfigVersion.cmake:cmakeconfig/EFLConfigVersion.cmake.in
])
AC_OUTPUT
@@ -4965,6 +5015,7 @@ echo "Ethumb..........: yes"
echo "Ethumb_Client...: yes"
echo "Elua............: $have_elua"
echo "Eflat_Xml_Model.: yes"
+echo "Esoap_Model.....: yes"
if test "${build_tests}" = "none"; then
echo "Tests...........: no"
elif test "${build_tests}" = "auto"; then
diff --git a/pc/esoap_model-cxx.pc.in b/pc/esoap_model-cxx.pc.in
new file mode 100644
index 0000000000..17446ab0a9
--- /dev/null
+++ b/pc/esoap_model-cxx.pc.in
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: Esoap-model C++
+Description: SOAP model for EFL
+Requires.private: @requirements_pc_esoap_model@ @requirements_pc_eo@
+Version: @VERSION@
+Libs: -L${libdir} -lesoap_model @requirements_public_libs_esoap_model@ @requirements_public_libs_eo@
+Libs.private: @requirements_libs_esoap_model@ @requirements_libs_eo@
+Cflags: -I${includedir}/efl-@VMAJ@ -I${includedir}/eo-@VMAJ@ -I${includedir}/esoap_model-@VMAJ@ -I${includedir}/esoap_model-cxx-@VMAJ@
diff --git a/pc/esoap_model.pc.in b/pc/esoap_model.pc.in
new file mode 100644
index 0000000000..22813e9089
--- /dev/null
+++ b/pc/esoap_model.pc.in
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: Esoap-model
+Description: SOAP model for EFL
+Requires.private: @requirements_pc_esoap_model@
+Version: @VERSION@
+Libs: -L${libdir} -lesoap_model @requirements_public_libs_esoap_model@
+Libs.private: @requirements_libs_esoap_model@
+Cflags: -I${includedir}/efl-@VMAJ@ -I${includedir}/esoap_model-@VMAJ@
diff --git a/src/Makefile.am b/src/Makefile.am
index 964dc531f0..cb0faae980 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -61,6 +61,7 @@ include Makefile_Emotion.am
include Makefile_Ethumb.am
include Makefile_Ethumb_Client.am
include Makefile_EflatXmlModel.am
+include Makefile_EsoapModel.am
include Makefile_Eina_Cxx.am
include Makefile_Ecore_Cxx.am
@@ -73,6 +74,7 @@ include Makefile_Edje_Cxx.am
include Makefile_Evas_Cxx.am
include Makefile_Eio_Cxx.am
include Makefile_EflatXmlModel_Cxx.am
+include Makefile_EsoapModel_Cxx.am
include Makefile_Elua.am
include Makefile_Elocation.am
diff --git a/src/Makefile_EsoapModel.am b/src/Makefile_EsoapModel.am
new file mode 100644
index 0000000000..85af9292f4
--- /dev/null
+++ b/src/Makefile_EsoapModel.am
@@ -0,0 +1,84 @@
+### Library
+
+esoap_model_eolian_files = \
+lib/esoap_model/esoap_model.eo
+
+esoap_model_eolian_c = $(esoap_model_eolian_files:%.eo=%.eo.c)
+esoap_model_eolian_h = $(esoap_model_eolian_files:%.eo=%.eo.h)
+
+BUILT_SOURCES += \
+ $(esoap_model_eolian_c) \
+ $(esoap_model_eolian_h)
+
+CLEANFILES += \
+ $(esoap_model_eolian_c) \
+ $(esoap_model_eolian_h)
+
+esoap_modeleolianfilesdir = $(datadir)/eolian/include/esoap_model-@VMAJ@
+esoap_modeleolianfiles_DATA = \
+ $(esoap_model_eolian_files)
+
+EXTRA_DIST += \
+ ${esoap_modeleolianfiles_DATA}
+
+lib_LTLIBRARIES += lib/esoap_model/libesoap_model.la
+
+installed_esoap_modelmainheadersdir = $(includedir)/esoap_model-@VMAJ@
+dist_installed_esoap_modelmainheaders_DATA = \
+lib/esoap_model/Esoap_Model.h
+
+nodist_installed_esoap_modelmainheaders_DATA = \
+ $(esoap_model_eolian_h)
+
+lib_esoap_model_libesoap_model_la_SOURCES = \
+lib/esoap_model/esoap_model_private.h \
+lib/esoap_model/esoap_model.c
+
+lib_esoap_model_libesoap_model_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl @ESOAP_MODEL_CFLAGS@ @EFL_CFLAGS@
+lib_esoap_model_libesoap_model_la_LIBADD = @ESOAP_MODEL_LIBS@ @EFL_LIBS@
+lib_esoap_model_libesoap_model_la_DEPENDENCIES = @ESOAP_MODEL_INTERNAL_LIBS@ @EFL_INTERNAL_LIBS@
+lib_esoap_model_libesoap_model_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@
+
+### Unit tests
+
+if EFL_ENABLE_TESTS
+
+check_PROGRAMS += tests/esoap_model/esoap_model_suite
+TESTS += tests/esoap_model/esoap_model_suite
+
+tests_esoap_model_esoap_model_suite_SOURCES = \
+tests/esoap_model/esoap_model_suite.c \
+tests/esoap_model/esoap_model_suite.h \
+tests/esoap_model/esoap_model_test_esoap_model.c \
+tests/esoap_model/esoap_model_test_esoap_model.h
+
+tests_esoap_model_esoap_model_suite_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
+-DTESTS_SRC_DIR=\"$(abs_top_srcdir)/src/tests/esoap_model\" \
+-DTESTS_BUILD_DIR=\"$(abs_top_builddir)/src/tests/esoap_model\" \
+@CHECK_CFLAGS@ \
+@ESOAP_MODEL_CFLAGS@ @EFL_CFLAGS@
+
+tests_esoap_model_esoap_model_suite_LDADD = \
+@CHECK_LIBS@ \
+@USE_ESOAP_MODEL_LIBS@ \
+@USE_EFL_LIBS@
+
+tests_esoap_model_esoap_model_suite_DEPENDENCIES = \
+@USE_ESOAP_MODEL_INTERNAL_LIBS@
+
+endif
+
+EXTRA_DIST += $(ESOAP_MODEL_DATA_FILES)
+
+if HAVE_ELUA
+
+esoap_model_eolian_lua = $(esoap_model_eolian_files:%.eo=%.eo.lua)
+
+generated_esoap_model_lua_all = $(esoap_model_eolian_lua)
+
+CLEANFILES += $(generated_esoap_model_lua_all)
+
+installed_esoap_modelluadir = $(datadir)/elua/modules/esoap_model
+nodist_installed_esoap_modellua_DATA = $(generated_esoap_model_lua_all)
+
+endif
diff --git a/src/Makefile_EsoapModel_Cxx.am b/src/Makefile_EsoapModel_Cxx.am
new file mode 100644
index 0000000000..16c6749ced
--- /dev/null
+++ b/src/Makefile_EsoapModel_Cxx.am
@@ -0,0 +1,22 @@
+if HAVE_CXX11
+
+### Generated headers
+
+generated_esoap_model_cxx_bindings = $(esoap_model_eolian_files:%.eo=%.eo.hh)
+
+lib/esoap_model/Esoap_Model.hh: $(generated_esoap_model_cxx_bindings)
+ @echo @ECHO_E@ "#ifndef EFL_CXX_ESOAP_MODEL_HH\n#define EFL_CXX_ESOAP_MODEL_HH\n" > $(top_builddir)/src/lib/esoap_model/Esoap_Model.hh
+ @echo @ECHO_E@ "#ifdef EFL_BETA_API_SUPPORT" >> $(top_builddir)/src/lib/esoap_model/Esoap_Model.hh
+ @for i in $(generated_esoap_model_cxx_bindings); do echo "#include <$$(basename $$i)>" >> $(top_builddir)/src/lib/esoap_model/Esoap_Model.hh; done
+ @echo @ECHO_E@ "#endif\n\n#endif\n" >> $(top_builddir)/src/lib/esoap_model/Esoap_Model.hh
+
+generated_esoap_model_cxx_all = \
+ $(generated_esoap_model_cxx_bindings) \
+ lib/esoap_model/Esoap_Model.hh
+
+CLEANFILES += $(generated_esoap_model_cxx_all)
+
+installed_esoap_modelcxxmainheadersdir = $(includedir)/esoap_model-cxx-@VMAJ@/
+nodist_installed_esoap_modelcxxmainheaders_DATA = $(generated_esoap_model_cxx_all)
+
+endif
diff --git a/src/lib/esoap_model/Esoap_Model.h b/src/lib/esoap_model/Esoap_Model.h
new file mode 100644
index 0000000000..22be6a811b
--- /dev/null
+++ b/src/lib/esoap_model/Esoap_Model.h
@@ -0,0 +1,63 @@
+#ifndef ESOAP_MODEL_H
+#define ESOAP_MODEL_H
+
+#include <Ecore.h>
+#include <Efl.h>
+#include <Efl_Config.h>
+
+#ifdef EAPI
+# undef EAPI
+#endif
+
+#ifdef _WIN32
+# ifdef EFL_ESOAP_MODEL_BUILD
+# ifdef DLL_EXPORT
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI
+# endif /* ! DLL_EXPORT */
+# else
+# define EAPI __declspec(dllimport)
+# endif /* ! EFL_ESOAP_MODEL_BUILD */
+#else
+# ifdef __GNUC__
+# if __GNUC__ >= 4
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+# else
+# define EAPI
+# endif
+#endif /* ! _WIN32 */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Initialize esoap_model.
+ *
+ * @return 1 or greater on success, 0 otherwise
+ */
+EAPI int esoap_model_init(void);
+
+/**
+ * @brief Shutdown esoap_model.
+ *
+ * @return 0 if esoap_model shuts down, greater than 0 otherwise.
+ */
+EAPI int esoap_model_shutdown(void);
+
+#ifdef EFL_EO_API_SUPPORT
+# include <esoap_model.eo.h>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#undef EAPI
+#define EAPI
+
+#endif
diff --git a/src/lib/esoap_model/esoap_model.c b/src/lib/esoap_model/esoap_model.c
new file mode 100644
index 0000000000..a5b1e49b17
--- /dev/null
+++ b/src/lib/esoap_model/esoap_model.c
@@ -0,0 +1,470 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "esoap_model_private.h"
+
+#include <curl/curl.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#define MY_CLASS ESOAP_MODEL_CLASS
+#define MY_CLASS_NAME "Esoap_Model"
+
+typedef struct
+{
+ Esoap_Model_Data *pd;
+ Eina_Strbuf *response;
+ struct curl_slist *header;
+ char *soap_action;
+ CURL *curl;
+ Ecore_Thread *thread;
+} Esoap_Model_Perform_Data;
+
+static void _properties_load(Esoap_Model_Data *);
+static void _children_load(Esoap_Model_Data *);
+static bool _init(Esoap_Model_Data *);
+static void _clear(Esoap_Model_Data *);
+static void _perform(Esoap_Model_Data *, const char *);
+static void _perform_cb(Esoap_Model_Perform_Data *, Ecore_Thread *);
+static void _perform_end_cb(Esoap_Model_Perform_Data *, Ecore_Thread *);
+static void _perform_cancel_cb(Esoap_Model_Perform_Data *, Ecore_Thread *);
+static Eina_Bool _properties_changed_cb(void *, Eo *, const Eo_Event_Description *, void *);
+static size_t _write_data_cb(void *, size_t, size_t, void *);
+static void _perform_data_free(Esoap_Model_Perform_Data *data);
+
+static int _esoap_model_init_count = 0;
+int _esoap_model_log_dom = -1;
+
+EAPI int
+esoap_model_init(void)
+{
+ if (_esoap_model_init_count++ > 0)
+ return _esoap_model_init_count;
+
+ if (!eina_init())
+ {
+ fputs("Esoap_Model: Unable to initialize eina\n", stderr);
+ return 0;
+ }
+
+ _esoap_model_log_dom = eina_log_domain_register("Esoap_Model", EINA_COLOR_CYAN);
+ if (_esoap_model_log_dom < 0)
+ {
+ EINA_LOG_ERR("Unable to create an 'Esoap_Model' log domain");
+ _esoap_model_log_dom = -1;
+ eina_shutdown();
+ return 0;
+ }
+
+ if (!ecore_init())
+ {
+ ERR("Unable to initialize ecore");
+ goto on_error;
+ }
+
+ if (!eflat_xml_model_init())
+ {
+ ERR("Unable to initialize eflat_xml_model");
+ goto on_error;
+ }
+
+ CURLcode code = curl_global_init(CURL_GLOBAL_ALL);
+ if (CURLE_OK != code)
+ {
+ ERR("Unable to initialize curl");
+ goto on_error;
+ }
+
+ return _esoap_model_init_count;
+
+on_error:
+ eina_log_domain_unregister(_esoap_model_log_dom);
+ _esoap_model_log_dom = -1;
+ eina_shutdown();
+ return 0;
+}
+
+EAPI int
+esoap_model_shutdown(void)
+{
+ if (_esoap_model_init_count <= 0)
+ {
+ ERR("Init count not greater than 0 in shutdown.");
+ _esoap_model_init_count = 0;
+ return 0;
+ }
+
+ if (--_esoap_model_init_count)
+ return _esoap_model_init_count;
+
+ curl_global_cleanup();
+ eflat_xml_model_shutdown();
+ ecore_shutdown();
+ eina_log_domain_unregister(_esoap_model_log_dom);
+ _esoap_model_log_dom = -1;
+ eina_shutdown();
+ return 0;
+}
+
+static Eo_Base *
+_esoap_model_eo_base_constructor(Eo *obj, Esoap_Model_Data *pd)
+{
+ DBG("(%p)", obj);
+
+ pd->obj = obj;
+ pd->load.status = EFL_MODEL_LOAD_STATUS_UNLOADED;
+ pd->children_list = NULL;
+ pd->xml = NULL;
+
+ return eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
+}
+
+static void
+_esoap_model_constructor(Eo *obj EINA_UNUSED,
+ Esoap_Model_Data *pd EINA_UNUSED,
+ const char *url,
+ const char *action)
+{
+ DBG("(%p)", obj);
+ EINA_SAFETY_ON_NULL_RETURN(url);
+ EINA_SAFETY_ON_NULL_RETURN(action);
+
+ pd->url = strdup(url);
+ pd->action = strdup(action);
+}
+
+static void
+_esoap_model_eo_base_destructor(Eo *obj, Esoap_Model_Data *pd)
+{
+ DBG("(%p)", obj);
+
+ _clear(pd);
+ free(pd->url);
+ free(pd->action);
+
+ eo_do_super(obj, MY_CLASS, eo_destructor());
+}
+
+static Efl_Model_Load_Status
+_esoap_model_efl_model_base_properties_get(Eo *obj EINA_UNUSED,
+ Esoap_Model_Data *pd,
+ Eina_Array * const* properties_array)
+{
+ DBG("(%p)", obj);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(pd, EFL_MODEL_LOAD_STATUS_ERROR);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(pd->obj, EFL_MODEL_LOAD_STATUS_ERROR);
+
+ eo_do(pd->xml, efl_model_properties_get(properties_array));
+ return pd->load.status;
+}
+
+static void
+_esoap_model_efl_model_base_properties_load(Eo *obj, Esoap_Model_Data *pd)
+{
+ DBG("(%p)", obj);
+
+ if (pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES)
+ return;
+
+ if (!_init(pd))
+ return;
+
+ _properties_load(pd);
+}
+
+static void
+_properties_load(Esoap_Model_Data *pd)
+{
+ DBG("(%p)", pd->obj);
+ efl_model_load_set(pd->obj,
+ &pd->load,
+ EFL_MODEL_LOAD_STATUS_LOADING_PROPERTIES);
+ eo_do(pd->xml, efl_model_properties_load());
+ efl_model_load_set(pd->obj,
+ &pd->load,
+ EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES);
+}
+
+static Efl_Model_Load_Status
+_esoap_model_efl_model_base_property_set(Eo *obj EINA_UNUSED,
+ Esoap_Model_Data *pd,
+ const char *property,
+ const Eina_Value *value)
+{
+ Efl_Model_Load_Status status;
+ eo_do(pd->xml, status = efl_model_property_set(property, value));
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(status != EFL_MODEL_LOAD_STATUS_ERROR, EFL_MODEL_LOAD_STATUS_ERROR);
+ return pd->load.status;
+}
+
+static Efl_Model_Load_Status
+_esoap_model_efl_model_base_property_get(Eo *obj EINA_UNUSED,
+ Esoap_Model_Data *pd,
+ const char *property,
+ const Eina_Value **value)
+{
+ Efl_Model_Load_Status status;
+ eo_do(pd->xml, status = efl_model_property_get(property, value));
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(status != EFL_MODEL_LOAD_STATUS_ERROR, EFL_MODEL_LOAD_STATUS_ERROR);
+ return pd->load.status;
+}
+
+static void
+_esoap_model_efl_model_base_load(Eo *obj EINA_UNUSED, Esoap_Model_Data *pd)
+{
+ DBG("(%p)", obj);
+
+ if ((pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED) == EFL_MODEL_LOAD_STATUS_LOADED)
+ return;
+
+ if (!_init(pd))
+ return;
+
+ if (!(pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES))
+ _properties_load(pd);
+
+ if (!(pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN))
+ _children_load(pd);
+}
+
+static Efl_Model_Load_Status
+_esoap_model_efl_model_base_load_status_get(Eo *obj EINA_UNUSED,
+ Esoap_Model_Data *pd)
+{
+ DBG("(%p)", obj);
+ return pd->load.status;
+}
+
+static void
+_esoap_model_efl_model_base_unload(Eo *obj EINA_UNUSED, Esoap_Model_Data *pd)
+{
+ DBG("(%p)", obj);
+
+ _clear(pd);
+
+ efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_UNLOADED);
+}
+
+Eo *
+_esoap_model_efl_model_base_child_add(Eo *obj, Esoap_Model_Data *pd EINA_UNUSED)
+{
+ DBG("(%p)", obj);
+ return NULL;
+}
+
+static Efl_Model_Load_Status
+_esoap_model_efl_model_base_child_del(Eo *obj,
+ Esoap_Model_Data *pd EINA_UNUSED,
+ Eo *child EINA_UNUSED)
+{
+ DBG("(%p)", obj);
+ return EFL_MODEL_LOAD_STATUS_ERROR;
+}
+
+static Efl_Model_Load_Status
+_esoap_model_efl_model_base_children_slice_get(Eo *obj EINA_UNUSED,
+ Esoap_Model_Data *pd,
+ unsigned start EINA_UNUSED,
+ unsigned count EINA_UNUSED,
+ Eina_Accessor **children_accessor)
+{
+ DBG("(%p)", obj);
+
+ if (!(pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN))
+ {
+ WRN("(%p): Children not loaded", obj);
+ *children_accessor = NULL;
+ return pd->load.status;
+ }
+
+ *children_accessor = efl_model_list_slice(pd->children_list, start, count);
+ return pd->load.status;
+}
+
+static Efl_Model_Load_Status
+_esoap_model_efl_model_base_children_count_get(Eo *obj EINA_UNUSED,
+ Esoap_Model_Data *pd,
+ unsigned *children_count)
+{
+ DBG("(%p)", obj);
+ *children_count = eina_list_count(pd->children_list);
+ return pd->load.status;
+}
+
+static void
+_esoap_model_efl_model_base_children_load(Eo *obj EINA_UNUSED, Esoap_Model_Data *pd)
+{
+ DBG("(%p)", obj);
+
+ if (pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN)
+ return;
+
+ if (!_init(pd))
+ return;
+
+ _children_load(pd);
+}
+
+static void
+_children_load(Esoap_Model_Data *pd)
+{
+ DBG("(%p)", pd->obj);
+
+ efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_LOADING_CHILDREN);
+
+ const Eina_Value *xml_value;
+ Efl_Model_Load_Status status;
+ eo_do(pd->xml, status = efl_model_property_get("/", &xml_value));
+ EINA_SAFETY_ON_FALSE_RETURN(EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES & status);
+
+ const char *xml = NULL;
+ eina_value_get(xml_value, &xml);
+ _perform(pd, xml);
+}
+
+static Eina_Bool
+_properties_changed_cb(void *data,
+ Eo *child EINA_UNUSED,
+ const Eo_Event_Description *desc EINA_UNUSED,
+ void *event_info)
+{
+ eo_do(data, eo_event_callback_call(EFL_MODEL_BASE_EVENT_PROPERTIES_CHANGED, event_info));
+ return EO_CALLBACK_CONTINUE;
+}
+
+static bool
+_init(Esoap_Model_Data *pd)
+{
+ if (pd->xml)
+ return true;
+
+ pd->xml = eo_add(EFLAT_XML_MODEL_CLASS,
+ NULL,
+ eflat_xml_model_constructor(NULL));
+
+ eo_do(pd->xml, eo_event_callback_add(EFL_MODEL_BASE_EVENT_PROPERTIES_CHANGED,
+ _properties_changed_cb,
+ pd->obj));
+ return true;
+}
+
+static void
+_clear(Esoap_Model_Data *pd)
+{
+ EINA_SAFETY_ON_NULL_RETURN(pd);
+
+ if (pd->xml)
+ {
+ eo_unref(pd->xml);
+ pd->xml = NULL;
+ }
+
+ Eo *child;
+ EINA_LIST_FREE(pd->children_list, child)
+ eo_del(child);
+}
+
+static size_t
+_write_data_cb(void *ptr, size_t size, size_t nmeb, void *data)
+{
+ Eina_Strbuf *buf = (Eina_Strbuf *)data;
+ Eina_Bool ret = eina_strbuf_append_length(buf, ptr, size * nmeb);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(ret, 0);
+ return size * nmeb;
+}
+
+static void
+_perform(Esoap_Model_Data *pd, const char *xml)
+{
+ DBG("(%p)", pd->obj);
+ Esoap_Model_Perform_Data *data = calloc(1, sizeof(Esoap_Model_Perform_Data));
+ data->pd = pd;
+ data->response = eina_strbuf_new();
+
+ const char *SOAP_ACTION = "SOAPAction:";
+ const size_t soap_action_lenght = strlen(SOAP_ACTION) + strlen(pd->action) + 1;
+ data->soap_action = malloc(soap_action_lenght);
+ snprintf(data->soap_action, soap_action_lenght, "%s%s", SOAP_ACTION, pd->action);
+
+ data->header = curl_slist_append(data->header, "Content-Type:application/soap+xml");
+ data->header = curl_slist_append(data->header, data->soap_action);
+ data->header = curl_slist_append(data->header, "Transfer-Encoding: chunked");
+ data->header = curl_slist_append(data->header, "Expect:");
+
+ data->curl = curl_easy_init();
+ EINA_SAFETY_ON_NULL_RETURN(data->curl);
+
+ curl_easy_setopt(data->curl, CURLOPT_URL, pd->url);
+ curl_easy_setopt(data->curl, CURLOPT_POST, 1L);
+ curl_easy_setopt(data->curl, CURLOPT_WRITEFUNCTION, _write_data_cb);
+ curl_easy_setopt(data->curl, CURLOPT_WRITEDATA, data->response);
+ curl_easy_setopt(data->curl, CURLOPT_HTTPHEADER, data->header);
+ curl_easy_setopt(data->curl, CURLOPT_COPYPOSTFIELDS, xml);
+ curl_easy_setopt(data->curl, CURLOPT_VERBOSE, 1L);
+
+ data->thread = ecore_thread_run((Ecore_Thread_Cb)_perform_cb,
+ (Ecore_Thread_Cb)_perform_end_cb,
+ (Ecore_Thread_Cb)_perform_cancel_cb, data);
+ EINA_SAFETY_ON_NULL_RETURN(data->thread);
+}
+
+static void
+_perform_cb(Esoap_Model_Perform_Data *data, Ecore_Thread *thread)
+{
+ DBG("(%p)", data->pd->obj);
+ CURLcode res = curl_easy_perform(data->curl);
+ if (CURLE_OK != res)
+ {
+ ERR("Could not perform: %d", res);
+ ecore_thread_cancel(thread);
+ }
+}
+
+static void
+_perform_end_cb(Esoap_Model_Perform_Data *data,
+ Ecore_Thread *thread EINA_UNUSED)
+{
+ DBG("(%p)", data->pd->obj);
+ const char *response = eina_strbuf_string_get(data->response);
+
+ DBG("(%p) response: %s", data->pd->obj, response);
+
+ Eo *child = eo_add(EFLAT_XML_MODEL_CLASS,
+ NULL,
+ eflat_xml_model_constructor(response));
+ data->pd->children_list = eina_list_append(data->pd->children_list, child);
+
+ unsigned int count = eina_list_count(data->pd->children_list);
+ Efl_Model_Children_Event evt = {.child = child, .index = count};
+ eo_do(data->pd->obj, eo_event_callback_call(EFL_MODEL_BASE_EVENT_CHILD_ADDED, &evt),
+ eo_event_callback_call(EFL_MODEL_BASE_EVENT_CHILDREN_COUNT_CHANGED, &count));
+
+ efl_model_load_set(data->pd->obj, &data->pd->load, EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN);
+
+ _perform_data_free(data);
+}
+
+static void
+_perform_cancel_cb(Esoap_Model_Perform_Data *data,
+ Ecore_Thread *thread EINA_UNUSED)
+{
+ DBG("(%p)", data->pd->obj);
+ efl_model_error_notify(data->pd->obj);
+ _perform_data_free(data);
+}
+
+static void
+_perform_data_free(Esoap_Model_Perform_Data *data)
+{
+ DBG("(%p)", data->pd->obj);
+ curl_easy_cleanup(data->curl);
+ eina_strbuf_free(data->response);
+ curl_slist_free_all(data->header);
+ free(data->soap_action);
+ free(data);
+}
+
+#include "Esoap_Model.eo.c"
diff --git a/src/lib/esoap_model/esoap_model.eo b/src/lib/esoap_model/esoap_model.eo
new file mode 100644
index 0000000000..971e8fc4ce
--- /dev/null
+++ b/src/lib/esoap_model/esoap_model.eo
@@ -0,0 +1,36 @@
+class Esoap.Model (Eo.Base, Efl.Model.Base) {
+ legacy_prefix: null;
+ methods {
+ constructor {
+ [[
+ Custom Soap_Model constructor.
+ @.constructor
+
+ @since 1.13
+ ]]
+ params {
+ url: const(char)*; [[The webservice URL]]
+ action: const(char)*; [[The soap action]]
+ }
+ }
+ }
+ implements {
+ Eo.Base.constructor;
+ Eo.Base.destructor;
+ Efl.Model.Base.properties.get;
+ Efl.Model.Base.properties_load;
+ Efl.Model.Base.property.set;
+ Efl.Model.Base.property.get;
+ Efl.Model.Base.load;
+ Efl.Model.Base.load_status.get;
+ Efl.Model.Base.unload;
+ Efl.Model.Base.child_add;
+ Efl.Model.Base.child_del;
+ Efl.Model.Base.children_slice.get;
+ Efl.Model.Base.children_count.get;
+ Efl.Model.Base.children_load;
+ }
+ constructors {
+ .constructor;
+ }
+}
diff --git a/src/lib/esoap_model/esoap_model_private.h b/src/lib/esoap_model/esoap_model_private.h
new file mode 100644
index 0000000000..98c6c65ebb
--- /dev/null
+++ b/src/lib/esoap_model/esoap_model_private.h
@@ -0,0 +1,35 @@
+#ifndef _ESOAP_MODEL_PRIVATE_H
+#define _ESOAP_MODEL_PRIVATE_H
+
+#include "Esoap_Model.h"
+
+#include <Eflat_Xml_Model.h>
+
+#include <stdbool.h>
+
+/* logging support */
+extern int _esoap_model_log_dom;
+
+#define CRI(...) EINA_LOG_DOM_CRIT(_esoap_model_log_dom, __VA_ARGS__)
+#define ERR(...) EINA_LOG_DOM_ERR(_esoap_model_log_dom, __VA_ARGS__)
+#define WRN(...) EINA_LOG_DOM_WARN(_esoap_model_log_dom, __VA_ARGS__)
+#define INF(...) EINA_LOG_DOM_INFO(_esoap_model_log_dom, __VA_ARGS__)
+#define DBG(...) EINA_LOG_DOM_DBG(_esoap_model_log_dom, __VA_ARGS__)
+
+typedef struct _Esoap_Model_Data Esoap_Model_Data;
+
+/**
+ * esoap_model
+ */
+struct _Esoap_Model_Data
+{
+ Eo *obj;
+ Efl_Model_Load load;
+ Eina_List *children_list;
+ Eflat_Xml_Model *xml;
+ char *url;
+ char *action;
+};
+
+#endif
+
diff --git a/src/tests/esoap_model/esoap_model_suite.c b/src/tests/esoap_model/esoap_model_suite.c
new file mode 100644
index 0000000000..5810b6a781
--- /dev/null
+++ b/src/tests/esoap_model/esoap_model_suite.c
@@ -0,0 +1,119 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "esoap_model_suite.h"
+
+#include <Eina.h>
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int _test_esoap_model_log_dom = -1;
+
+typedef struct
+{
+ const char *test_case;
+ void (*build)(TCase *tc);
+} Esoap_Model_Test_Case;
+
+static const Esoap_Model_Test_Case etc[] = {
+ { "Esoap_Model", esoap_model_test_esoap_model },
+ { NULL, NULL }
+};
+
+static void
+_list_tests(void)
+{
+ const Esoap_Model_Test_Case *it = etc;
+ fputs("Available Test Cases:\n", stderr);
+ for (; it->test_case; it++)
+ fprintf(stderr, "\t%s\n", it->test_case);
+}
+
+static bool
+_use_test(int argc, const char **argv, const char *test_case)
+{
+ if (argc < 1)
+ return true;
+
+ for (; argc > 0; argc--, argv++)
+ if (strcmp(test_case, *argv) == 0)
+ return true;
+ return false;
+}
+
+static Suite *
+_esoap_suite_build(int argc, const char **argv)
+{
+ Suite *s = suite_create("Esoap");
+
+ for (int i = 0; etc[i].test_case; ++i)
+ {
+ if (!_use_test(argc, argv, etc[i].test_case)) continue;
+ TCase *tc = tcase_create(etc[i].test_case);
+
+ etc[i].build(tc);
+
+ suite_add_tcase(s, tc);
+ //tcase_set_timeout(tc, 0);
+ }
+
+ return s;
+}
+
+static void
+_init_logging(void)
+{
+ _test_esoap_model_log_dom = eina_log_domain_register("test_esoap_model", EINA_COLOR_LIGHTBLUE);
+ if (_test_esoap_model_log_dom < 0)
+ ck_abort_msg("Could not register log domain: test_esoap_model");
+
+ //eina_log_domain_level_set("esskyuehl", EINA_LOG_LEVEL_DBG);
+ //eina_log_domain_level_set("esoap_model", EINA_LOG_LEVEL_DBG);
+ eina_log_domain_level_set("test_esoap_model", EINA_LOG_LEVEL_DBG);
+}
+
+static void
+_shutdown_logging(void)
+{
+ eina_log_domain_unregister(_test_esoap_model_log_dom);
+ _test_esoap_model_log_dom = -1;
+}
+
+int
+main(int argc, char **argv)
+{
+ for (int 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;
+ }
+ }
+
+ _init_logging();
+
+ Suite *s = _esoap_suite_build(argc - 1, (const char **)argv + 1);
+ SRunner *sr = srunner_create(s);
+
+ srunner_set_xml(sr, TESTS_BUILD_DIR "/check-results.xml");
+
+ srunner_run_all(sr, CK_ENV);
+ int failed_count = srunner_ntests_failed(sr);
+ srunner_free(sr);
+
+ _shutdown_logging();
+
+ return (failed_count == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/src/tests/esoap_model/esoap_model_suite.h b/src/tests/esoap_model/esoap_model_suite.h
new file mode 100644
index 0000000000..e1bcaa2902
--- /dev/null
+++ b/src/tests/esoap_model/esoap_model_suite.h
@@ -0,0 +1,16 @@
+#ifndef _ESOAP_MODEL_SUITE_H
+#define _ESOAP_MODEL_SUITE_H
+
+#include <check.h>
+
+extern int _test_esoap_model_log_dom;
+
+#define CRI(...) EINA_LOG_DOM_CRIT(_test_esoap_model_log_dom, __VA_ARGS__)
+#define ERR(...) EINA_LOG_DOM_ERR(_test_esoap_model_log_dom, __VA_ARGS__)
+#define WRN(...) EINA_LOG_DOM_WARN(_test_esoap_model_log_dom, __VA_ARGS__)
+#define INF(...) EINA_LOG_DOM_INFO(_test_esoap_model_log_dom, __VA_ARGS__)
+#define DBG(...) EINA_LOG_DOM_DBG(_test_esoap_model_log_dom, __VA_ARGS__)
+
+void esoap_model_test_esoap_model(TCase *tc);
+
+#endif
diff --git a/src/tests/esoap_model/esoap_model_test_esoap_model.c b/src/tests/esoap_model/esoap_model_test_esoap_model.c
new file mode 100644
index 0000000000..2a7ed543ca
--- /dev/null
+++ b/src/tests/esoap_model/esoap_model_test_esoap_model.c
@@ -0,0 +1,238 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "esoap_model_test_esoap_model.h"
+#include "esoap_model_suite.h"
+
+#include <Ecore.h>
+#include <Eina.h>
+#include <Esoap_Model.h>
+
+#include <stdbool.h>
+
+static void
+_setup(void)
+{
+ int ret = esoap_model_init();
+ ck_assert_int_ge(ret, 1);
+}
+
+static void
+_teardown(void)
+{
+ int ret = esoap_model_shutdown();
+ ck_assert_int_eq(ret, 0);
+}
+
+static Eina_Bool
+_eo_event_load_status_cb(void *data,
+ Eo *obj EINA_UNUSED,
+ const Eo_Event_Description *desc EINA_UNUSED,
+ void *event_info EINA_UNUSED)
+{
+ Efl_Model_Load_Status expected_status = *((Efl_Model_Load_Status*)data);
+ Efl_Model_Load load = *((Efl_Model_Load*)event_info);
+ if ((load.status & expected_status) != expected_status)
+ return EINA_TRUE;
+
+ ecore_main_loop_quit();
+ return EINA_FALSE;
+}
+
+static void
+_wait_until_load_status(Efl_Model_Base *model, Efl_Model_Load_Status expected_status)
+{
+ Efl_Model_Load_Status actual_status;
+ eo_do(model, actual_status = efl_model_load_status_get());
+ if ((expected_status & actual_status) == expected_status) return;
+
+ eo_do(model, eo_event_callback_add(EFL_MODEL_BASE_EVENT_LOAD_STATUS, _eo_event_load_status_cb, &expected_status));
+ ecore_main_loop_begin();
+ eo_do(model, eo_event_callback_del(EFL_MODEL_BASE_EVENT_LOAD_STATUS, _eo_event_load_status_cb, &expected_status));
+}
+
+static void
+_check_value_type_cannot_have_children(Efl_Model_Base *model)
+{
+ Efl_Model_Base *child = eo_do_ret(model, child, efl_model_child_add());
+ ck_assert_ptr_eq(NULL, child);
+}
+
+static void
+_check_model_children_count_eq(Efl_Model_Base *model, unsigned int expected_children_count)
+{
+ unsigned int actual_children_count = 0;
+ eo_do(model, efl_model_children_count_get(&actual_children_count));
+ ck_assert_int_eq(expected_children_count, actual_children_count);
+}
+
+static void
+_check_model_property_int_eq(Efl_Model_Base *model, const char *property, int64_t expected_value)
+{
+ const Eina_Value *value;
+ Efl_Model_Load_Status status;
+ eo_do(model, status = efl_model_property_get(property, &value));
+ ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
+ ck_assert_ptr_ne(NULL, value);
+
+ const Eina_Value_Type *property_type = eina_value_type_get(value);
+ ck_assert_ptr_eq(EINA_VALUE_TYPE_INT64, property_type);
+
+ int64_t actual_value = 0;
+ eina_value_get(value, &actual_value);
+ ck_assert_int_eq(expected_value, actual_value);
+}
+
+static void
+_check_model_property_str_eq(Efl_Model_Base *model, const char *property, const char *expected_value)
+{
+ const Eina_Value *value;
+ Efl_Model_Load_Status status;
+ eo_do(model, status = efl_model_property_get(property, &value));
+ ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
+ ck_assert_ptr_ne(NULL, value);
+
+ const Eina_Value_Type *property_type = eina_value_type_get(value);
+ fail_if(EINA_VALUE_TYPE_STRING != property_type && EINA_VALUE_TYPE_STRINGSHARE != property_type);
+
+ const char *actual_value = NULL;
+ eina_value_get(value, &actual_value);
+ ck_assert_str_eq(expected_value, actual_value);
+}
+
+static Efl_Model_Base *
+_efl_model_nth_child_get(Efl_Model_Base *model, unsigned int n)
+{
+ Eina_Accessor *accessor;
+ Efl_Model_Load_Status status;
+ eo_do(model, status = efl_model_children_slice_get(n, 1, &accessor));
+ ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
+ ck_assert_ptr_ne(NULL, accessor);
+ Efl_Model_Base *child = NULL;
+ Eina_Bool ret = eina_accessor_data_get(accessor, 0, (void**)&child);
+ eina_accessor_free(accessor);
+ ck_assert(ret);
+ ck_assert_ptr_ne(NULL, child);
+ return child;
+}
+
+static void
+_check_model_load(Efl_Model_Base *model)
+{
+ eo_do(model, efl_model_load());
+ _wait_until_load_status(model, EFL_MODEL_LOAD_STATUS_LOADED);
+}
+
+static void
+_check_model_properties(Efl_Model_Base *model, const char *expected_properties[])
+{
+ Eina_Array *properties = NULL;
+ Efl_Model_Load_Status status;
+ eo_do(model, status = efl_model_properties_get(&properties));
+ ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
+ ck_assert_ptr_ne(NULL, properties);
+
+ unsigned int actual_properties_count = eina_array_count(properties);
+
+ unsigned int expected_properties_count = 0;
+ const char *expected_property = NULL;
+ while ((expected_property = *expected_properties++))
+ {
+ const char *actual_property = eina_array_data_get(properties,
+ expected_properties_count);
+ ck_assert_str_eq(expected_property, actual_property);
+ ++expected_properties_count;
+ ck_assert_int_le(expected_properties_count, actual_properties_count);
+ }
+
+ ck_assert_int_eq(expected_properties_count, actual_properties_count);
+}
+
+static void
+_check_properties_count_eq(Efl_Model_Base *model, unsigned int expected_properties_count)
+{
+ Eina_Array *properties = NULL;
+ Efl_Model_Load_Status status;
+ eo_do(model, status = efl_model_properties_get(&properties));
+ ck_assert_int_ne(EFL_MODEL_LOAD_STATUS_ERROR, status);
+ if (!expected_properties_count && !properties)
+ return;
+
+ ck_assert_ptr_ne(NULL, properties);
+
+ unsigned int actual_properties_count = eina_array_count(properties);
+ ck_assert_int_eq(expected_properties_count, actual_properties_count);
+}
+
+static Esoap_Model *
+_create_esoap_model()
+{
+ Efl_Model_Base *esoap = eo_add(ESOAP_MODEL_CLASS, NULL,
+ esoap_model_constructor("http://127.0.0.1:9090/axis2/services/echo",
+ "http://ws.apache.org/axis2/c/samples/echoString"));
+ ck_assert_ptr_ne(NULL, esoap);
+ return esoap;
+}
+
+START_TEST(smoke)
+{
+ Efl_Model_Base *esoap = _create_esoap_model();
+ eo_unref(esoap);
+}
+END_TEST
+
+static void
+_check_string_property_set(Efl_Model_Base *model, const char *property, const char *v)
+{
+ Eina_Value value;
+ eina_value_setup(&value, EINA_VALUE_TYPE_STRING);
+ eina_value_set(&value, v);
+ Efl_Model_Load_Status status;
+ eo_do(model, status = efl_model_property_set(property, &value));
+ eina_value_flush(&value);
+ ck_assert(EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES & status);
+}
+
+START_TEST(load_children)
+{
+ Efl_Model_Base *esoap = _create_esoap_model();
+
+ eo_do(esoap, efl_model_properties_load());
+ _wait_until_load_status(esoap, EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES);
+
+ _check_string_property_set(esoap, "esoap:Envelope@xmlns:esoap", "http://www.w3.org/2003/05/esoap-envelope");
+ _check_string_property_set(esoap, "esoap:Envelope@esoap:encodingStyle", "http://www.w3.org/2001/12/esoap-encoding");
+ _check_string_property_set(esoap, "esoap:Envelope/esoap:Body/ns1:echoString@xmlns:ns1", "http://ws.apache.org/axis2/services/echo");
+ _check_string_property_set(esoap, "esoap:Envelope/esoap:Body/ns1:echoString/ns1:text", "Hello World!");
+
+ // make the call loading the children
+ eo_do(esoap, efl_model_children_load());
+ _wait_until_load_status(esoap, EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN);
+
+ _check_model_children_count_eq(esoap, 1);
+
+ Efl_Model_Base *child = _efl_model_nth_child_get(esoap, 1);
+ _check_model_load(child);
+
+ _check_model_properties(child, (const char*[]){
+ "esoapenv:Envelope@xmlns:esoapenv",
+ "esoapenv:Envelope/esoapenv:Body/ns1:echoString@xmlns:ns1",
+ "esoapenv:Envelope/esoapenv:Body/ns1:echoString/text",
+ NULL});
+
+ _check_model_property_str_eq(child, "esoapenv:Envelope@xmlns:esoapenv", "http://www.w3.org/2003/05/esoap-envelope");
+ _check_model_property_str_eq(child, "esoapenv:Envelope/esoapenv:Body/ns1:echoString@xmlns:ns1", "http://ws.apache.org/axis2/c/samples");
+ _check_model_property_str_eq(child, "esoapenv:Envelope/esoapenv:Body/ns1:echoString/text", "Hello World!");
+
+ eo_unref(esoap);
+}
+END_TEST
+
+void
+esoap_model_test_esoap_model(TCase *tc)
+{
+ tcase_add_checked_fixture(tc, _setup, _teardown);
+ tcase_add_test(tc, smoke);
+ tcase_add_test(tc, load_children);
+}
diff --git a/src/tests/esoap_model/esoap_model_test_esoap_model.h b/src/tests/esoap_model/esoap_model_test_esoap_model.h
new file mode 100644
index 0000000000..e1d1396c06
--- /dev/null
+++ b/src/tests/esoap_model/esoap_model_test_esoap_model.h
@@ -0,0 +1,6 @@
+#ifndef _ESOAP_MODEL_TEST_ESOAP_MODEL_H
+#define _ESOAP_MODEL_TEST_ESOAP_MODEL_H
+
+#include <Esoap_Model.h>
+
+#endif