NULL, NULL, NULL, NULL
};
+static gchar* atspi_dbus_name;
+static gboolean atspi_no_register;
+
+static GOptionEntry atspi_option_entries[] =
+{
+ {"atspi-dbus-name", 0, 0, G_OPTION_ARG_STRING, &atspi_dbus_name, "D-Bus bus name to register as", NULL},
+ {"atspi-no-register", 0, 0, G_OPTION_ARG_NONE, &atspi_no_register, "Do not register with Registry Daemon", NULL},
+ {NULL}
+};
+
static SpiAppData *
-spi_app_init (AtkObject *root)
+spi_app_init (AtkObject *root, gint *argc, gchar **argv[])
{
+ GOptionContext *opt;
+ SpiAppData *ad = g_new0(SpiAppData, 1);
+ GError *err = NULL;
DBusError error;
+ int i;
+
+ opt = g_option_context_new(NULL);
+ g_option_context_add_main_entries(opt, atspi_option_entries, NULL);
+ g_option_context_set_ignore_unknown_options(opt, TRUE);
+ if (!g_option_context_parse(opt, argc, argv, &err))
+ g_warning("Option parsing failed: %s\n", err->message);
+
dbus_error_init(&error);
- SpiAppData *ad = (SpiAppData *)calloc(sizeof(SpiAppData), 1);
- if (!ad) return NULL;
ad->root = root;
ad->droute.bus = dbus_bus_get(DBUS_BUS_SESSION, &error);
+
if (!ad->droute.bus)
{
g_warning("Couldn't connect to dbus: %s\n", error.message);
free(ad);
return NULL;
}
- //dbus_connection_set_exit_on_disconnect(ad->droute.bus, FALSE);
- //dbus_bus_register(ad->droute.bus, &error);
- spi_dbus_initialize (&ad->droute);
- /* Below line for testing -- it should be removed once at-spi-registryd is working */
- if (dbus_bus_request_name(ad->droute.bus, "test.atspi.tree", 0, &error)) printf("Got test name.\n");
+ if (atspi_dbus_name != NULL && dbus_bus_request_name(ad->droute.bus,
+ atspi_dbus_name,
+ 0,
+ &error))
+ {
+ g_print("\nRecieved D-Bus name - %s\n", atspi_dbus_name);
+ }
spi_register_tree_object(ad->droute.bus, &ad->droute, "/org/freedesktop/atspi/tree");
- if (!dbus_connection_try_register_fallback (ad->droute.bus, "/org/freedesktop/atspi/accessible", &droute_vtable, &ad->droute, &error))
+ if (!dbus_connection_try_register_fallback (ad->droute.bus,
+ "/org/freedesktop/atspi/accessible",
+ &droute_vtable,
+ &ad->droute,
+ &error))
{
g_warning("Couldn't register droute.\n");
+ free(ad);
+ return NULL;
}
+
dbus_connection_setup_with_g_main(ad->droute.bus, g_main_context_default());
+
+ spi_dbus_initialize (&ad->droute);
return ad;
}
_dbg = (int) g_ascii_strtod (debug_env_string, NULL);
/* Connect to dbus */
- this_app = spi_app_init (atk_get_root ());
+ this_app = spi_app_init (atk_get_root (), argc, argv);
/*
* We only want to enable the bridge for top level
/* Create the accessible application server object */
if (this_app == NULL)
- this_app = spi_app_init (atk_get_root ());
+ this_app = spi_app_init (atk_get_root (), 0, NULL);
DBG (1, g_message ("About to register application\n"));
int
gtk_module_init (gint *argc, gchar **argv[])
{
+ //printf("Pointer to argc %x %x\n", (short) ((argc && 0xffff0000) >> 16), (short) (argc && 0xffff));
return atk_bridge_init (argc, argv);
}
void
gnome_accessibility_module_init (void)
{
- atk_bridge_init (NULL, NULL);
+ atk_bridge_init (0, NULL);
if (g_getenv ("AT_BRIDGE_SHUTDOWN"))
{
EXTRA_DIST = testrunner.py runtests.sh
TESTS=testrunner.py
-TESTS_ENVIRONMENT = PYTHONPATH=$(abs_top_srcdir)/python \
- ATSPI_INTROSPECTION_PATH=$(top_srcdir)/xml/introspection \
- testdata=$(abs_top_srcdir)/tests/data \
- atspilib=$(abs_top_srcdir)/atk-adaptor/.libs/libspiatk.so \
- testmodules=$(abs_top_srcdir)/tests/apps/.libs \
- testapp=$(abs_top_srcdir)/tests/apps/test-application
+TESTS_ENVIRONMENT = PYTHONPATH=$(abs_top_srcdir)/python \
+ ATSPI_INTROSPECTION_PATH=$(top_srcdir)/xml/introspection \
+ TEST_DATA_DIRECTORY=$(abs_top_srcdir)/tests/data \
+ TEST_ATSPI_LIBRARY=$(abs_top_srcdir)/atk-adaptor/.libs/libspiatk.so \
+ TEST_MODULES_DIRECTORY=$(abs_top_srcdir)/tests/apps/.libs \
+ TEST_APPLICATION=$(abs_top_srcdir)/tests/apps/test-application
CLEANFILES = *.pyc
check_PROGRAMS = test-application
-check_LTLIBRARIES = libnoopapp.la libobjectapp.la
+check_LTLIBRARIES = libnoopapp.la libobjectapp.la libcomponentapp.la
test_application_CFLAGS = $(DBUS_GLIB_CFLAGS) \
$(ATK_CFLAGS) \
libobjectapp_la_LDFLAGS = $(TEST_APP_LDFLAGS)
libobjectapp_la_LIBADD = $(TEST_APP_LIBADD) $(LIB_XML_LIBS)
libobjectapp_la_SOURCES = object-app.c atk-object-xml-loader.c atk-object-xml-loader.h
+
+libcomponentapp_la_CFLAGS = $(TEST_APP_CFLAGS)
+libcomponentapp_la_LDFLAGS = $(TEST_APP_LDFLAGS)
+libcomponentapp_la_LIBADD = $(TEST_APP_LIBADD)
+libcomponentapp_la_SOURCES = component-app.c
--- /dev/null
+#include <gmodule.h>
+#include <atk/atk.h>
+#include <my-atk.h>
+
+static gchar *tdata_path = NULL;
+
+static AtkComponent *comps[] = {NULL, NULL, NULL};
+static const AtkRectangle extents[] = {{0,0,30,20}, {40,30,30,40}, {0,0,70,70}};
+static const AtkLayer layers[] = {ATK_LAYER_WINDOW, ATK_LAYER_WIDGET, ATK_LAYER_MDI};
+static const guint zorders[] = {0, G_MININT, 100};
+static const gboolean extent_may_changed[] = {TRUE, FALSE, TRUE};
+
+G_MODULE_EXPORT void
+test_init (gchar *path)
+{
+ int i;
+
+ if (path == NULL)
+ g_error("No test data path provided");
+ tdata_path = path;
+
+ g_type_init();
+ for(i = 0; i < sizeof(comps) / sizeof(comps[0]); i++)
+ {
+ MyAtkComponent *mycomp = MY_ATK_COMPONENT(g_object_new(MY_TYPE_ATK_COMPONENT, NULL));
+
+ mycomp->extent = extents[i];
+ mycomp->is_extent_may_changed = extent_may_changed[i];
+ mycomp->layer = layers[i];
+ mycomp->zorder = zorders[i];
+
+ comps[i] = ATK_COMPONENT(mycomp);
+ }
+ atk_object_set_parent((AtkObject*)comps[0],(AtkObject*)comps[2]);
+ atk_object_set_parent((AtkObject*)comps[1],(AtkObject*)comps[2]);
+}
+
+G_MODULE_EXPORT void
+test_next (int argc, char *argv[])
+{
+ g_print("Moving to next stage\n");
+}
+
+G_MODULE_EXPORT void
+test_finished (int argc, char *argv[])
+{
+ g_print("Test has completed\n");
+}
+
+G_MODULE_EXPORT AtkObject *
+test_get_root (void)
+{
+ return ATK_COMPONENT(comps[2]);
+}
;
}
+G_MODULE_EXPORT void
+test_next (int argc, char *argv[])
+{
+ ;
+}
+
+G_MODULE_EXPORT void
+test_finished (int argc, char *argv[])
+{
+ ;
+}
+
G_MODULE_EXPORT AtkObject *
test_get_root (void)
{
g_free(td);
}
+G_MODULE_EXPORT void
+test_next (int argc, char *argv[])
+{
+ g_print("Moving to next stage\n");
+}
+
+G_MODULE_EXPORT void
+test_finished (int argc, char *argv[])
+{
+ g_print("Test has completed\n");
+}
+
G_MODULE_EXPORT AtkObject *
test_get_root (void)
{
* all the application state for the test.
*/
+#include <stdlib.h>
#include <glib.h>
#include <gmodule.h>
#include <atk/atk.h>
/* The test module, GModule containing interface for an atk-test */
static GModule *test_module;
static gpointer test_module_get_root;
+static gpointer test_module_next;
+static gpointer test_module_finished;
+
+static DBusConnection *dbus_bus;
+static GMainLoop *mainloop;
/* Test module interface */
/*************************/
return ((TestModuleGetRoot) test_module_get_root)();
}
+typedef void (*VoidVoid) (void);
+
+/* Called to move to next stage of test.*/
+static void
+next(void)
+{
+ ((VoidVoid) test_module_next)();
+}
+
+
/*************************/
/* The AtkUtil class is called to find the root accessible and to deal
g_type_class_unref(klass);
}
-typedef void (*GtkModuleInit) (int argc, char *argv[]);
+typedef void (*GtkModuleInit) (int *argc, char **argv[]);
/* AT-SPI is a gtk module that must be loaded and initialized */
static void
-load_atspi_module(const char *path, int argc, char *argv[])
+load_atspi_module(const char *path, int *argc, char **argv[])
{
GModule *bridge;
gpointer init;
if (!g_module_symbol(test_module, "test_get_root", &test_module_get_root))
g_error("Couldn't load symbol \"test_get_root\"\n");
+ if (!g_module_symbol(test_module, "test_next", &test_module_next))
+ g_error("Couldn't load symbol \"test_next\"\n");
+
+ if (!g_module_symbol(test_module, "test_finished", &test_module_finished))
+ g_error("Couldn't load symbol \"test_finished\"\n");
+
((TestModuleInit) init)((gchar *)tdpath);
}
+static const char* introspection_string =
+"<node name=\"/org/codethink/atspi/test\">"
+" <interface name=\"org.codethink.atspi.test\">"
+" <method name=\"next\"/>"
+" <signal name=\"started\"/>"
+" </interface>"
+"</node>";
+
+static DBusHandlerResult
+message_handler (DBusConnection *bus, DBusMessage *message, void *user_data)
+{
+ const char *iface = dbus_message_get_interface (message);
+ const char *member = dbus_message_get_member (message);
+ DBusHandlerResult result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ gboolean exit = FALSE;
+
+ DBusMessage *reply = NULL;
+
+ g_print("\nRecieved test interface message\n");
+
+ g_return_val_if_fail(iface != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
+
+ if (!strcmp(iface, "org.codethink.atspi.test"))
+ {
+ if (!strcmp(member, "next"))
+ {
+ next();
+ reply = dbus_message_new_method_return (message);
+ g_assert(reply != NULL);
+ result = DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ if (!strcmp(member, "finished"))
+ {
+ ((VoidVoid) test_module_finished)();
+ reply = dbus_message_new_method_return (message);
+ g_assert(reply != NULL);
+ result = DBUS_HANDLER_RESULT_HANDLED;
+ exit = TRUE;
+ }
+ }
+
+ if (!strcmp(iface, "org.freedesktop.DBus.Introspectable"))
+ {
+ if (!strcmp(member, "Introspect"))
+ {
+ reply = dbus_message_new_method_return (message);
+ g_assert(reply != NULL);
+ dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection_string,
+ DBUS_TYPE_INVALID);
+ result = DBUS_HANDLER_RESULT_HANDLED;
+ }
+ }
+
+ if (reply)
+ {
+ dbus_connection_send (bus, reply, NULL);
+ dbus_message_unref (reply);
+ }
+
+ if (exit == TRUE)
+ {
+ dbus_connection_flush(bus);
+ dbus_connection_unref(bus);
+ g_main_loop_quit(mainloop);
+ abort();
+ }
+ return result;
+}
+
+static DBusObjectPathVTable test_vtable =
+{
+ NULL,
+ &message_handler,
+ NULL, NULL, NULL, NULL
+};
+
+static void
+init_dbus_interface(void)
+{
+ DBusError error;
+
+ dbus_error_init(&error);
+ dbus_bus = dbus_bus_get(DBUS_BUS_SESSION, &error);
+ g_print("\nUnique D-Bus name is: %s\n", dbus_bus_get_unique_name(dbus_bus));
+
+ if (!dbus_bus)
+ g_error("Couldn't get the session bus - %s\n", error.message);
+
+ g_assert(dbus_connection_register_object_path(dbus_bus,
+ "/org/codethink/atspi/test",
+ &test_vtable,
+ NULL));
+
+ dbus_connection_setup_with_g_main(dbus_bus, g_main_context_default());
+}
+
+static void
+send_started_signal(void)
+{
+ DBusMessage* sig;
+ DBusMessageIter args;
+
+ sig = dbus_message_new_signal("/org/codethink/atspi/test", "org.codethink.atspi.test", "started");
+ g_assert(sig != NULL);
+ if (!dbus_connection_send(dbus_bus, sig, NULL))
+ g_error("Out of memory");
+ dbus_connection_flush(dbus_bus);
+ dbus_message_unref(sig);
+}
+
/*Command line data*/
static gchar *tmodule_path = NULL;
static gchar *amodule_path = NULL;
static GOptionEntry optentries[] =
{
- {"test-module", 't', 0, G_OPTION_ARG_STRING, &tmodule_path, "Module containing test scenario", NULL},
- {"atspi-module", 'a', 0, G_OPTION_ARG_STRING, &amodule_path, "Gtk module with atk-atspi adaptor", NULL},
- {"test-data", 'd', 0, G_OPTION_ARG_STRING, &tdata_path, "Path to directory of test data", NULL},
+ {"test-module", 0, 0, G_OPTION_ARG_STRING, &tmodule_path, "Module containing test scenario", NULL},
+ {"test-atspi-library", 0, 0, G_OPTION_ARG_STRING, &amodule_path, "Gtk module with atk-atspi adaptor", NULL},
+ {"test-data-directory", 0, 0, G_OPTION_ARG_STRING, &tdata_path, "Path to directory of test data", NULL},
{NULL}
};
*/
main(int argc, char *argv[])
{
- GMainLoop *mainloop;
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();
load_test_module(tmodule_path, tdata_path);
- load_atspi_module(amodule_path, argc, argv);
+ load_atspi_module(amodule_path, &argc, &argv);
+ init_dbus_interface();
+ send_started_signal();
mainloop = g_main_loop_new (NULL, FALSE);
g_main_loop_run (mainloop);
EXTRA_DIST = \
- accessibleobject.py \
__init__.py \
+ accessibleobject.py \
+ component.py \
testutil.py
CLEANFILES = *.pyc
-from accessibleobject import AccessibleObjectTestCase
+from accessibletest import AccessibleTestCase
+from componenttest import ComponentTestCase
import testutil
-
-del accessibleobject
-import unittest
import testutil
import dbus
import gobject
import os.path
+import coretest
from dbus.mainloop.glib import DBusGMainLoop
from accessible_cache import AccessibleCache
from xml.dom import minidom
+import os
def createNode(accessible, parentElement):
e = minidom.Element("accessible")
parentElement.appendChild(e)
-class AccessibleObjectTestCase(unittest.TestCase):
- def setUp(self):
- DBusGMainLoop(set_as_default=True)
- self._app = testutil.runTestApp("libobjectapp.so")
-
- self._bus = dbus.SessionBus()
- self._loop = gobject.MainLoop()
- self._cache = AccessibleCache(self._bus, testutil.busname, testutil.objectpath)
-
- def tearDown(self):
- del(self._bus)
- del(self._loop)
- del(self._cache)
- #TODO Shut down the test application.
- del(self._app)
-
+class AccessibleTestCase(coretest.CoreTestCase):
def runTest(self):
+ self._app = testutil.runTestApp("libobjectapp.so", self._name)
+ self._loop.run()
+
+ def post_application_test(self):
root = self._cache.getRootAccessible()
doc = minidom.Document()
createNode(root, doc)
answer = doc.toprettyxml()
- correct = os.path.join(testutil.testdata, "object-test-stage1-results.xml")
+ correct = os.path.join(os.environ["TEST_DATA_DIRECTORY"],
+ "object-test-stage1-results.xml")
file = open(correct)
cstring = file.read()
--- /dev/null
+import testutil
+
+import dbus
+import gobject
+import os.path
+import coretest
+from dbus.mainloop.glib import DBusGMainLoop
+
+from accessible_cache import AccessibleCache
+from accessible_cache import ATSPI_COMPONENT
+
+from xml.dom import minidom
+
+ATSPI_LAYER_WIDGET = 3
+ATSPI_LAYER_MDI = 4
+ATSPI_LAYER_WINDOW = 7
+
+extents_expected = [(0,0,30,20), (40,30,30,40), (0,0,70,70)]
+layers_expected = [ATSPI_LAYER_WINDOW, ATSPI_LAYER_WIDGET, ATSPI_LAYER_MDI]
+zorders_expected = [0, -100, 100]
+
+def supportsInterface(accessible, interface):
+ for itf in accessible.interfaces:
+ if itf == interface:
+ return True
+ return False
+
+class ComponentTestCase(coretest.CoreTestCase):
+ def runTest(self):
+ self._app = testutil.runTestApp("libcomponentapp.so", self._name)
+ self._loop.run()
+
+ def post_application_test(self):
+ #----------------------------------------
+ comps = [None, None, None]
+ comps[2] = self._cache.getRootAccessible()
+
+ self.assertEqual(comps[2].numChildren, 2,
+ """
+ Number of child components = %d
+ Correct number of components = 2
+ """ % comps[2].numChildren)
+ #----------------------------------------
+ comps[0] = comps[2].getChild(0)
+ comps[1] = comps[2].getChild(1)
+
+ for comp in comps:
+ self.assert_(supportsInterface(comp, ATSPI_COMPONENT),
+ """
+ An accessible object provided does not support the
+ component interface.
+ """)
+ #----------------------------------------
+ for (expected, comp) in zip(extents_expected, comps):
+ extents = comp.getExtents(dbus.types.UInt32(0))
+ self.assertEquals(extents, expected,
+ """
+ Extents of component do not match.
+ Expected: %s
+ Recieved: %s
+ """ % (str(expected), str(extents)))
+ #----------------------------------------
+ for (expected, comp) in zip(layers_expected, comps):
+ layer = comp.getLayer()
+ self.assertEquals(layer, expected,
+ """
+ Layer of component does not match.
+ Expected: %s
+ Recieved: %s
+ """ % (str(expected), str(layer)))
+ #----------------------------------------
+ #There is no defined value for the result when the layer is not WINDOW or MDI
+ #for (expected, comp) in zip(zorders_expected, [comps[0], comps[2]]):
+ # zorder = comp.getMDIZOrder()
+ # print zorder, expected
+ # self.assertEquals(layer, expected,
+ # """
+ # ZOrder of component does not match.
+ # Expected: %s
+ # Recieved: %s
+ # """ % (str(expected), str(zorder)))
+ #----------------------------------------
--- /dev/null
+import unittest
+import testutil
+
+import dbus
+import gobject
+import os.path
+from dbus.mainloop.glib import DBusGMainLoop
+
+from accessible_cache import AccessibleCache
+from random import randint
+
+
+
+class CoreTestCase(unittest.TestCase):
+ def setUp(self):
+ DBusGMainLoop(set_as_default=True)
+
+ self._bus = dbus.SessionBus()
+ self._loop = gobject.MainLoop()
+ self._name = "test.atspi.R" + str(randint(1, 1000))
+ self._match = self._bus.add_signal_receiver(self.post_application_setup,
+ "started",
+ "org.codethink.atspi.test",
+ self._name)
+ self._started = False
+
+ if "TEST_APP_WAIT_FOR_DEBUG" not in os.environ.keys():
+ gobject.timeout_add(1000, self.application_check)
+
+ def tearDown(self):
+ #Shut down the test application
+ self._test.finished()
+
+ del(self._bus)
+ del(self._loop)
+ del(self._cache)
+ del(self._app)
+ del(self._test)
+
+ def application_check(self):
+ if not self._started:
+ self.fail("Test application did not start")
+
+ def post_application_setup(self):
+ self._started = True
+
+ self._cache = AccessibleCache(self._bus, self._name, "/org/freedesktop/atspi/tree")
+
+ test_object = self._bus.get_object(self._name, "/org/codethink/atspi/test")
+ self._test = dbus.Interface(test_object, "org.codethink.atspi.test")
+
+ self.post_application_test()
+
+ self._loop.quit()
+
+ def post_application_test(self):
+ raise Exception, "No test has been defined"
-#Bus name where test application can be found.
-busname = "test.atspi.tree"
-#Path of tree interface on test application.
-objectpath = "/org/freedesktop/atspi/tree"
-
-#Directory where test data, such as XML results
-#can be found.
-testdata = "./"
-
-#Location of test application.
-testapp = "../apps/test-application"
-
-#Directory of test application modules.
-testmodules = "../apps/.libs"
-
-#Atk to at-spi adaptor library location.
-atspilib = "../../atk-adaptor/.libs/libspiatk.so"
-
-
-def runTestApp(module_name):
+def runTestApp(module_name, dbus_name):
import os
from subprocess import Popen
- testmodule = os.path.join(testmodules, module_name)
- pop = Popen([testapp , "-a", atspilib, "-t", testmodule, "-d", testdata])
+ test_data_directory = os.environ["TEST_DATA_DIRECTORY"]
+ test_modules_directory = os.environ["TEST_MODULES_DIRECTORY"]
+ test_atspi_library = os.environ["TEST_ATSPI_LIBRARY"]
+ test_application = os.environ["TEST_APPLICATION"]
- wait_envar = "TEST_APP_WAIT_FOR_DEBUG"
+ test_module = os.path.join(test_modules_directory, module_name)
+ pop = Popen([test_application,
+ "--atspi-dbus-name", dbus_name,
+ "--test-atspi-library", test_atspi_library,
+ "--test-module", test_module,
+ "--test-data-directory", test_data_directory,])
+
+ print " ".join([test_application,
+ "--atspi-dbus-name", dbus_name,
+ "--test-atspi-library", test_atspi_library,
+ "--test-module", test_module,
+ "--test-data-directory", test_data_directory,])
wait_message = """
The test application %s has been started with PID %d.
To continue the test press ENTER.\n\n
"""
-
- if (wait_envar in os.environ.keys()):
+ if ("TEST_APP_WAIT_FOR_DEBUG" in os.environ.keys()):
raw_input(wait_message % (module_name, pop.pid))
+++ /dev/null
-export PYTHONPATH=../python
-export ATSPI_INTROSPECTION_PATH=../xml/introspection
-
-export testdata=../tests/data
-export atspilib=../atk-adaptor/.libs/libspiatk.so
-export testmodules=../tests/apps/.libs
-export testapp=../tests/apps/test-application
-
-./testrunner.py
#!/usr/bin/python
import sys
-import os
import unittest
import clients
-optionvars = ["testdata",
- "atspilib",
- "testmodules",
- "testapp",
- "busname",
- "objectpath"]
-
-
def main(argv):
- def set_data(name):
- if name in os.environ.keys():
- setattr(clients.testutil, name, os.environ[name])
-
- [set_data(name) for name in optionvars]
-
runner = unittest.TextTestRunner()
testsuite = unittest.defaultTestLoader.loadTestsFromModule(clients)
result = runner.run(testsuite)
else:
return 1
-
if __name__=="__main__":
sys.exit(main(sys.argv))