2009-12-07 Joanmarie Diggs <joanmarie.diggs@gmail.com>
[WebKit-https.git] / WebKit / gtk / tests / testatk.c
1 /*
2  * Copyright (C) 2009 Igalia S.L.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 #include <errno.h>
21 #include <unistd.h>
22 #include <glib.h>
23 #include <glib/gstdio.h>
24 #include <gtk/gtk.h>
25 #include <webkit/webkit.h>
26
27 #if GLIB_CHECK_VERSION(2, 16, 0) && GTK_CHECK_VERSION(2, 14, 0)
28
29 static const char* contents = "<html><body><p>This is a test. This is the second sentence. And this the third.</p></body></html>";
30
31 static const char* contentsWithNewlines = "<html><body><p>This is a test. \n\nThis\n is the second sentence. And this the third.</p></body></html>";
32
33 static const char* contentsInTextarea = "<html><body><textarea cols='80'>This is a test. This is the second sentence. And this the third.</textarea></body></html>";
34
35 static const char* contentsInTextInput = "<html><body><input type='text' size='80' value='This is a test. This is the second sentence. And this the third.'/></body></html>";
36
37 static gboolean bail_out(GMainLoop* loop)
38 {
39     if (g_main_loop_is_running(loop))
40         g_main_loop_quit(loop);
41
42     return FALSE;
43 }
44
45 typedef gchar* (*AtkGetTextFunction) (AtkText*, gint, AtkTextBoundary, gint*, gint*);
46
47 static void test_get_text_function(AtkText* text_obj, AtkGetTextFunction fn, AtkTextBoundary boundary, gint offset, const char* text_result, gint start_offset_result, gint end_offset_result)
48 {
49     gint start_offset, end_offset;
50     char* text;
51
52     text = fn(text_obj, offset, boundary, &start_offset, &end_offset);
53     g_assert_cmpstr(text, ==, text_result);
54     g_assert_cmpint(start_offset, ==, start_offset_result);
55     g_assert_cmpint(end_offset, ==, end_offset_result);
56     g_free(text);
57 }
58
59 static void run_get_text_tests(AtkText* text_obj)
60 {
61     char* text = atk_text_get_text(text_obj, 0, -1);
62     g_assert_cmpstr(text, ==, "This is a test. This is the second sentence. And this the third.");
63     g_free(text);
64
65     /* ATK_TEXT_BOUNDARY_CHAR */
66     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_CHAR,
67                            0, "T", 0, 1);
68
69     test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_CHAR,
70                            0, "h", 1, 2);
71
72     test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_CHAR,
73                            0, "", 0, 0);
74
75     test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_CHAR,
76                            1, "T", 0, 1);
77     
78     /* ATK_TEXT_BOUNDARY_WORD_START */
79     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START,
80                            0, "This ", 0, 5);
81
82     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START,
83                            4, "This ", 0, 5);
84
85     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START,
86                            10, "test. ", 10, 16);
87
88     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START,
89                            58, "third.", 58, 64);
90
91     test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_START,
92                            5, "This ", 0, 5);
93
94     test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_START,
95                            7, "This ", 0, 5);
96
97     test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_START,
98                            0, "is ", 5, 8);
99
100     test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_START,
101                            4, "is ", 5, 8);
102
103     test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_START,
104                            3, "is ", 5, 8);
105
106     /* ATK_TEXT_BOUNDARY_WORD_END */
107     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END,
108                            0, "This", 0, 4);
109
110     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END,
111                            4, " is", 4, 7);
112
113     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END,
114                            5, " is", 4, 7);
115
116     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END,
117                            9, " test", 9, 14);
118
119     test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_END,
120                            5, "This", 0, 4);
121
122     test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_END,
123                            4, "This", 0, 4);
124
125     test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_END,
126                            7, " is", 4, 7);
127
128     test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_END,
129                            5, " a", 7, 9);
130
131     test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_END,
132                            4, " a", 7, 9);
133
134     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END,
135                            58, " third", 57, 63);
136
137     /* ATK_TEXT_BOUNDARY_SENTENCE_START */
138     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_START,
139                            0, "This is a test. ", 0, 16);
140
141     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_START,
142                            15, "This is a test. ", 0, 16);
143
144     test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_SENTENCE_START,
145                            0, "This is the second sentence. ", 16, 45);
146
147     test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_SENTENCE_START,
148                            15, "This is the second sentence. ", 16, 45);
149
150     test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_START,
151                            16, "This is a test. ", 0, 16);
152
153     test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_START,
154                            44, "This is a test. ", 0, 16);
155
156     test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_START,
157                            15, "", 0, 0);
158
159     /* ATK_TEXT_BOUNDARY_SENTENCE_END */
160     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
161                            0, "This is a test.", 0, 15);
162
163     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
164                            15, " This is the second sentence.", 15, 44);
165
166     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
167                            16, " This is the second sentence.", 15, 44);
168
169     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
170                            17, " This is the second sentence.", 15, 44);
171
172     test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
173                            0, " This is the second sentence.", 15, 44);
174
175     test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
176                            15, " And this the third.", 44, 64);
177
178     test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
179                            16, "This is a test.", 0, 15);
180
181     test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
182                            15, "This is a test.", 0, 15);
183
184     test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
185                            14, "", 0, 0);
186
187     test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
188                            44, " This is the second sentence.", 15, 44);
189
190     /* It's trick to test these properly right now, since our a11y
191        implementation splits different lines in different a11y
192        items */
193     /* ATK_TEXT_BOUNDARY_LINE_START */
194     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_LINE_START,
195                            0, "This is a test. This is the second sentence. And this the third.", 0, 64);
196
197     /* ATK_TEXT_BOUNDARY_LINE_END */
198     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_LINE_END,
199                            0, "This is a test. This is the second sentence. And this the third.", 0, 64);
200 }
201
202 static void test_webkit_atk_get_text_at_offset_forms(void)
203 {
204     WebKitWebView* webView;
205     AtkObject* obj;
206     GMainLoop* loop;
207     AtkText* text_obj;
208
209     webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
210     g_object_ref_sink(webView);
211     GtkAllocation alloc = { 0, 0, 800, 600 };
212     gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc);
213     webkit_web_view_load_string(webView, contents, NULL, NULL, NULL);
214     loop = g_main_loop_new(NULL, TRUE);
215
216     g_timeout_add(100, (GSourceFunc)bail_out, loop);
217     g_main_loop_run(loop);
218
219     /* Get to the inner AtkText object */
220     obj = gtk_widget_get_accessible(GTK_WIDGET(webView));
221     g_assert(obj);
222     obj = atk_object_ref_accessible_child(obj, 0);
223     g_assert(obj);
224     obj = atk_object_ref_accessible_child(obj, 0);
225     g_assert(obj);
226
227     text_obj = ATK_TEXT(obj);
228     g_assert(ATK_IS_TEXT(text_obj));
229
230     run_get_text_tests(text_obj);
231
232     g_object_unref(webView);
233 }
234
235 static void test_webkit_atk_get_text_at_offset(void)
236 {
237     WebKitWebView* webView;
238     AtkObject* obj;
239     GMainLoop* loop;
240     AtkText* text_obj;
241
242     webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
243     g_object_ref_sink(webView);
244     GtkAllocation alloc = { 0, 0, 800, 600 };
245     gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc);
246     webkit_web_view_load_string(webView, contents, NULL, NULL, NULL);
247     loop = g_main_loop_new(NULL, TRUE);
248
249     g_timeout_add(100, (GSourceFunc)bail_out, loop);
250     g_main_loop_run(loop);
251
252     /* Get to the inner AtkText object */
253     obj = gtk_widget_get_accessible(GTK_WIDGET(webView));
254     g_assert(obj);
255     obj = atk_object_ref_accessible_child(obj, 0);
256     g_assert(obj);
257     obj = atk_object_ref_accessible_child(obj, 0);
258     g_assert(obj);
259
260     text_obj = ATK_TEXT(obj);
261     g_assert(ATK_IS_TEXT(text_obj));
262
263     run_get_text_tests(text_obj);
264
265     g_object_unref(webView);
266 }
267
268 static void test_webkit_atk_get_text_at_offset_newlines(void)
269 {
270     WebKitWebView* webView;
271     AtkObject* obj;
272     GMainLoop* loop;
273     AtkText* text_obj;
274
275     webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
276     g_object_ref_sink(webView);
277     GtkAllocation alloc = { 0, 0, 800, 600 };
278     gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc);
279     webkit_web_view_load_string(webView, contentsWithNewlines, NULL, NULL, NULL);
280     loop = g_main_loop_new(NULL, TRUE);
281
282     g_timeout_add(100, (GSourceFunc)bail_out, loop);
283     g_main_loop_run(loop);
284
285     /* Get to the inner AtkText object */
286     obj = gtk_widget_get_accessible(GTK_WIDGET(webView));
287     g_assert(obj);
288     obj = atk_object_ref_accessible_child(obj, 0);
289     g_assert(obj);
290     obj = atk_object_ref_accessible_child(obj, 0);
291     g_assert(obj);
292
293     text_obj = ATK_TEXT(obj);
294     g_assert(ATK_IS_TEXT(text_obj));
295
296     run_get_text_tests(text_obj);
297
298     g_object_unref(webView);
299 }
300
301 static void test_webkit_atk_get_text_at_offset_textarea(void)
302 {
303     WebKitWebView* webView;
304     AtkObject* obj;
305     GMainLoop* loop;
306     AtkText* text_obj;
307
308     webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
309     g_object_ref_sink(webView);
310     GtkAllocation alloc = { 0, 0, 800, 600 };
311     gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc);
312     webkit_web_view_load_string(webView, contentsInTextarea, NULL, NULL, NULL);
313     loop = g_main_loop_new(NULL, TRUE);
314
315     g_timeout_add(100, (GSourceFunc)bail_out, loop);
316     g_main_loop_run(loop);
317
318     /* Get to the inner AtkText object */
319     obj = gtk_widget_get_accessible(GTK_WIDGET(webView));
320     g_assert(obj);
321     obj = atk_object_ref_accessible_child(obj, 0);
322     g_assert(obj);
323     obj = atk_object_ref_accessible_child(obj, 0);
324     g_assert(obj);
325
326     text_obj = ATK_TEXT(obj);
327     g_assert(ATK_IS_TEXT(text_obj));
328
329     run_get_text_tests(text_obj);
330
331     g_object_unref(webView);
332 }
333
334 static void test_webkit_atk_get_text_at_offset_text_input(void)
335 {
336     WebKitWebView* webView;
337     AtkObject* obj;
338     GMainLoop* loop;
339     AtkText* text_obj;
340
341     webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
342     g_object_ref_sink(webView);
343     GtkAllocation alloc = { 0, 0, 800, 600 };
344     gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc);
345     webkit_web_view_load_string(webView, contentsInTextInput, NULL, NULL, NULL);
346     loop = g_main_loop_new(NULL, TRUE);
347
348     g_timeout_add(100, (GSourceFunc)bail_out, loop);
349     g_main_loop_run(loop);
350
351     /* Get to the inner AtkText object */
352     obj = gtk_widget_get_accessible(GTK_WIDGET(webView));
353     g_assert(obj);
354     obj = atk_object_ref_accessible_child(obj, 0);
355     g_assert(obj);
356     obj = atk_object_ref_accessible_child(obj, 0);
357     g_assert(obj);
358
359     text_obj = ATK_TEXT(obj);
360     g_assert(ATK_IS_TEXT(text_obj));
361
362     run_get_text_tests(text_obj);
363
364     g_object_unref(webView);
365 }
366
367 int main(int argc, char** argv)
368 {
369     g_thread_init(NULL);
370     gtk_test_init(&argc, &argv, NULL);
371
372     g_test_bug_base("https://bugs.webkit.org/");
373     g_test_add_func("/webkit/atk/get_text_at_offset", test_webkit_atk_get_text_at_offset);
374     g_test_add_func("/webkit/atk/get_text_at_offset_forms", test_webkit_atk_get_text_at_offset_forms);
375     g_test_add_func("/webkit/atk/get_text_at_offset_newlines", test_webkit_atk_get_text_at_offset_newlines);
376     g_test_add_func("/webkit/atk/get_text_at_offset_textarea", test_webkit_atk_get_text_at_offset_textarea);
377     g_test_add_func("/webkit/atk/get_text_at_offset_text_input", test_webkit_atk_get_text_at_offset_text_input);
378     return g_test_run ();
379 }
380
381 #else
382 int main(int argc, char** argv)
383 {
384     g_critical("You will need at least glib-2.16.0 and gtk-2.14.0 to run the unit tests. Doing nothing now.");
385     return 0;
386 }
387
388 #endif