2001-12-08 Michael Meeks <michael@ximian.com>
[platform/core/uifw/at-spi2-atk.git] / test / test-simple.c
1 /*
2  * test-simple.c: A set of simple regression tests
3  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
4  *
5  * Copyright 2001 Ximian, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 /*
24  * ******** Do not copy this code as an example *********
25  */
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <gtk/gtk.h>
31 #include <cspi/spi.h>
32 #include <libbonobo.h>
33
34 static void validate_accessible (Accessible *accessible,
35                                  gboolean    has_parent,
36                                  gboolean    recurse_down);
37
38 #define WINDOW_MAGIC 0x123456a
39 #define TEST_STRING_A "A test string"
40 #define TEST_STRING_B "Another test string"
41
42 static int      print_tree_depth = 0;
43 static gboolean print_tree = FALSE;
44
45 typedef struct {
46         gulong     magic;
47         GtkWidget *window;
48 } TestWindow;
49
50 static gboolean
51 focus_me (GtkWidget *widget)
52 {
53         AtkObject *aobject = atk_implementor_ref_accessible (
54                 ATK_IMPLEMENTOR (widget));
55
56         /* Force a focus event - even if the WM focused
57          * us before our at-bridge's idle handler registered
58          * our interest */
59         if (!GTK_WIDGET_HAS_FOCUS (widget))
60                 gtk_widget_grab_focus (widget);
61 /*      else: FIXME - gtk_widget_grab_focus should send a notify */
62                 atk_focus_tracker_notify (aobject);
63         
64         g_object_unref (G_OBJECT (aobject));
65
66         /* Pull focus away and then back - thus sucks */
67         return FALSE;
68 }
69
70 static TestWindow *
71 create_test_window (void)
72 {
73         TestWindow *win = g_new0 (TestWindow, 1);
74         GtkWidget  *widget, *vbox;
75
76         win->magic  = WINDOW_MAGIC;
77         win->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
78  
79         gtk_widget_show (win->window);
80
81         vbox = gtk_vbox_new (0, 0);
82         gtk_container_add (GTK_CONTAINER (win->window), vbox);
83         gtk_widget_show (vbox);
84
85         widget = gtk_entry_new ();
86         gtk_entry_set_text (GTK_ENTRY (widget), TEST_STRING_A);
87         gtk_container_add (GTK_CONTAINER (vbox), widget);
88         gtk_widget_show (widget);
89
90         g_idle_add ((GSourceFunc) focus_me, win->window);
91
92         return win;
93 }
94
95 static void
96 test_window_destroy (TestWindow *win)
97 {
98         gtk_widget_destroy (win->window);
99         g_free (win);
100 }
101
102 static void
103 test_roles (void)
104 {
105         int i;
106
107         fprintf (stderr, "Testing roles...\n");
108         for (i = -1; i < 1000; i++)
109                 g_assert (AccessibleRole_getName (i) != NULL);
110
111         g_assert (!strcmp (AccessibleRole_getName (SPI_ROLE_FILE_CHOOSER), "file chooser"));
112         g_assert (!strcmp (AccessibleRole_getName (SPI_ROLE_RADIO_BUTTON), "radiobutton"));
113         g_assert (!strcmp (AccessibleRole_getName (SPI_ROLE_TABLE), "table"));
114         g_assert (!strcmp (AccessibleRole_getName (SPI_ROLE_WINDOW), "window"));
115 }
116
117 static void
118 test_desktop (void)
119 {
120         Accessible *desktop;
121         Accessible *application;
122
123         fprintf (stderr, "Testing desktop...\n");
124
125         g_assert (getDesktop (-1) == NULL);
126         desktop = getDesktop (0);
127         g_assert (desktop != NULL);
128
129         validate_accessible (desktop, FALSE, FALSE);
130
131         application = Accessible_getChildAtIndex (desktop, 0);
132         g_assert (application != NULL);
133         AccessibleApplication_unref (application);
134
135         Accessible_unref (desktop);
136 }
137
138 static void
139 test_application (Accessible *application)
140 {
141         char *str;
142
143         fprintf (stderr, "Testing application ...\n");
144         g_assert (Accessible_isApplication (application));
145         g_assert (Accessible_getApplication (application) ==
146                   application);
147         AccessibleApplication_unref (application);
148
149         str = AccessibleApplication_getToolkitName (application);
150         g_assert (str != NULL);
151         g_assert (!strcmp (str, "GAIL"));
152         SPI_freeString (str);
153
154         str = AccessibleApplication_getVersion (application);
155         g_assert (str != NULL);
156         SPI_freeString (str);
157
158         AccessibleApplication_getID (application);
159 }
160
161 static void
162 test_editable_text (AccessibleEditableText *etext)
163 {
164         char *str;
165         AccessibleText *text;
166
167         fprintf (stderr, "Testing editable text ...\n");
168         
169         g_assert (Accessible_isText (etext));
170         text = Accessible_getText (etext);
171
172         AccessibleEditableText_setTextContents (
173                 etext, TEST_STRING_B);
174
175         str = AccessibleText_getText (text, 0, -1);
176         g_assert (!strcmp (str, TEST_STRING_B));
177
178         SPI_freeString (str);
179
180         /* FIXME: lots more editing here */
181
182         AccessibleEditableText_setTextContents (
183                 etext, TEST_STRING_A);
184
185         AccessibleText_unref (text);
186 }
187
188 static void
189 test_text (AccessibleText *text)
190 {
191         char *str;
192
193         fprintf (stderr, "Testing text ...\n");
194
195         g_assert (AccessibleText_getCharacterCount (text) ==
196                   strlen (TEST_STRING_A));
197
198         str = AccessibleText_getText (text, 0, -1);
199         g_assert (!strcmp (str, TEST_STRING_A));
200         SPI_freeString (str);
201
202         str = AccessibleText_getText (text, 0, 5);
203         g_assert (!strncmp (str, TEST_STRING_A, 5));
204         SPI_freeString (str);
205
206         AccessibleText_setCaretOffset (text, 7);
207         g_assert (AccessibleText_getCaretOffset (text) == 7);
208
209         /* FIXME: lots more tests - selections etc. etc. */
210 }
211
212 static void
213 test_component (AccessibleComponent *component)
214 {
215         long x, y, width, height;
216
217         fprintf (stderr, "Testing component...\n");
218
219         AccessibleComponent_getExtents (
220                 component, &x, &y, &width, &height, SPI_COORD_TYPE_SCREEN);
221
222         AccessibleComponent_getPosition (
223                 component, &x, &y, SPI_COORD_TYPE_SCREEN);
224
225         AccessibleComponent_getSize (component, &width, &height);
226
227         if (width > 0 && height > 0) {
228 #ifdef FIXME
229                 Accessible *accessible, *componentb;
230 #endif
231
232                 g_assert (AccessibleComponent_contains (
233                         component, x, y, SPI_COORD_TYPE_SCREEN));
234
235                 g_assert (AccessibleComponent_contains (
236                         component, x + width - 1, y, SPI_COORD_TYPE_SCREEN));
237
238                 g_assert (AccessibleComponent_contains (
239                         component, x + width - 1, y + height - 1,
240                         SPI_COORD_TYPE_SCREEN));
241
242 #ifdef FIXME
243                 accessible = AccessibleComponent_getAccessibleAtPoint (
244                         component, x, y, SPI_COORD_TYPE_SCREEN);
245
246                 g_assert (Accessible_isComponent (accessible));
247                 componentb = Accessible_getComponent (accessible);
248                 g_assert (componentb == component);
249
250                 AccessibleComponent_unref (componentb);
251                 Accessible_unref (accessible);
252 #endif
253         }
254
255         AccessibleComponent_getLayer (component);
256         AccessibleComponent_getMDIZOrder (component);
257 /*      AccessibleComponent_grabFocus (component); */
258 }
259
260 static void
261 validate_tree (Accessible *accessible,
262                gboolean    has_parent,
263                gboolean    recurse_down)
264 {
265         Accessible  *parent;
266         long         len, i;
267
268         parent = Accessible_getParent (accessible);
269         if (has_parent) {
270                 long        index;
271                 Accessible *child_at_index;
272
273                 g_assert (parent != NULL);
274
275                 index = Accessible_getIndexInParent (accessible);
276                 g_assert (index >= 0);
277
278                 child_at_index = Accessible_getChildAtIndex (parent, index);
279
280                 g_assert (child_at_index == accessible);
281
282                 Accessible_unref (child_at_index);
283                 Accessible_unref (parent);
284         }
285
286         len = Accessible_getChildCount (accessible);
287         print_tree_depth++;
288         for (i = 0; i < len; i++) {
289                 Accessible *child;
290
291                 child = Accessible_getChildAtIndex (accessible, i);
292 #ifdef ROPEY
293                 if (!child)
294                         fprintf (stderr, "Unusual - ChildGone at %ld\n", i);
295
296                 g_assert (Accessible_getIndexInParent (child) == i);
297                 g_assert (Accessible_getParent (child) == accessible);
298 #endif
299
300                 if (recurse_down && child)
301                         validate_accessible (child, has_parent, recurse_down);
302
303                 Accessible_unref (child);
304         }
305         print_tree_depth--;
306 }
307
308 static void
309 validate_accessible (Accessible *accessible,
310                      gboolean    has_parent,
311                      gboolean    recurse_down)
312 {
313         Accessible *tmp;
314         char       *name, *descr;
315         const char *role;
316
317         name = Accessible_getName (accessible);
318         g_assert (name != NULL);
319         
320         descr = Accessible_getDescription (accessible);
321         g_assert (descr != NULL);
322
323         role = Accessible_getRole (accessible);
324         g_assert (role != NULL);
325
326         if (print_tree) {
327                 int i;
328
329                 for (i = 0; i < print_tree_depth; i++)
330                         fputc (' ', stderr);
331                 fputs ("|-> [ ", stderr);
332         }
333
334         if (Accessible_isAction (accessible)) {
335                 tmp = Accessible_getAction (accessible);
336                 g_assert (tmp != NULL);
337                 if (print_tree)
338                         fprintf (stderr, "At");
339                 AccessibleAction_unref (tmp);
340         }
341
342         if (Accessible_isApplication (accessible)) {
343                 tmp = Accessible_getApplication (accessible);
344                 if (print_tree)
345                         fprintf (stderr, "Ap");
346                 else
347                         test_application (tmp);
348                 AccessibleApplication_unref (tmp);
349         }
350
351         if (Accessible_isComponent (accessible)) {
352                 tmp = Accessible_getComponent (accessible);
353                 g_assert (tmp != NULL);
354                 if (print_tree)
355                         fprintf (stderr, "Co");
356                 else
357                         test_component (tmp);
358                 AccessibleComponent_unref (tmp);
359         }
360
361         if (Accessible_isEditableText (accessible)) {
362                 tmp = Accessible_getEditableText (accessible);
363                 g_assert (tmp != NULL);
364                 if (print_tree)
365                         fprintf (stderr, "Et");
366                 else
367                         test_editable_text (tmp);
368                 AccessibleEditableText_unref (tmp);
369         }
370
371         if (Accessible_isHypertext (accessible)) {
372                 tmp = Accessible_getHypertext (accessible);
373                 g_assert (tmp != NULL);
374                 if (print_tree)
375                         fprintf (stderr, "Ht");
376                 AccessibleHypertext_unref (tmp);
377         }
378
379         if (Accessible_isImage (accessible)) {
380                 tmp = Accessible_getImage (accessible);
381                 g_assert (tmp != NULL);
382                 if (print_tree)
383                         fprintf (stderr, "Im");
384                 AccessibleImage_unref (accessible);
385         }
386
387         if (Accessible_isSelection (accessible)) {
388                 tmp = Accessible_getSelection (accessible);
389                 g_assert (tmp != NULL);
390                 if (print_tree)
391                         fprintf (stderr, "Se");
392                 AccessibleSelection_unref (tmp);
393         }
394
395         if (Accessible_isTable (accessible)) {
396                 tmp = Accessible_getTable (accessible);
397                 g_assert (tmp != NULL);
398                 if (print_tree)
399                         fprintf (stderr, "Ta");
400                 AccessibleTable_unref (tmp);
401         }
402
403         if (Accessible_isText (accessible)) {
404                 tmp = Accessible_getText (accessible);
405                 g_assert (tmp != NULL);
406                 if (print_tree)
407                         fprintf (stderr, "Te");
408                 else
409                         test_text (tmp);
410                 AccessibleText_unref (tmp);
411         }
412
413         if (print_tree)
414                 fprintf (stderr, " ] '%s' (%s) - %s:\n", name, descr, role);
415
416         SPI_freeString (name);
417         SPI_freeString (descr);
418
419         validate_tree (accessible, has_parent, recurse_down);
420 }
421
422 static void
423 test_misc (void)
424 {
425         fprintf (stderr, "Testing misc bits ...\n");
426
427         g_assert (!Accessible_isComponent (NULL));
428         g_assert (Accessible_getComponent (NULL) == NULL);
429         SPI_freeString (NULL);
430 }
431
432 static void
433 global_listener_cb (AccessibleEvent     *event,
434                     void                *user_data)
435 {
436         TestWindow *win = user_data;
437         Accessible *desktop;
438         AccessibleApplication *application;
439
440         g_assert (win->magic == WINDOW_MAGIC);
441         g_assert (!strcmp (event->type, "focus:"));
442
443         fprintf (stderr, "Fielded focus event ...\n");
444
445         desktop = getDesktop (0);
446         application = Accessible_getChildAtIndex (desktop, 0);
447         g_assert (application != NULL);
448         Accessible_unref (desktop);
449
450         test_application (application);
451         
452         AccessibleApplication_unref (application);
453
454         print_tree = TRUE;
455         validate_accessible (event->source, TRUE, TRUE);
456         print_tree = FALSE;
457         validate_accessible (event->source, TRUE, TRUE);
458
459         gtk_main_quit ();
460 }
461
462 int
463 main (int argc, char **argv)
464 {
465         int leaked;
466         TestWindow *win;
467         AccessibleEventListener *global_listener;
468
469         setenv ("GTK_MODULES", "gail:at-bridge", FALSE);
470
471         gtk_init (&argc, &argv);
472
473         g_assert (!SPI_init ());
474         g_assert (SPI_init ());
475         g_assert (getDesktopCount () == 1);
476
477         test_roles ();
478         test_misc ();
479         test_desktop ();
480
481         win = create_test_window ();
482
483         global_listener = createAccessibleEventListener (global_listener_cb, win);
484         g_assert (registerGlobalEventListener (global_listener, "focus:"));
485
486         fprintf (stderr, "Waiting for focus event ...\n");
487         gtk_main ();
488
489         g_assert (deregisterGlobalEventListenerAll (global_listener));
490         AccessibleEventListener_unref (global_listener);
491
492         test_window_destroy (win);
493
494         if ((leaked = SPI_exit ()))
495                 g_error ("Leaked %d SPI handles", leaked);
496
497         g_assert (!SPI_exit ());
498
499         fprintf (stderr, "All tests passed\n");
500
501         if (g_getenv ("_MEMPROF_SOCKET")) {
502                 fprintf (stderr, "Waiting for memprof\n");
503                 gtk_main ();
504         }
505
506         setenv ("AT_BRIDGE_SHUTDOWN", "1", TRUE);
507
508         return 0;
509 }