2001-12-11 Michael Meeks <michael@ximian.com>
[platform/upstream/at-spi2-core.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         return FALSE;
67 }
68
69 static void
70 test_window_add_and_show (GtkContainer *container, GtkWidget *widget)
71 {
72         gtk_container_add (container, widget);
73         gtk_widget_show (widget);
74 }
75
76 static TestWindow *
77 create_test_window (void)
78 {
79         TestWindow *win = g_new0 (TestWindow, 1);
80         GtkWidget  *widget, *vbox;
81         GtkListStore *store;
82         GtkTreeViewColumn *column;
83         GtkTreeIter iter;
84
85         win->magic  = WINDOW_MAGIC;
86         win->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
87  
88         gtk_widget_show (win->window);
89
90         vbox = gtk_vbox_new (0, 0);
91         gtk_container_add (GTK_CONTAINER (win->window), vbox);
92         gtk_widget_show (vbox);
93
94         widget = gtk_entry_new ();
95         gtk_entry_set_text (GTK_ENTRY (widget), TEST_STRING_A);
96         test_window_add_and_show (GTK_CONTAINER (vbox), widget);
97
98         widget = g_object_new (GTK_TYPE_RANGE, NULL);
99         gtk_range_set_range (GTK_RANGE (widget), 0.0, 100.0);
100         test_window_add_and_show (GTK_CONTAINER (vbox), widget);
101
102         store = gtk_list_store_new (1, G_TYPE_STRING);
103         gtk_list_store_append (store, &iter);
104         gtk_list_store_set (store, &iter, 0, TEST_STRING_A, -1); 
105         column = gtk_tree_view_column_new_with_attributes ("String",
106                 gtk_cell_renderer_text_new (), "text", 0, NULL);
107         widget = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store)); 
108         g_object_unref (G_OBJECT (store));
109         gtk_tree_view_append_column (GTK_TREE_VIEW (widget), column);
110         test_window_add_and_show (GTK_CONTAINER (vbox), widget);
111
112         g_idle_add ((GSourceFunc) focus_me, win->window);
113
114         return win;
115 }
116
117 static void
118 test_window_destroy (TestWindow *win)
119 {
120         gtk_widget_destroy (win->window);
121         g_free (win);
122 }
123
124 static void
125 test_roles (void)
126 {
127         int i;
128
129         fprintf (stderr, "Testing roles...\n");
130         for (i = -1; i < 1000; i++)
131                 g_assert (AccessibleRole_getName (i) != NULL);
132
133         g_assert (!strcmp (AccessibleRole_getName (SPI_ROLE_FILE_CHOOSER), "file chooser"));
134         g_assert (!strcmp (AccessibleRole_getName (SPI_ROLE_RADIO_BUTTON), "radiobutton"));
135         g_assert (!strcmp (AccessibleRole_getName (SPI_ROLE_TABLE), "table"));
136         g_assert (!strcmp (AccessibleRole_getName (SPI_ROLE_WINDOW), "window"));
137 }
138
139 static void
140 test_desktop (void)
141 {
142         Accessible *desktop;
143         Accessible *application;
144
145         fprintf (stderr, "Testing desktop...\n");
146
147         g_assert (getDesktop (-1) == NULL);
148         desktop = getDesktop (0);
149         g_assert (desktop != NULL);
150
151         validate_accessible (desktop, FALSE, FALSE);
152
153         application = Accessible_getChildAtIndex (desktop, 0);
154         g_assert (application != NULL);
155         AccessibleApplication_unref (application);
156
157         Accessible_unref (desktop);
158 }
159
160 static void
161 test_application (Accessible *application)
162 {
163         char *str;
164
165         fprintf (stderr, "Testing application ...\n");
166         g_assert (Accessible_isApplication (application));
167         g_assert (Accessible_getApplication (application) ==
168                   application);
169         AccessibleApplication_unref (application);
170
171         str = AccessibleApplication_getToolkitName (application);
172         g_assert (str != NULL);
173         g_assert (!strcmp (str, "GAIL"));
174         SPI_freeString (str);
175
176         str = AccessibleApplication_getVersion (application);
177         g_assert (str != NULL);
178         SPI_freeString (str);
179
180         AccessibleApplication_getID (application);
181 }
182
183 static void
184 test_editable_text (AccessibleEditableText *etext)
185 {
186         char *str;
187         AccessibleText *text;
188
189         fprintf (stderr, "Testing editable text ...\n");
190         
191         g_assert (Accessible_isText (etext));
192         text = Accessible_getText (etext);
193
194         AccessibleEditableText_setTextContents (
195                 etext, TEST_STRING_B);
196
197         str = AccessibleText_getText (text, 0, -1);
198         g_assert (!strcmp (str, TEST_STRING_B));
199
200         SPI_freeString (str);
201
202         /* FIXME: lots more editing here */
203
204         AccessibleEditableText_setTextContents (
205                 etext, TEST_STRING_A);
206
207         AccessibleText_unref (text);
208 }
209
210 static void
211 test_table (AccessibleTable *table)
212 {
213         Accessible *header;
214         gint index;
215         gint rows, columns;
216
217         fprintf (stderr, "Testing table ...\n");
218
219         rows = AccessibleTable_getNRows (table);
220         g_assert (rows > 0);
221
222         columns = AccessibleTable_getNColumns (table);
223         g_assert (columns > 0);
224
225         index = AccessibleTable_getIndexAt (table, rows - 1, columns - 1);
226
227         g_assert (AccessibleTable_getRowAtIndex (table, index) == rows - 1);
228
229         g_assert (AccessibleTable_getColumnAtIndex (table, index) == columns - 1);
230
231         g_assert ((header = AccessibleTable_getColumnHeader (table, 0)));
232         Accessible_unref (header);
233
234         AccessibleTable_isSelected (table, 0, 0);
235         
236         /* FIXME: lots more tests */
237 }
238
239 static void
240 test_text (AccessibleText *text)
241 {
242         char *str;
243
244         fprintf (stderr, "Testing text ...\n");
245
246         g_assert (AccessibleText_getCharacterCount (text) ==
247                   strlen (TEST_STRING_A));
248
249         str = AccessibleText_getText (text, 0, -1);
250         g_assert (!strcmp (str, TEST_STRING_A));
251         SPI_freeString (str);
252
253         str = AccessibleText_getText (text, 0, 5);
254         g_assert (!strncmp (str, TEST_STRING_A, 5));
255         SPI_freeString (str);
256
257         AccessibleText_setCaretOffset (text, 7);
258         g_assert (AccessibleText_getCaretOffset (text) == 7);
259
260         /* FIXME: lots more tests - selections etc. etc. */
261 }
262
263 static void
264 test_value (AccessibleValue *value)
265 {
266         float original_value;
267         
268         /* Note: test_value assertions are known not to work as of Dec 09 */
269         
270         fprintf (stderr, "Testing value ...\n");
271
272         original_value = AccessibleValue_getCurrentValue (value);
273         
274         g_assert (AccessibleValue_getCurrentValue (value) <=
275                   AccessibleValue_getMaximumValue (value));
276
277         g_assert (AccessibleValue_getCurrentValue (value) >=
278                   AccessibleValue_getMinimumValue (value));
279
280         AccessibleValue_setCurrentValue (value, 
281                   AccessibleValue_getMinimumValue (value));
282         
283         g_assert (AccessibleValue_getCurrentValue (value) ==
284                   AccessibleValue_getMinimumValue (value));
285
286         AccessibleValue_setCurrentValue (value, 
287                   AccessibleValue_getMaximumValue (value));
288         
289         g_assert (AccessibleValue_getCurrentValue (value) ==
290                   AccessibleValue_getMaximumValue (value));
291
292         AccessibleValue_setCurrentValue (value, original_value);
293         
294         g_assert (AccessibleValue_getCurrentValue (value) == original_value);
295 }
296
297 static void
298 test_component (AccessibleComponent *component)
299 {
300         long x, y, width, height;
301
302         fprintf (stderr, "Testing component...\n");
303
304         AccessibleComponent_getExtents (
305                 component, &x, &y, &width, &height, SPI_COORD_TYPE_SCREEN);
306
307         AccessibleComponent_getPosition (
308                 component, &x, &y, SPI_COORD_TYPE_SCREEN);
309
310         AccessibleComponent_getSize (component, &width, &height);
311
312         if (width > 0 && height > 0) {
313 #ifdef FIXME
314                 Accessible *accessible, *componentb;
315 #endif
316
317                 g_assert (AccessibleComponent_contains (
318                         component, x, y, SPI_COORD_TYPE_SCREEN));
319
320                 g_assert (AccessibleComponent_contains (
321                         component, x + width - 1, y, SPI_COORD_TYPE_SCREEN));
322
323                 g_assert (AccessibleComponent_contains (
324                         component, x + width - 1, y + height - 1,
325                         SPI_COORD_TYPE_SCREEN));
326
327 #ifdef FIXME
328                 accessible = AccessibleComponent_getAccessibleAtPoint (
329                         component, x, y, SPI_COORD_TYPE_SCREEN);
330
331                 g_assert (Accessible_isComponent (accessible));
332                 componentb = Accessible_getComponent (accessible);
333                 g_assert (componentb == component);
334
335                 AccessibleComponent_unref (componentb);
336                 Accessible_unref (accessible);
337 #endif
338         }
339
340         AccessibleComponent_getLayer (component);
341         AccessibleComponent_getMDIZOrder (component);
342 /*      AccessibleComponent_grabFocus (component); */
343 }
344
345 static void
346 validate_tree (Accessible *accessible,
347                gboolean    has_parent,
348                gboolean    recurse_down)
349 {
350         Accessible  *parent;
351         long         len, i;
352
353         parent = Accessible_getParent (accessible);
354         if (has_parent) {
355                 long        index;
356                 Accessible *child_at_index;
357
358                 g_assert (parent != NULL);
359
360                 index = Accessible_getIndexInParent (accessible);
361                 g_assert (index >= 0); 
362
363                 child_at_index = Accessible_getChildAtIndex (parent, index);
364
365                 g_assert (child_at_index == accessible);
366
367                 Accessible_unref (child_at_index);
368                 Accessible_unref (parent);
369         }
370
371         len = Accessible_getChildCount (accessible);
372         print_tree_depth++;
373         for (i = 0; i < len; i++) {
374                 Accessible *child;
375
376                 child = Accessible_getChildAtIndex (accessible, i);
377 #ifdef ROPEY
378                 if (!child)
379                         fprintf (stderr, "Unusual - ChildGone at %ld\n", i);
380
381                 g_assert (Accessible_getIndexInParent (child) == i);
382                 g_assert (Accessible_getParent (child) == accessible);
383 #endif
384
385                 if (recurse_down && child)
386                         validate_accessible (child, has_parent, recurse_down);
387
388                 Accessible_unref (child);
389         }
390         print_tree_depth--;
391 }
392
393 static void
394 validate_accessible (Accessible *accessible,
395                      gboolean    has_parent,
396                      gboolean    recurse_down)
397 {
398         Accessible *tmp;
399         char       *name, *descr;
400         const char *role;
401
402         name = Accessible_getName (accessible);
403         g_assert (name != NULL);
404         
405         descr = Accessible_getDescription (accessible);
406         g_assert (descr != NULL);
407
408         role = Accessible_getRole (accessible);
409         g_assert (role != NULL);
410
411         if (print_tree) {
412                 int i;
413
414                 for (i = 0; i < print_tree_depth; i++)
415                         fputc (' ', stderr);
416                 fputs ("|-> [ ", stderr);
417         }
418
419         if (Accessible_isAction (accessible)) {
420                 tmp = Accessible_getAction (accessible);
421                 g_assert (tmp != NULL);
422                 if (print_tree)
423                         fprintf (stderr, "At");
424                 AccessibleAction_unref (tmp);
425         }
426
427         if (Accessible_isApplication (accessible)) {
428                 tmp = Accessible_getApplication (accessible);
429                 if (print_tree)
430                         fprintf (stderr, "Ap");
431                 else
432                         test_application (tmp);
433                 AccessibleApplication_unref (tmp);
434         }
435
436         if (Accessible_isComponent (accessible)) {
437                 tmp = Accessible_getComponent (accessible);
438                 g_assert (tmp != NULL);
439                 if (print_tree)
440                         fprintf (stderr, "Co");
441                 else
442                         test_component (tmp);
443                 AccessibleComponent_unref (tmp);
444         }
445
446         if (Accessible_isEditableText (accessible)) {
447                 tmp = Accessible_getEditableText (accessible);
448                 g_assert (tmp != NULL);
449                 if (print_tree)
450                         fprintf (stderr, "Et");
451                 else
452                         test_editable_text (tmp);
453                 AccessibleEditableText_unref (tmp);
454         }
455
456         if (Accessible_isHypertext (accessible)) {
457                 tmp = Accessible_getHypertext (accessible);
458                 g_assert (tmp != NULL);
459                 if (print_tree)
460                         fprintf (stderr, "Ht");
461                 AccessibleHypertext_unref (tmp);
462         }
463
464         if (Accessible_isImage (accessible)) {
465                 tmp = Accessible_getImage (accessible);
466                 g_assert (tmp != NULL);
467                 if (print_tree)
468                         fprintf (stderr, "Im");
469                 AccessibleImage_unref (accessible);
470         }
471
472         if (Accessible_isSelection (accessible)) {
473                 tmp = Accessible_getSelection (accessible);
474                 g_assert (tmp != NULL);
475                 if (print_tree)
476                         fprintf (stderr, "Se");
477                 AccessibleSelection_unref (tmp);
478         }
479
480         if (Accessible_isTable (accessible)) {
481                 tmp = Accessible_getTable (accessible);
482                 g_assert (tmp != NULL);
483                 if (print_tree)
484                         fprintf (stderr, "Ta");
485                 else
486                         test_table (tmp);
487                 AccessibleTable_unref (tmp);
488         }
489
490         if (Accessible_isText (accessible)) {
491                 tmp = Accessible_getText (accessible);
492                 g_assert (tmp != NULL);
493                 if (print_tree)
494                         fprintf (stderr, "Te");
495                 else
496                         test_text (tmp);
497                 AccessibleText_unref (tmp);
498         }
499
500         if (Accessible_isValue (accessible)) {
501                 tmp = Accessible_getValue (accessible);
502                 g_assert (tmp != NULL);
503                 if (print_tree)
504                         fprintf (stderr, "Va");
505                 else
506                         test_value (tmp); 
507                 AccessibleValue_unref (tmp);
508         }
509
510         if (print_tree)
511                 fprintf (stderr, " ] '%s' (%s) - %s:\n", name, descr, role);
512
513         SPI_freeString (name);
514         SPI_freeString (descr);
515
516         validate_tree (accessible, has_parent, recurse_down);
517 }
518
519 static void
520 test_misc (void)
521 {
522         fprintf (stderr, "Testing misc bits ...\n");
523
524         g_assert (!Accessible_isComponent (NULL));
525         g_assert (Accessible_getComponent (NULL) == NULL);
526         SPI_freeString (NULL);
527 }
528
529 static void
530 global_listener_cb (AccessibleEvent     *event,
531                     void                *user_data)
532 {
533         TestWindow *win = user_data;
534         Accessible *desktop;
535         AccessibleApplication *application;
536
537         g_assert (win->magic == WINDOW_MAGIC);
538         g_assert (!strcmp (event->type, "focus:"));
539
540         fprintf (stderr, "Fielded focus event ...\n");
541
542         desktop = getDesktop (0);
543         application = Accessible_getChildAtIndex (desktop, 0);
544         g_assert (application != NULL);
545         Accessible_unref (desktop);
546
547         test_application (application);
548         
549         AccessibleApplication_unref (application);
550
551         print_tree = TRUE;
552         validate_accessible (event->source, TRUE, TRUE);
553         print_tree = FALSE;
554         validate_accessible (event->source, TRUE, TRUE);
555
556         gtk_main_quit ();
557 }
558
559 int
560 main (int argc, char **argv)
561 {
562         int leaked;
563         TestWindow *win;
564         const char *modules;
565         AccessibleEventListener *global_listener;
566
567         modules = g_getenv ("GTK_MODULES");
568         if (!modules || modules [0] == '\0')
569                 putenv ("GTK_MODULES=gail:at-bridge");
570         modules = NULL;
571
572         gtk_init (&argc, &argv);
573
574         g_assert (!SPI_init ());
575         g_assert (SPI_init ());
576         g_assert (getDesktopCount () == 1);
577
578         test_roles ();
579         test_misc ();
580         test_desktop ();
581
582         win = create_test_window ();
583
584         global_listener = createAccessibleEventListener (global_listener_cb, win);
585         g_assert (registerGlobalEventListener (global_listener, "focus:"));
586
587         fprintf (stderr, "Waiting for focus event ...\n");
588         gtk_main ();
589
590         g_assert (deregisterGlobalEventListenerAll (global_listener));
591         AccessibleEventListener_unref (global_listener);
592
593         test_window_destroy (win);
594
595         if ((leaked = SPI_exit ()))
596                 g_error ("Leaked %d SPI handles", leaked);
597
598         g_assert (!SPI_exit ());
599
600         fprintf (stderr, "All tests passed\n");
601
602         if (g_getenv ("_MEMPROF_SOCKET")) {
603                 fprintf (stderr, "Waiting for memprof\n");
604                 gtk_main ();
605         }
606
607         putenv ("AT_BRIDGE_SHUTDOWN=1");
608
609         return 0;
610 }