Unit test framework
authorPatryk Kaczmarek <patryk.k@samsung.com>
Tue, 2 Dec 2014 11:18:41 +0000 (12:18 +0100)
committerMike Gorse <mgorse@suse.com>
Tue, 9 Dec 2014 14:56:38 +0000 (08:56 -0600)
   * New test framework for testing Atspi library
   * https://bugzilla.gnome.org/show_bug.cgi?id=730505

17 files changed:
Makefile.am
README
configure.ac
tests/.gitignore [new file with mode: 0644]
tests/Makefile.am [new file with mode: 0644]
tests/README [new file with mode: 0644]
tests/atk-object-xml-loader.c [new file with mode: 0644]
tests/atk-object-xml-loader.h [new file with mode: 0644]
tests/atk_suite.c [new file with mode: 0644]
tests/atk_suite.h [new file with mode: 0644]
tests/atk_test_accessible.c [new file with mode: 0644]
tests/data/test.xml [new file with mode: 0644]
tests/dummyatk/Makefile.am [new file with mode: 0644]
tests/dummyatk/my-atk-object.c [new file with mode: 0644]
tests/dummyatk/my-atk-object.h [new file with mode: 0644]
tests/dummyatk/my-atk.h [new file with mode: 0644]
tests/test-application.c [new file with mode: 0644]

index 713fec5..889e76c 100644 (file)
@@ -1,5 +1,11 @@
 SUBDIRS=droute atk-adaptor
 
+if ATSPI_TESTS
+
+SUBDIRS += tests
+
+endif
+
 gtk_modulesdir = $(libdir)/gnome-settings-daemon-3.0/gtk-modules/
 gtk_modules_DATA = at-spi2-atk.desktop
 
diff --git a/README b/README
index eb23e8a..7a3449c 100644 (file)
--- a/README
+++ b/README
@@ -60,6 +60,13 @@ as a module.
 These libraries depend on the at-spi2-core code that contains the daemon for
 registering applications, D-Bus helper libraries and the AT-SPI D-Bus specifications.
 
+Tests
+-----
+
+To run tests execute autogen.sh with '--with-tests=yes' parameter then
+after 'make', type 'make check'.
+Test result is available in tests/atk-test.log
+
 Directory structure
 -------------------
 
@@ -84,3 +91,8 @@ The directories within this package are arranged as follows:
         It is also responsible for servicing requests from
         the registry to register handlers for specific event
         types.
+
+    tests
+
+        Contains tests for atspi.
+        More details in tests/README
index 31e3d41..11d967d 100644 (file)
@@ -47,7 +47,7 @@ PKG_CHECK_MODULES(GOBJ, [gobject-2.0 >= 2.0.0])
 AC_SUBST(GOBJ_LIBS)
 AC_SUBST(GOBJ_CFLAGS)
 
-PKG_CHECK_MODULES(GMODULE, [gmodule-2.0 >= 2.0.0])     
+PKG_CHECK_MODULES(GMODULE, [gmodule-2.0 >= 2.0.0])
 AC_SUBST(GMODULE_LIBS)
 AC_SUBST(GMODULE_CFLAGS)
 
@@ -59,6 +59,34 @@ PKG_CHECK_MODULES(ATSPI, [atspi-2 >= 2.15.2])
 AC_SUBST(ATSPI_LIBS)
 AC_SUBST(ATSPI_CFLAGS)
 
+AC_ARG_WITH([tests],
+       [AC_HELP_STRING([--with-tests=yes|no],
+               [choose if test should be enabled.
+                @<:@default=no@:>@])],
+       [build_tests=${withval}],
+       [build_tests=no])
+
+want_tests="no"
+
+case "${build_tests}" in
+   yes)
+     want_tests="yes"
+     ;;
+   no*)
+     ;;
+   *)
+     AC_MSG_ERROR([Unknown build tests option: --with-tests=${build_tests}])
+     ;;
+esac
+
+
+if test "${want_tests}" = "yes"; then
+       PKG_CHECK_MODULES(XML, [libxml-2.0 >= 2.9.1])
+       AC_SUBST(XML_LIBS)
+       AC_SUBST(XML_CFLAGS)
+fi
+AM_CONDITIONAL([ATSPI_TESTS], [test "${want_tests}" = "yes"])
+
 GLIB_GSETTINGS
 
 AC_ARG_ENABLE(p2p, [  --enable-p2p  Allow peer-to-peer DBus connections [default=yes]], enable_p2p="$enableval", enable_p2p=yes)
@@ -93,11 +121,17 @@ fi
 AC_SUBST(P2P_CFLAGS)
 
 AC_CONFIG_FILES([Makefile
-                atk-bridge-2.0.pc
-                droute/Makefile
-                atk-adaptor/Makefile
-                atk-adaptor/adaptors/Makefile
-                atk-adaptor/gtk-2.0/Makefile
-               ])
+        atk-bridge-2.0.pc
+        droute/Makefile
+        atk-adaptor/Makefile
+        atk-adaptor/adaptors/Makefile
+        atk-adaptor/gtk-2.0/Makefile
+       ])
+
+
+if test "${want_tests}" = "yes"; then
+       AC_CONFIG_FILES([tests/Makefile])
+       AC_CONFIG_FILES([tests/dummyatk/Makefile])
+fi
 
 AC_OUTPUT
