From 0dfb76041528ab5f13ab9f0646d9de088c9adb5d Mon Sep 17 00:00:00 2001 From: Mark Doffman Date: Fri, 22 Aug 2008 15:27:29 +0100 Subject: [PATCH] 2008-08-22 Mark Doffman * pyatspi/state.py tests/pyatspi/statetest.py tests/apps/accessible-app.c Add a stateset unit test. * tests/dummyatk/* tests/pyatspi/accessibletest.py Add a more complete getAttributes test. --- pyatspi/state.py | 16 ++++--- tests/apps/accessible-app.c | 14 ++++++ tests/dummyatk/my-atk-object.c | 35 ++++++++++++++ tests/dummyatk/my-atk-object.h | 2 + tests/pyatspi/accessibletest.py | 16 +++++-- tests/pyatspi/componenttest.py | 2 +- tests/pyatspi/desktoptest.py | 2 +- tests/pyatspi/statetest.py | 101 ++++++++++++++++++++++++++++++++++++++++ 8 files changed, 177 insertions(+), 11 deletions(-) create mode 100644 tests/pyatspi/statetest.py diff --git a/pyatspi/state.py b/pyatspi/state.py index 971bc66..6e698d4 100644 --- a/pyatspi/state.py +++ b/pyatspi/state.py @@ -141,13 +141,16 @@ def _marshal_state_set(bitfield): pos = 0 while (lower): if (1L)&lower: - #TODO Return the state objects rather than integers. - states.append(pos) + states.append(StateType(pos)) pos+=1 + lower >>= 1 + + pos = 32 while (upper): if (1L)&upper: - #TODO return the state objects rather than integers. - states.append(pos) + states.append(StateType(pos)) + pos+=1 + upper >>= 1 return StateSet(*states) @@ -170,8 +173,8 @@ class StateSet(object): @param states: States to add immediately @type states: list """ - map(self.add, states) self.states = set() + map(self.add, states) def contains(self, state): """ @@ -191,7 +194,8 @@ class StateSet(object): @param states: State(s) to add @type states: Accessibility.StateType """ - self.states.add(state) + for state in states: + self.states.add(state) def remove(self, state): """ diff --git a/tests/apps/accessible-app.c b/tests/apps/accessible-app.c index 408759b..2796bf5 100644 --- a/tests/apps/accessible-app.c +++ b/tests/apps/accessible-app.c @@ -8,11 +8,21 @@ static gchar *tdata_path = NULL; static AtkObject *root_accessible; +static AtkStateType states[] = +{ + ATK_STATE_MULTI_LINE, + ATK_STATE_MODAL, + ATK_STATE_INDETERMINATE, + ATK_STATE_SUPPORTS_AUTOCOMPLETION, + ATK_STATE_VERTICAL +}; + #define OBJECT_TEST_1 "accessible-test.xml" G_MODULE_EXPORT void test_init (gchar *path) { + AtkStateSet *ss; gchar *td; if (path == NULL) @@ -22,6 +32,10 @@ test_init (gchar *path) td = g_build_path(G_DIR_SEPARATOR_S, tdata_path, OBJECT_TEST_1, NULL); root_accessible = ATK_OBJECT(atk_object_xml_parse(td)); g_free(td); + + ss = atk_object_ref_state_set(ATK_OBJECT(root_accessible)); + atk_state_set_add_states(ss, states, 5); + g_object_unref(G_OBJECT(ss)); } G_MODULE_EXPORT void diff --git a/tests/dummyatk/my-atk-object.c b/tests/dummyatk/my-atk-object.c index 23f6c65..4029424 100644 --- a/tests/dummyatk/my-atk-object.c +++ b/tests/dummyatk/my-atk-object.c @@ -1,4 +1,5 @@ +#include #include #include "my-atk-object.h" @@ -90,6 +91,37 @@ static gint my_atk_object_get_index_in_parent(AtkObject *accessible) return i;//if error, i will be equal to -1 } +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); +} + //function, needed in instance_finalize() static void my_unref1(gpointer data, gpointer user_data) { @@ -117,6 +149,8 @@ void my_atk_object_class_init(gpointer g_class, gpointer g_class_data) atkObjectClass->get_n_children = my_atk_object_get_n_children; atkObjectClass->ref_child = my_atk_object_ref_child; atkObjectClass->get_index_in_parent = my_atk_object_get_index_in_parent; + atkObjectClass->ref_state_set = my_atk_object_ref_state_set; + atkObjectClass->get_attributes = my_atk_object_get_attributes; atk_object_parent_class = g_type_class_peek_parent(g_class); } @@ -126,6 +160,7 @@ static void my_atk_object_instance_init(GTypeInstance *obj, gpointer g_class) MyAtkObject *self = (MyAtkObject*)obj; self->children = g_ptr_array_sized_new(10); + self->attributes = g_slist_alloc(); } GType my_atk_object_get_type() diff --git a/tests/dummyatk/my-atk-object.h b/tests/dummyatk/my-atk-object.h index 04b0c78..72a4aea 100644 --- a/tests/dummyatk/my-atk-object.h +++ b/tests/dummyatk/my-atk-object.h @@ -17,6 +17,8 @@ struct _MyAtkObject { AtkObject parent; //array of children + AtkStateSet *state_set; + AtkAttributeSet *attributes; GPtrArray* children; gint id; }; diff --git a/tests/pyatspi/accessibletest.py b/tests/pyatspi/accessibletest.py index 29d3aa2..3867883 100644 --- a/tests/pyatspi/accessibletest.py +++ b/tests/pyatspi/accessibletest.py @@ -8,6 +8,13 @@ import os from pasytest import PasyTest as _PasyTest import pyatspi +from pyatspi import StateSet + +st = [pyatspi.STATE_MULTI_LINE, + pyatspi.STATE_MODAL, + pyatspi.STATE_INDETERMINATE, + pyatspi.STATE_SUPPORTS_AUTOCOMPLETION, + pyatspi.STATE_VERTICAL,] def _createNode(accessible, parentElement): e = minidom.Element("accessible") @@ -100,8 +107,10 @@ class AccessibleTest(_PasyTest): def test_getAttributes(self, test): root = self._desktop.getChildAtIndex(0) - #TODO The AttributeSet test needs expanding. Check attributes are passed correctly. attr = root.getAttributes() + res = ["foo:bar", "baz:qux", "quux:corge"] + test.assertEqual(attr, res, "Attributes expected %s, recieved %s" % (attr, res)) + def test_parent(self, test): root = self._desktop.getChildAtIndex(0) @@ -159,10 +168,11 @@ class AccessibleTest(_PasyTest): "Expected roleName - \"%s\". Recieved - \"%s\"" % (ans, res,)) def test_getState(self, test): - # Complete test of StateSet interface is separate root = self._desktop.getChildAtIndex(0) state = root.getState() - list = state.getStates() + res = StateSet(*st) + if not res.equals(state): + test.fail("States not reported correctly") def test_childCount(self, test): root = self._desktop.getChildAtIndex(0) diff --git a/tests/pyatspi/componenttest.py b/tests/pyatspi/componenttest.py index 41c8a7f..28a66f3 100644 --- a/tests/pyatspi/componenttest.py +++ b/tests/pyatspi/componenttest.py @@ -39,7 +39,7 @@ class ComponentTest(_PasyTest): ] def __init__(self, bus, path): - _PasyTest.__init__(self, "Accessible", False) + _PasyTest.__init__(self, "Component", False) self._bus = bus self._path = path diff --git a/tests/pyatspi/desktoptest.py b/tests/pyatspi/desktoptest.py index 49db2af..8266220 100644 --- a/tests/pyatspi/desktoptest.py +++ b/tests/pyatspi/desktoptest.py @@ -41,7 +41,7 @@ class DesktopTest(_PasyTest): ] def __init__(self, bus, path): - _PasyTest.__init__(self, "Accessible", False) + _PasyTest.__init__(self, "Desktop", False) self._bus = bus self._path = path diff --git a/tests/pyatspi/statetest.py b/tests/pyatspi/statetest.py new file mode 100644 index 0000000..223cf6e --- /dev/null +++ b/tests/pyatspi/statetest.py @@ -0,0 +1,101 @@ +import dbus +import gobject +import os.path + +from xml.dom import minidom +import os + +from pasytest import PasyTest as _PasyTest + +import pyatspi +from pyatspi import StateSet + +os = [pyatspi.STATE_MULTISELECTABLE, + pyatspi.STATE_PRESSED, + pyatspi.STATE_SHOWING, + pyatspi.STATE_TRANSIENT, + pyatspi.STATE_COLLAPSED, + pyatspi.STATE_EDITABLE,] + +class StateTest(_PasyTest): + + __tests__ = ["setup", + "test_contains", + "test_add", + "test_remove", + "test_equals", + "test_compare", + "test_isEmpty", + "test_getStates", + "teardown", + ] + + def __init__(self, bus, path): + _PasyTest.__init__(self, "State", False) + + def setup(self, test): + pass + + def test_contains(self, test): + state = StateSet(*os) + if not state.contains(pyatspi.STATE_PRESSED): + test.fail("Does not find contained state") + if state.contains(pyatspi.STATE_ACTIVE): + test.fail("Finds state not contained") + + def test_add(self, test): + state = StateSet() + state.add(pyatspi.STATE_PRESSED) + if not state.contains(pyatspi.STATE_PRESSED): + test.fail("State not added") + + def test_remove(self, test): + state = StateSet(*os) + state.remove(pyatspi.STATE_PRESSED) + if state.contains(pyatspi.STATE_PRESSED): + test.fail("State not removed") + + def test_equals(self, test): + one = StateSet(*os) + two = StateSet(*os) + if not one.equals(two): + test.fail("Same states not found equal") + two.remove(pyatspi.STATE_PRESSED) + if two.equals(one): + test.fail("Unequal states found equal") + + def test_isEmpty(self, test): + emp = StateSet() + if not emp.isEmpty(): + test.fail("Empty state found non-empty") + emp.add(pyatspi.STATE_PRESSED) + if emp.isEmpty(): + test.fail("State incorrectly found empty") + + def test_compare(self, test): + one = StateSet(*os) + two = StateSet(*os) + + onemtwo = one.compare(two) + if not onemtwo.isEmpty(): + test.fail("Equal states when compared yeilds non-empty state") + + one.add(pyatspi.STATE_ACTIVE) + onemtwo = one.compare(two) + + act = StateSet(pyatspi.STATE_ACTIVE) + if not onemtwo.equals(act): + test.fail("Compared states do not yeild correct state") + + def test_getStates(self, test): + state = StateSet(*os) + + states = state.getStates() + cone = set(states) + ctwo = set(os) + + if not (cone.issubset(ctwo) and ctwo.issubset(cone)): + test.fail("States not reported correctly") + + def teardown(self, test): + pass -- 2.7.4