diff --git a/tests/.gitignore b/tests/.gitignore
new file mode 100644 (file)
index 0000000..7ec3435
--- /dev/null
@@ -0,0 +1,8 @@
+.deps/
+.libs/
+app-test
+atk-test
+*.log
+*.o
+*.la
+*.lo
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644 (file)
index 0000000..c8d9a3a
--- /dev/null
@@ -0,0 +1,58 @@
+SUBDIRS = dummyatk
+
+noinst_PROGRAMS = atk-test app-test
+TESTS = atk-test
+lib_LTLIBRARIES =libxmlloader.la
+
+atk_test_CFLAGS = $(DBUS_CFLAGS) \
+                     -I$(top_builddir)\
+                     $(GLIB_CFLAGS) \
+                     $(ATSPI_CFLAGS) \
+                     -I$(top_srcdir)/tests/dummyatk/ \
+                     -I$(top_srcdir)/tests/dummyatk/.libs \
+                     -I$(top_srcdir)/tests/dummyatk/.deps \
+                     -I$(top_srcdir)
+
+atk_test_LDFLAGS  = libxmlloader.la \
+                       $(GLIB_LIBS) \
+                       $(ATSPI_LIBS) \
+                       $(top_srcdir)/tests/dummyatk/libdummyatk.la
+
+atk_test_CPPFLAGS = -DTESTS_BUILD_DIR=\"$(top_builddir)/tests\" \
+                    -DTESTS_SRC_DIR=\"$(top_srcdir)/tests\" \
+                    -DTESTS_DATA_DIR=\"$(top_srcdir)/tests/data\"
+
+atk_test_SOURCES = atk_suite.c \
+                   atk_test_accessible.c
+
+app_test_CFLAGS = -I$(top_builddir) \
+                   $(GLIB_CFLAGS) \
+                   $(ATK_CFLAGS) \
+                   -I$(top_srcdir)/tests/dummyatk \
+                   -I$(top_srcdir)/atk-adaptor
+
+app_test_LDFLAGS = libxmlloader.la \
+                   $(GLIB_LIBS) \
+                   $(ATK_LIBS) \
+                   $(top_srcdir)/tests/dummyatk/libdummyatk.la \
+                   $(top_srcdir)/atk-adaptor/libatk-bridge-2.0.la
+
+app_test_SOURCES = test-application.c
+
+libxmlloader_la_CFLAGS = \
+                         $(GLIB_CFLAGS) \
+                         $(GOBJ_CFLAGS)  \
+                         $(XML_CFLAGS) \
+                         $(ATK_CFLAGS) \
+                         -I$(top_srcdir)/tests/dummyatk/
+
+libxmlloader_la_LIBADD = \
+                         $(GLIB_LIBS) \
+                         $(XML_LIBS) \
+                         $(GOBJ_LIBS) \
+                         $(top_srcdir)/tests/dummyatk/libdummyatk.la \
+                         $(ATK_LIBS)
+
+libxmlloader_la_SOURCES =\
+                         atk-object-xml-loader.c\
+                         atk-object-xml-loader.h
diff --git a/tests/README b/tests/README
new file mode 100644 (file)
index 0000000..b48cb51
--- /dev/null
@@ -0,0 +1,74 @@
+
+Testing AT-SPI requires both a test application and an AT client.
+
+Test applications are built from xml files using xml loader module,
+based on Dummy ATK implementation.
+
+Each test is built as a GTest object and packed into a single interface test suite.
+
+Test directory contains:
+
+ * atk_suite - Generates a test suite, the main executable of all test suite,
+               help is shown when run with '-h' parameter.
+
+ * atk-object-xml-loader - Generates dummy atk object from xml file.
+
+ * test-application - Starts an application with atk object generated by atk-object-xml-loader
+
+ * data/ - Folder which contains xml file from which dummy atk object is generated
+
+ * dummyatk/ - Folder which contains dummy atk implementation
+
+
+************************
+HOW TO CREATE NEW TESTS:
+
+1) Add atspi interface which will be tested to Atk_Test_Case in atk_suite.c and atk_suite.h,
+   then add proper test call in atk_suite_build function.
+2) Prepare xml file which describes tested root object and descendants.
+   If any new fields in xml file appear, atk-object-xml-loader should be modifed.
+3) Add test file named atk_test_TEST_NAME.c, where TEST_NAME is tested interface name:
+   a) Create function which runs tested application
+   b) Create get_root_obj function for tested interface
+   c) Create tested functions
+   d) Create function which calls all test functions, this function should be called in atk_suite.c file.
+
+*************************
+AVAILABLE TESTS:
+
+- Accessible:
+             -accessible_get_name
+             -accessible_get_description
+             -accessible_get_child_count
+             -accessible_get_parent
+             -accessible_get_child_at_index
+             -accessible_get_index_in_parent
+             -accessible_get_relation_set_1
+             -accessible_get_relation_set_2
+             -accessible_get_role
+             -accessible_get_role_name
+             -accessible_get_localized_role_name
+             -accessible_get_state_set
+             -accessible_get_attributes
+             -accessible_get_attributes_as_array
+             -accessible_get_toolkit_name
+             -accessible_get_toolkit_version
+             -accessible_get_atspi_version
+             -accessible_get_id
+             -accessible_get_application
+             -accessible_get_action_iface
+             -accessible_get_collection_iface
+             -accessible_get_component_iface
+             -accessible_get_document_iface
+             -accessible_get_editable_text_iface
+             -accessible_get_hypertext_iface
+             -accessible_get_image_iface
+             -accessible_get_selection_iface
+             -accessible_get_table_iface
+             -accessible_get_text_iface
+             -accessible_get_value_iface
+             -accessible_get_interfaces
+             -accessible_get_object_locale
+             -accessible_set_cache_mask
+             -accessible_clear_cache
+             -accessible_get_process_id
diff --git a/tests/atk-object-xml-loader.c b/tests/atk-object-xml-loader.c
new file mode 100644 (file)
index 0000000..a05b4ea
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * AT-SPI - Assistive Technology Service Provider Interface
+ * (Gnome Accessibility Project; https://wiki.gnome.org/Accessibility)
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+#include "my-atk.h"
+
+#define ACCESSIBLE_NODE ((const xmlChar *) "accessible")
+#define INTERFACE_NODE  ((const xmlChar *) "interface")
+#define RELATION_NODE ((const xmlChar *) "relation")
+#define STATE_NODE ((const xmlChar *) "state")
+
+#define NAME_ATTR ((const xmlChar *) "name")
+#define DESC_ATTR ((const xmlChar *) "description")
+#define ROLE_ATTR ((const xmlChar *) "role")
+#define TYPE_ATTR ((const xmlChar *) "type")
+#define RELATION_TYPE_ATTR ((const xmlChar *) "relation_type")
+#define RELATION_TARGET_NAME_ATTR ((const xmlChar *) "target_name")
+#define STATE_TYPE_ATTR ((const xmlChar *) "state_enum")
+
+MyAtkObject *relation_target = NULL;
+
+static MyAtkObject *
+create_atk_object_from_element (xmlNode *element)
+{
+  xmlNode *child_node;
+  xmlNode *child_node2;
+
+  MyAtkObject *obj = NULL;
+  MyAtkObject *child_obj = NULL;
+  AtkRelationSet *relation_set = NULL;
+  AtkObject *array[1];
+  AtkRelation *relation;
+  AtkStateSet *state_set = NULL;
+  AtkStateType state_type;
+
+  xmlChar *name;
+  xmlChar *description;
+  xmlChar *type_text;
+  xmlChar *relation_type_text;
+  xmlChar *state_enum;
+  xmlChar *role;
+  gint relation_type;
+  xmlChar *relation_target_name;
+  GType type = MY_TYPE_ATK_OBJECT;
+
+  name = xmlGetProp (element, NAME_ATTR);
+  description = xmlGetProp (element, DESC_ATTR);
+  role = xmlGetProp (element, ROLE_ATTR);
+  type_text = xmlGetProp (element, TYPE_ATTR);
+
+  obj = MY_ATK_OBJECT (g_object_new (type,
+                                     "accessible-name", name,
+                                     "accessible-description", description,
+                                     "accessible-role", atk_role_for_name (role),
+                                     NULL));
+
+  child_node = element->xmlChildrenNode;
+  while (child_node != NULL) {
+    if (!xmlStrcmp(child_node->name, ACCESSIBLE_NODE)) {
+      child_obj = create_atk_object_from_element(child_node);
+      my_atk_object_add_child(obj, child_obj);
+
+      child_node2 = child_node->xmlChildrenNode;
+      while (child_node2 != NULL) {
+        if (!xmlStrcmp (child_node2->name, RELATION_NODE)) {
+          relation_type_text = xmlGetProp (child_node2, RELATION_TYPE_ATTR);
+          relation_type = atoi (relation_type_text);
+          relation_target_name = xmlGetProp (child_node2, RELATION_TARGET_NAME_ATTR);
+          relation_set = atk_object_ref_relation_set (ATK_OBJECT(child_obj));
+          array[0] = ATK_OBJECT (obj);
+          relation = atk_relation_new (array, 1, relation_type);
+          atk_relation_new (array, 1, relation_type);
+          atk_relation_set_add (relation_set, relation);
+          g_object_unref (relation);
+          g_object_unref (relation_set);
+          xmlFree (relation_target_name);
+          xmlFree (relation_type_text);
+        }
+        if (!xmlStrcmp (child_node2->name, STATE_NODE)) {
+          state_set = atk_object_ref_state_set (ATK_OBJECT(child_obj));
+          state_enum = xmlGetProp (child_node2, STATE_TYPE_ATTR);
+          state_type = atk_state_type_for_name (state_enum);
+          atk_state_set_add_state (state_set, state_type);
+          g_object_unref (state_set);
+          xmlFree (state_enum);
+        }
+        child_node2 = child_node2->next;
+      }
+    }
+    child_node = child_node->next;
+  }
+  return obj;
+}
+
+/*
+ * Reads the XML from filename and uses it
+ * to create a tree of MyAtkObjects.
+ *
+ * returns: The root object of the tree.
+ */
+MyAtkObject *
+atk_object_xml_parse (gchar *filename)
+{
+  xmlDoc *doc;
+  xmlNode *root_element;
+  MyAtkObject *new_atk_object = NULL;
+
+  doc = xmlReadFile (filename, NULL, 0);
+  g_assert (doc != NULL);
+
+  root_element = xmlDocGetRootElement (doc);
+
+  if (!xmlStrcmp (root_element->name, ACCESSIBLE_NODE))
+    new_atk_object = create_atk_object_from_element (root_element);
+
+  xmlFreeDoc (doc);
+  return new_atk_object;
+}
diff --git a/tests/atk-object-xml-loader.h b/tests/atk-object-xml-loader.h
new file mode 100644 (file)
index 0000000..5d2768a
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * AT-SPI - Assistive Technology Service Provider Interface
+ * (Gnome Accessibility Project; https://wiki.gnome.org/Accessibility)
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef ATK_OBJECT_XML_LOADER_H
+#define ATK_OBJECT_XML_LOADER_H
+
+#include <glib.h>
+#include "my-atk.h"
+
+MyAtkObject * atk_object_xml_parse (gchar *filename);
+
+#endif /*ATK_OBJECT_XML_LOADER_H*/
diff --git a/tests/atk_suite.c b/tests/atk_suite.c
new file mode 100644 (file)
index 0000000..0c8a21b
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * AT-SPI - Assistive Technology Service Provider Interface
+ * (Gnome Accessibility Project; https://wiki.gnome.org/Accessibility)
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <glib.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include "atk_suite.h"
+
+static gchar *tdata_list = NULL;
+
+typedef struct _Atk_Test_Case Atk_Test_Case;
+
+struct _Atk_Test_Case
+{
+  const char *test_case;
+  void (*build)( void);
+};
+
+static const Atk_Test_Case atc[] = {
+  { ATK_TEST_PATH_ACCESSIBLE, atk_test_accessible },
+  { NULL, NULL}
+};
+
+static void
+_list_tests (void)
+{
+  const Atk_Test_Case *itr;
+
+  itr = atc;
+  g_print ("Available Test Cases:\n");
+  for (; itr->test_case; itr++)
+    g_print ("\t%s\n", itr->test_case);
+}
+
+static void
+atk_suite_build (int argc, char **argv )
+{
+  g_test_init (&argc, &argv, NULL);
+  atk_test_accessible ();
+}
+
+static GOptionEntry optentries[] =
+{
+  {"list", 'l', 0, G_OPTION_ARG_NONE, &tdata_list, "Display all available test cases", NULL},
+  {NULL}
+};
+
+int
+main(int argc, char **argv)
+{
+  int test_result;
+  GOptionContext *opt;
+  opt = g_option_context_new (NULL);
+  g_option_context_add_main_entries (opt, optentries, NULL);
+  g_option_context_set_help_enabled (opt, TRUE);
+  g_option_context_set_ignore_unknown_options (opt, TRUE);
+
+  if (!g_option_context_parse (opt, &argc, &argv, NULL))
+    return EXIT_FAILURE;
+
+  if (tdata_list) {
+    _list_tests();
+    return EXIT_SUCCESS;
+  }
+
+  atk_suite_build (argc, argv);
+  test_result = g_test_run ();
+
+  return ( test_result == 0 ) ? 0 : 255;
+
+}
diff --git a/tests/atk_suite.h b/tests/atk_suite.h
new file mode 100644 (file)
index 0000000..59b3892
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * AT-SPI - Assistive Technology Service Provider Interface
+ * (Gnome Accessibility Project; https://wiki.gnome.org/Accessibility)
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _ATK_SUITE_H
+#define _ATK_SUITE_H
+
+#include <atspi/atspi.h>
+
+#define ATK_TEST_PATH_ACCESSIBLE (const char *)"/Accessible"
+
+void atk_test_accessible (void);
+
+#endif /* _ATK_SUITE_H */
diff --git a/tests/atk_test_accessible.c b/tests/atk_test_accessible.c
new file mode 100644 (file)
index 0000000..50ae9da
--- /dev/null
@@ -0,0 +1,502 @@
+/*
+ * AT-SPI - Assistive Technology Service Provider Interface
+ * (Gnome Accessibility Project; https://wiki.gnome.org/Accessibility)
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <locale.h>
+#include "atk_suite.h"
+
+#define DATA_FILE TESTS_DATA_DIR"/test.xml"
+
+pid_t child_pid;
+
+void
+run_app (void)
+{
+  int i=0;
+  child_pid = fork ();
+  if (child_pid == 0) {
+    execlp ("./app-test",
+            "./app-test",
+            "--test-data-file",
+            DATA_FILE,
+            NULL);
+    _exit(EXIT_SUCCESS);
+  }
+}
+
+AtspiAccessible * get_root_obj (void)
+{
+  int i;
+  AtspiAccessible *obj= NULL;
+
+  run_app ();
+
+  /* sleep is needed to wait for forked test application */
+  sleep (1);
+
+  obj = atspi_get_desktop (0);
+  gint child_count = atspi_accessible_get_child_count (obj, NULL);
+  if (child_count < 1) {
+    g_test_message ("Fail, test application not found\n");
+    g_test_fail ();
+    kill (child_pid, SIGTERM);
+    return NULL;
+  }
+
+  for (i=0; i<child_count; i++) {
+    AtspiAccessible *child = atspi_accessible_get_child_at_index (obj,i, NULL);
+    if (!strcmp (atspi_accessible_get_name (child, NULL), "root_object"))
+      return child;
+  }
+  g_test_message ("test object not found\n");
+  g_test_fail ();
+
+  kill (child_pid, SIGTERM);
+  return NULL;
+}
+
+static void
+teardown_accessible_test (gpointer fixture, gconstpointer user_data)
+{
+  kill (child_pid, SIGTERM);
+}
+
+static void
+atk_test_accessible_get_name (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  g_assert_cmpstr (atspi_accessible_get_name (obj, NULL), ==, "root_object");
+}
+
+static void
+atk_test_accessible_get_description (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  g_assert_cmpstr (atspi_accessible_get_description (obj, NULL), ==, "Root of the accessible tree" );
+}
+
+static void
+atk_test_accessible_get_child_count (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  gint child_c = atspi_accessible_get_child_count (obj, NULL);
+  g_assert_cmpint ( 3, ==, child_c );
+}
+
+static void
+atk_test_accessible_get_parent (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  AtspiAccessible *child = atspi_accessible_get_child_at_index (obj, 0, NULL );
+  AtspiAccessible *parent = atspi_accessible_get_parent (child, NULL );
+  g_assert (parent == obj );
+}
+
+static void
+atk_test_accessible_get_child_at_index (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  AtspiAccessible *child = atspi_accessible_get_child_at_index (obj, 1, NULL );
+  g_assert_cmpstr (atspi_accessible_get_name (child, NULL), ==, "obj2");
+}
+
+static void
+atk_test_accessible_get_index_in_parent (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  AtspiAccessible *child = atspi_accessible_get_child_at_index (obj, 2, NULL);
+  int index = atspi_accessible_get_index_in_parent (child, NULL);
+  g_assert_cmpint (index, ==, 2);
+}
+
+static void
+atk_test_accessible_get_relation_set_1 (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  AtspiAccessible *child1 = atspi_accessible_get_child_at_index (obj, 1, NULL);
+  AtspiAccessible *child = atspi_accessible_get_child_at_index (child1, 0, NULL);
+  GArray *rel_set = atspi_accessible_get_relation_set (child, NULL);
+  g_assert_cmpint (rel_set->len, == , 1);
+}
+
+static void
+atk_test_accessible_get_relation_set_2 (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *root_object = get_root_obj ();
+  AtspiAccessible *obj2 = atspi_accessible_get_child_at_index (root_object, 1, NULL);
+  AtspiAccessible *obj2_1 = atspi_accessible_get_child_at_index (obj2, 0, NULL);
+  GArray *rel_set = atspi_accessible_get_relation_set (obj2_1, NULL);
+  int i=0;
+  for (i = 0; i < rel_set->len; i++) {
+    AtspiRelation *a = g_array_index (rel_set, AtspiRelation *, i);
+    g_assert_cmpint (atspi_relation_get_relation_type (a), == , ATSPI_RELATION_CONTROLLER_FOR );
+    g_assert_cmpint (atspi_relation_get_n_targets (a), ==, 1);
+    AtspiAccessible *target = atspi_relation_get_target (a, 0);
+    g_assert_cmpstr (atspi_accessible_get_name (target,NULL), == , "obj2");
+  }
+}
+
+static void
+atk_test_accessible_get_role (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  AtspiRole root_role = atspi_accessible_get_role (obj, NULL);
+  g_assert_cmpint (root_role, ==, ATSPI_ROLE_ACCELERATOR_LABEL);
+}
+
+static void
+atk_test_accessible_get_role_name (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  gchar *root_role_name = atspi_accessible_get_role_name (obj, NULL);
+  g_assert_cmpstr (root_role_name, ==, "accelerator label");
+}
+
+static void
+atk_test_accessible_get_localized_role_name (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj();
+  gchar *root_role_name = atspi_accessible_get_localized_role_name (obj, NULL);
+  g_assert_cmpstr (root_role_name, ==, "accelerator label");
+}
+
+static void
+atk_test_accessible_get_state_set (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  AtspiAccessible *child = atspi_accessible_get_child_at_index (obj, 0, NULL);
+  AtspiStateSet *states = atspi_accessible_get_state_set (child);
+  GArray *states_arr = atspi_state_set_get_states (states);
+
+  AtspiStateType valid_states[] = {
+    ATSPI_STATE_MODAL,
+    ATSPI_STATE_MULTI_LINE,
+  };
+  g_assert_cmpint (states_arr->len, ==, 2);
+  int i = 0;
+  for (i = 0; i < states_arr->len; ++i) {
+    g_assert_cmpint (valid_states[i], ==, g_array_index (states_arr, AtspiStateType, i));
+    g_assert (atspi_state_set_contains (states, ATSPI_STATE_MODAL));
+    g_assert (atspi_state_set_contains(states, ATSPI_STATE_MULTI_LINE));
+  }
+}
+
+static void
+atk_test_accessible_get_attributes (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  GHashTable *attr_hash_tab = atspi_accessible_get_attributes (obj, NULL);
+  GHashTableIter iter;
+  gpointer key, value;
+
+  gchar *valid_keys[] = { "baz", "quux",  "foo" };
+  gchar *valid_values[] = { "qux", "corge", "bar" };
+
+  g_hash_table_iter_init (&iter, attr_hash_tab );
+  int i = 0;
+  while (g_hash_table_iter_next (&iter, &key, &value)) {
+    g_assert_cmpstr (valid_keys[i], ==, (gchar *)key );
+    g_assert_cmpstr (valid_values[i], ==, (gchar *)value );
+    ++i;
+  }
+}
+
+static void
+atk_test_accessible_get_attributes_as_array (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  gchar *valid_attr[] = { "foo:bar", "baz:qux", "quux:corge", NULL };
+  GArray *attr_arr = atspi_accessible_get_attributes_as_array ( obj, NULL);
+  int i = 0;
+  g_assert (attr_arr->len == 3);
+  for( i = 0; i < attr_arr->len; ++i) {
+    g_assert_cmpstr (valid_attr[i], ==, g_array_index (attr_arr, gchar *, i));
+  }
+}
+
+static void
+atk_test_accessible_get_toolkit_name (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  gchar *toolkit_name = atspi_accessible_get_toolkit_name (obj, NULL);
+
+  g_assert_cmpstr (toolkit_name, ==, "atspitesting-toolkit");
+}
+
+static void
+atk_test_accessible_get_toolkit_version (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  gchar *toolkit_ver = atspi_accessible_get_toolkit_version (obj, NULL);
+  /* should be empty string, because no value is setted */
+  g_assert_cmpstr (toolkit_ver, ==, "");
+}
+
+static void
+atk_test_accessible_get_atspi_version (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  gchar *atspi_version = atspi_accessible_get_atspi_version (obj, NULL);
+  g_assert_cmpstr (atspi_version, ==, "2.0");
+}
+
+static void
+atk_test_accessible_get_id (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  gint app_id = atspi_accessible_get_id (obj, NULL);
+  g_assert_cmpint (app_id, !=, -1);
+}
+
+static void
+atk_test_accessible_get_application (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  AtspiAccessible *app = atspi_accessible_get_application (obj, NULL);
+  g_assert (app != NULL);
+}
+
+static void
+atk_test_accessible_get_action_iface (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  AtspiAction *iface = atspi_accessible_get_action_iface (obj);
+  g_assert (iface == NULL);
+}
+
+static void
+atk_test_accessible_get_collection_iface (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  AtspiCollection *iface = atspi_accessible_get_collection_iface (obj);
+  g_assert (iface != NULL);
+}
+
+static void
+atk_test_accessible_get_component_iface (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  AtspiComponent *iface = atspi_accessible_get_component_iface (obj);
+  g_assert (iface == NULL);
+}
+
+static void
+atk_test_accessible_get_document_iface (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  AtspiDocument *iface = atspi_accessible_get_document_iface (obj);
+  g_assert (iface == NULL);
+}
+
+static void
+atk_test_accessible_get_editable_text_iface (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  AtspiEditableText *iface = atspi_accessible_get_editable_text_iface (obj);
+  g_assert (iface == NULL);
+}
+
+static void
+atk_test_accessible_get_hypertext_iface (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  AtspiHypertext *iface = atspi_accessible_get_hypertext_iface (obj);
+  g_assert (iface == NULL);
+}
+
+static void
+atk_test_accessible_get_image_iface (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  AtspiImage *iface = atspi_accessible_get_image_iface (obj);
+  g_assert (iface == NULL);
+}
+
+static void
+atk_test_accessible_get_selection_iface (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  AtspiSelection *iface = atspi_accessible_get_selection_iface (obj);
+  g_assert (iface == NULL);
+}
+
+static void
+atk_test_accessible_get_table_iface (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  AtspiTable *iface = atspi_accessible_get_table_iface (obj);
+  g_assert (iface == NULL);
+}
+
+static void
+atk_test_accessible_get_text_iface (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  AtspiText *iface = atspi_accessible_get_text_iface (obj);
+  g_assert (iface == NULL);
+}
+
+static void
+atk_test_accessible_get_value_iface (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  AtspiValue *iface = atspi_accessible_get_value_iface (obj);
+  g_assert (iface == NULL);
+}
+
+static void
+atk_test_accessible_get_interfaces (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj();
+  gchar *valid_obj_ifaces[] = { "Accessible", "Collection" };
+
+  GArray *ifaces = atspi_accessible_get_interfaces (obj);
+  g_assert (ifaces->len == 2);
+  int i = 0;
+  for (i = 0; i < ifaces->len; ++i)
+    g_assert_cmpstr (valid_obj_ifaces[i], ==, g_array_index (ifaces, gchar *, i));
+}
+
+static void
+atk_test_accessible_get_object_locale (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  const gchar *obj_locale = atspi_accessible_get_object_locale (obj, NULL);
+  g_assert_cmpstr (obj_locale, ==, setlocale (LC_MESSAGES, NULL));
+}
+
+static void
+atk_test_accessible_set_cache_mask (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  AtspiCache cache_mask = ATSPI_CACHE_ROLE;
+  atspi_accessible_set_cache_mask (obj, cache_mask);
+  g_assert_cmpint (obj->parent.app->cache, ==, cache_mask);
+}
+
+static void
+atk_test_check_cache_cleared (AtspiAccessible *obj)
+{
+  GList *l;
+  g_assert_cmpint (obj->cached_properties, ==, ATSPI_CACHE_NONE);
+  for (l = obj->children; l; l = l->next)
+    atk_test_check_cache_cleared( l->data);
+}
+
+static void
+atk_test_accessible_clear_cache (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  atspi_accessible_clear_cache (obj);
+  atk_test_check_cache_cleared (obj);
+}
+
+static void
+atk_test_accessible_get_process_id (gpointer fixture, gconstpointer user_data)
+{
+  AtspiAccessible *obj = get_root_obj ();
+  guint proc_id = atspi_accessible_get_process_id (obj, NULL);
+  g_assert_cmpint (proc_id, ==, child_pid);
+}
+
+void
+atk_test_accessible(void )
+{
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accesible_get_name",
+    0, NULL, NULL, atk_test_accessible_get_name, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_description",
+    0, NULL, NULL, atk_test_accessible_get_description, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_child_count",
+    0, NULL, NULL, atk_test_accessible_get_child_count, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_parent",
+    0, NULL, NULL, atk_test_accessible_get_parent, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_child_at_index",
+    0, NULL, NULL, atk_test_accessible_get_child_at_index, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_index_in_parent",
+    0, NULL, NULL, atk_test_accessible_get_index_in_parent, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_relation_set_1",
+    0, NULL, NULL, atk_test_accessible_get_relation_set_1, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_relation_set_2",
+    0, NULL, NULL, atk_test_accessible_get_relation_set_2, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_role",
+    0, NULL, NULL, atk_test_accessible_get_role, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_role_name",
+    0, NULL, NULL, atk_test_accessible_get_role_name, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_localized_role_name",
+    0, NULL, NULL, atk_test_accessible_get_localized_role_name, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_state_set",
+    0, NULL, NULL, atk_test_accessible_get_state_set, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_attributes",
+    0, NULL, NULL, atk_test_accessible_get_attributes, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_attributes_as_array",
+    0, NULL, NULL, atk_test_accessible_get_attributes_as_array, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_toolkit_name",
+    0, NULL, NULL, atk_test_accessible_get_toolkit_name, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_toolkit_version",
+    0, NULL, NULL, atk_test_accessible_get_toolkit_version, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_atspi_version",
+    0, NULL, NULL, atk_test_accessible_get_atspi_version, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_id",
+    0, NULL, NULL, atk_test_accessible_get_id, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_application",
+    0, NULL, NULL, atk_test_accessible_get_application, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_action_iface",
+    0, NULL, NULL, atk_test_accessible_get_action_iface, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_collection_iface",
+    0, NULL, NULL, atk_test_accessible_get_collection_iface, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_component_iface",
+    0, NULL, NULL, atk_test_accessible_get_component_iface, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_document_iface",
+    0, NULL, NULL, atk_test_accessible_get_document_iface, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_editable_text_iface",
+    0, NULL, NULL, atk_test_accessible_get_editable_text_iface, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_hypertext_iface",
+    0, NULL, NULL, atk_test_accessible_get_hypertext_iface, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_image_iface",
+    0, NULL, NULL, atk_test_accessible_get_image_iface, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_selection_iface",
+    0, NULL, NULL, atk_test_accessible_get_selection_iface, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_table_iface",
+    0, NULL, NULL, atk_test_accessible_get_table_iface, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_text_iface",
+    0, NULL, NULL, atk_test_accessible_get_text_iface, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_value_iface",
+    0, NULL, NULL, atk_test_accessible_get_value_iface, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_interfaces",
+    0, NULL, NULL, atk_test_accessible_get_interfaces, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_object_locale",
+    0, NULL, NULL, atk_test_accessible_get_object_locale, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_set_cache_mask",
+    0, NULL, NULL, atk_test_accessible_set_cache_mask, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_clear_cache",
+    0, NULL, NULL, atk_test_accessible_clear_cache, teardown_accessible_test );
+  g_test_add_vtable (ATK_TEST_PATH_ACCESSIBLE "/atk_test_accessible_get_process_id",
+    0, NULL, NULL, atk_test_accessible_get_process_id, teardown_accessible_test );
+}
diff --git a/tests/data/test.xml b/tests/data/test.xml
new file mode 100644 (file)
index 0000000..26728dd
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" ?>
+<accessible description="Root of the accessible tree" name="root_object" role="accelerator label">
+       <accessible description="first child" name="obj1" role="alert">
+               <state state_enum="modal"/>
+               <state state_enum="multi-line"/>
+       </accessible>
+       <accessible description="second child" name="obj2" role="animation">
+               <accessible description="first prechild" name="obj2/1" role="arrow">
+                       <relation relation_type="2" target_name="obj2"/>
+               </accessible>
+               <accessible description="second prechild" name="obj2/2" role="canvas"/>
+       </accessible>
+       <accessible description="third child" name="obj3" role="check box">
+               <accessible description="first prechild" name="obj3/1" role="check menu item"/>
+       </accessible>
+</accessible>
diff --git a/tests/dummyatk/Makefile.am b/tests/dummyatk/Makefile.am
new file mode 100644 (file)
index 0000000..ff018a9
--- /dev/null
@@ -0,0 +1,18 @@
+lib_LTLIBRARIES = libdummyatk.la
+
+libdummyatk_la_CFLAGS = $(ATK_CFLAGS)          \
+                       $(GMODULE_CFLAGS)       \
+                       $(GLIB_CFLAGS)          \
+                       $(GOBJ_CFLAGS)          \
+                       -I$(top_srcdir)
+
+libdummyatk_la_LDFLAGS = -no-undefined
+
+libdummyatk_la_LIBADD = $(ATK_LIBS)    \
+                       $(GMODULE_LIBS) \
+                       $(GLIB_LIBS)    \
+                       $(GOBJ_LIBS)
+
+libdummyatk_la_SOURCES = my-atk-object.c       \
+                        my-atk-object.h        \
+                        my-atk.h
diff --git a/tests/dummyatk/my-atk-object.c b/tests/dummyatk/my-atk-object.c
new file mode 100644 (file)
index 0000000..c20ad7a
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * AT-SPI - Assistive Technology Service Provider Interface
+ * (Gnome Accessibility Project; https://wiki.gnome.org/Accessibility)
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <atk/atk.h>
+
+#include "my-atk-object.h"
+
+struct _MyAtkObject
+{
+  AtkObject parent;
+  AtkStateSet *state_set;
+  AtkAttributeSet *attributes;
+  AtkRelationSet *relation_set;
+  GPtrArray* children;
+  gint id;
+};
+
+struct _MyAtkObjectClass
+{
+  AtkObjectClass parent;
+};
+
+GType my_atk_object_get_type (void);
+
+G_DEFINE_TYPE (MyAtkObject,
+               my_atk_object,
+               ATK_TYPE_OBJECT);
+
+void my_atk_object_add_child (MyAtkObject* parent,
+                              MyAtkObject* child)
+{
+  g_ptr_array_add (parent->children, child);
+  g_object_ref_sink (child);
+
+  atk_object_set_parent (ATK_OBJECT (child), ATK_OBJECT (parent));
+
+  g_signal_emit_by_name (parent, "children-changed::add",
+                         parent->children->len - 1,
+                         child);
+}
+
+void my_atk_object_remove_child (MyAtkObject* parent,
+                                 MyAtkObject* child)
+{
+  gint i;
+  for (i = parent->children->len - 1; i >= 0; i--) {
+    if (g_ptr_array_index (parent->children, i) == child)
+      break;
+    }
+  g_return_if_fail (i < 0);
+  g_ptr_array_remove_index (parent->children, i);
+  g_signal_emit_by_name (parent, "children-changed::remove", i, child);
+}
+
+static void my_atk_object_set_parent(AtkObject *accessible, AtkObject *parent)
+{
+  MyAtkObject *self = MY_ATK_OBJECT (accessible);
+  AtkObject *parent_old = atk_object_get_parent (accessible);
+
+  if (parent_old == parent)
+    return;
+
+  AtkObjectClass *klass = ATK_OBJECT_CLASS (my_atk_object_parent_class);
+  klass->set_parent (accessible, parent);
+
+  if (parent_old != NULL)
+    my_atk_object_remove_child (MY_ATK_OBJECT (parent_old), self);
+}
+
+static gint my_atk_object_get_n_children (AtkObject *accessible)
+{
+  MyAtkObject *self = MY_ATK_OBJECT (accessible);
+  return self->children->len;
+}
+
+static AtkObject* my_atk_object_ref_child (AtkObject *accessible, gint i)
+{
+  MyAtkObject *self = MY_ATK_OBJECT (accessible);
+
+  g_return_val_if_fail (i >= 0 || i <= self->children->len, NULL);
+
+  AtkObject* child = ATK_OBJECT (g_ptr_array_index (self->children, i));
+
+  return (child == NULL) ? NULL : g_object_ref (child);
+}
+
+static gint my_atk_object_get_index_in_parent (AtkObject *accessible)
+{
+  AtkObject *parent = atk_object_get_parent (accessible);
+  if (parent == NULL) return -1; /*root object so no parent*/
+
+  MyAtkObject *parent_my = MY_ATK_OBJECT (parent);
+
+  int i = parent_my->children->len;
+  for (; i>=0; i--) {
+    if (g_ptr_array_index (parent_my->children,i) == accessible)
+      break;
+  }
+
+  g_return_val_if_fail (i>=0, -1);
+
+  return i;
+}
+
+static AtkRelationSet *my_atk_object_ref_relation_set (AtkObject* accessible)
+{
+  MyAtkObject *obj = MY_ATK_OBJECT (accessible);
+  if (obj->relation_set == NULL)
+    obj->relation_set = atk_relation_set_new ();
+  return g_object_ref (G_OBJECT (obj->relation_set));
+}
+
+static AtkStateSet *my_atk_object_ref_state_set (AtkObject *accessible)
+{
+  MyAtkObject *obj = MY_ATK_OBJECT (accessible);
+  if (obj->state_set == NULL)
+    obj->state_set = atk_state_set_new ();
+  return g_object_ref (G_OBJECT (obj->state_set));
+}
+
+static AtkAttributeSet *my_atk_object_get_attributes (AtkObject *accessible)
+{
+  MyAtkObject *obj = MY_ATK_OBJECT (accessible);
+  AtkAttributeSet *rs = obj->attributes = NULL;
+  AtkAttribute *a, *b, *c;
+
+  a = g_new (AtkAttribute, 1);
+  b = g_new (AtkAttribute, 1);
+  c = g_new (AtkAttribute, 1);
+
+  a->name = g_strdup ("foo");
+  a->value = g_strdup ("bar");
+  b->name = g_strdup ("baz");
+  b->value = g_strdup ("qux");
+  c->name = g_strdup ("quux");
+  c->value = g_strdup ("corge");
+
+  rs = g_slist_append (rs, (gpointer) a);
+  rs = g_slist_append (rs, (gpointer) b);
+  rs = g_slist_append (rs, (gpointer) c);
+}
+
+static void my_atk_object_init (MyAtkObject *self)
+{
+  self->children = g_ptr_array_new_full (10, g_object_unref);
+}
+
+static void my_atk_object_class_init (MyAtkObjectClass *my_class)
+{
+  AtkObjectClass *object_class = ATK_OBJECT_CLASS (my_class);
+
+  object_class->set_parent = my_atk_object_set_parent;
+  object_class->get_n_children = my_atk_object_get_n_children;
+  object_class->ref_child = my_atk_object_ref_child;
+  object_class->get_index_in_parent = my_atk_object_get_index_in_parent;
+  object_class->ref_state_set = my_atk_object_ref_state_set;
+  object_class->get_attributes = my_atk_object_get_attributes;
+  object_class->ref_relation_set = my_atk_object_ref_relation_set;
+
+}
diff --git a/tests/dummyatk/my-atk-object.h b/tests/dummyatk/my-atk-object.h
new file mode 100644 (file)
index 0000000..10ab034
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * AT-SPI - Assistive Technology Service Provider Interface
+ * (Gnome Accessibility Project; https://wiki.gnome.org/Accessibility)
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef MY_ATK_OBJECT_H
+#define MY_ATK_OBJECT_H
+
+#include <atk/atk.h>
+
+#define MY_TYPE_ATK_OBJECT             (my_atk_object_get_type ())
+#define MY_ATK_OBJECT(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), MY_TYPE_ATK_OBJECT, MyAtkObject))
+#define MY_ATK_OBJECT_CLASS(vtable)    (G_TYPE_CHECK_CLASS_CAST ((vtable), MY_TYPE_ATK_OBJECT, MyAtkObjectClass))
+#define MY_IS_ATK_OBJECT(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MY_TYPE_ATK_OBJECT))
+#define MY_IS_ATK_OBJECT_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), MY_TYPE_ATK_OBJECT))
+#define MY_ATK_OBJECT_GET_CLASS(inst)  (G_TYPE_INSTANCE_GET_CLASS ((inst), MY_TYPE_ATK_OBJECT, MyAtkObjectClass))
+
+typedef struct _MyAtkObject MyAtkObject;
+typedef struct _MyAtkObjectClass MyAtkObjectClass;
+
+GType my_atk_object_get_type ();
+
+void my_atk_object_add_child (MyAtkObject* parent,
+                              MyAtkObject* child);
+
+void my_atk_object_remove_child (MyAtkObject* parent,
+                                 MyAtkObject* child);
+
+#endif /*MY_ATK_OBJECT_H*/
diff --git a/tests/dummyatk/my-atk.h b/tests/dummyatk/my-atk.h
new file mode 100644 (file)
index 0000000..97e1bfd
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * AT-SPI - Assistive Technology Service Provider Interface
+ * (Gnome Accessibility Project; https://wiki.gnome.org/Accessibility)
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef MY_ATK_H
+#define MY_ATK_H
+
+#include "my-atk-object.h"
+
+#endif /*MY_ATK_H*/
diff --git a/tests/test-application.c b/tests/test-application.c
new file mode 100644 (file)
index 0000000..74265ae
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * AT-SPI - Assistive Technology Service Provider Interface
+ * (Gnome Accessibility Project; https://wiki.gnome.org/Accessibility)
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Testing AT-SPI requires both a test application and AT client.
+ * Test applications are built using the Dummy ATK implementation: MyAtk.
+ * This file contains the entry point for all test applications.
+ * The test will provide its own implementation of atk_get_root,
+ * and as such provide all the application state for the test.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <atk/atk.h>
+#include <atk-bridge.h>
+#include "my-atk.h"
+#include "atk-object-xml-loader.h"
+
+static AtkObject *root_accessible;
+
+static GMainLoop *mainloop;
+
+static gchar *tdata_path = NULL;
+
+void
+test_init (gchar *path)
+{
+  gchar *td;
+
+  if (path == NULL) {
+    g_print("No test data file provided\n");
+    exit(EXIT_FAILURE);
+  }
+  tdata_path = path;
+
+  td = g_build_path (G_DIR_SEPARATOR_S, tdata_path, NULL, NULL);
+  root_accessible = ATK_OBJECT (atk_object_xml_parse (td));
+  g_free (td);
+}
+
+AtkObject *
+test_get_root (void)
+{
+  return root_accessible;
+}
+
+static AtkObject *
+get_root (void)
+{
+  return test_get_root ();
+}
+
+const gchar *
+get_toolkit_name (void)
+{
+  return strdup ("atspitesting-toolkit");
+}
+
+static void
+setup_atk_util (void)
+{
+  AtkUtilClass *klass;
+
+  klass = g_type_class_ref (ATK_TYPE_UTIL);
+  klass->get_root = get_root;
+  klass->get_toolkit_name = get_toolkit_name;
+  g_type_class_unref (klass);
+}
+
+static GOptionEntry optentries[] =
+{
+  {"test-data-file", 0, 0, G_OPTION_ARG_STRING, &tdata_path, "Path to file of test data", NULL},
+  {NULL}
+};
+
+int main (int argc, char *argv[])
+{
+  GOptionContext *opt;
+  GError *err = NULL;
+  opt = g_option_context_new (NULL);
+  g_option_context_add_main_entries (opt, optentries, NULL);
+  g_option_context_set_ignore_unknown_options (opt, TRUE);
+
+  if (!g_option_context_parse (opt, &argc, &argv, &err))
+    g_error("Option parsing failed: %s\n", err->message);
+
+  setup_atk_util ();
+  test_init (tdata_path);
+  atk_bridge_adaptor_init (NULL, NULL);
+
+  mainloop = g_main_loop_new (NULL, FALSE);
+  g_main_loop_run (mainloop);
+
+  return 0;
+}