79bf75c0bdaeed7fb14b9a0222b08152c9397fe6
[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 gboolean bail_out(GMainLoop* loop)
34 {
35     if (g_main_loop_is_running(loop))
36         g_main_loop_quit(loop);
37
38     return FALSE;
39 }
40
41 typedef gchar* (*AtkGetTextFunction) (AtkText*, gint, AtkTextBoundary, gint*, gint*);
42
43 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)
44 {
45     gint start_offset, end_offset;
46     char* text;
47
48     text = fn(text_obj, offset, boundary, &start_offset, &end_offset);
49     g_assert_cmpstr(text, ==, text_result);
50     g_assert_cmpint(start_offset, ==, start_offset_result);
51     g_assert_cmpint(end_offset, ==, end_offset_result);
52     g_free(text);
53 }
54
55 static void run_get_text_tests(AtkText* text_obj)
56 {
57     char* text = atk_text_get_text(text_obj, 0, -1);
58     g_assert_cmpstr(text, ==, "This is a test. This is the second sentence. And this the third.");
59     g_free(text);
60
61     /* ATK_TEXT_BOUNDARY_CHAR */
62     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_CHAR,
63                            0, "T", 0, 1);
64
65     test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_CHAR,
66                            0, "h", 1, 2);
67
68     test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_CHAR,
69                            0, "", 0, 0);
70
71     test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_CHAR,
72                            1, "T", 0, 1);
73     
74     /* ATK_TEXT_BOUNDARY_WORD_START */
75     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START,
76                            0, "This ", 0, 5);
77
78     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START,
79                            4, "This ", 0, 5);
80
81     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START,
82                            10, "test. ", 10, 16);
83
84     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START,
85                            58, "third.", 58, 64);
86
87     test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_START,
88                            5, "This ", 0, 5);
89
90     test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_START,
91                            7, "This ", 0, 5);
92
93     test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_START,
94                            0, "is ", 5, 8);
95
96     test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_START,
97                            4, "is ", 5, 8);
98
99     test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_START,
100                            3, "is ", 5, 8);
101
102     /* ATK_TEXT_BOUNDARY_WORD_END */
103     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END,
104                            0, "This", 0, 4);
105
106     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END,
107                            4, " is", 4, 7);
108
109     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END,
110                            5, " is", 4, 7);
111
112     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END,
113                            9, " test", 9, 14);
114
115     test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_END,
116                            5, "This", 0, 4);
117
118     test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_END,
119                            4, "This", 0, 4);
120
121     test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_END,
122                            7, " is", 4, 7);
123
124     test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_END,
125                            5, " a", 7, 9);
126
127     test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_END,
128                            4, " a", 7, 9);
129
130     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END,
131                            58, " third", 57, 63);
132
133     /* ATK_TEXT_BOUNDARY_SENTENCE_START */
134     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_START,
135                            0, "This is a test. ", 0, 16);
136
137     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_START,
138                            15, "This is a test. ", 0, 16);
139
140     test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_SENTENCE_START,
141                            0, "This is the second sentence. ", 16, 45);
142
143     test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_SENTENCE_START,
144                            15, "This is the second sentence. ", 16, 45);
145
146     test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_START,
147                            16, "This is a test. ", 0, 16);
148
149     test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_START,
150                            44, "This is a test. ", 0, 16);
151
152     test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_START,
153                            15, "", 0, 0);
154
155     /* ATK_TEXT_BOUNDARY_SENTENCE_END */
156     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
157                            0, "This is a test.", 0, 15);
158
159     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
160                            15, " This is the second sentence.", 15, 44);
161
162     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
163                            16, " This is the second sentence.", 15, 44);
164
165     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
166                            17, " This is the second sentence.", 15, 44);
167
168     test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
169                            0, " This is the second sentence.", 15, 44);
170
171     test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
172                            15, " And this the third.", 44, 64);
173
174     test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
175                            16, "This is a test.", 0, 15);
176
177     test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
178                            15, "This is a test.", 0, 15);
179
180     test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
181                            14, "", 0, 0);
182
183     test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
184                            44, " This is the second sentence.", 15, 44);
185
186     /* It's trick to test these properly right now, since our a11y
187        implementation splits different lines in different a11y
188        items */
189     /* ATK_TEXT_BOUNDARY_LINE_START */
190     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_LINE_START,
191                            0, "This is a test. This is the second sentence. And this the third.", 0, 64);
192
193     /* ATK_TEXT_BOUNDARY_LINE_END */
194     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_LINE_END,
195                            0, "This is a test. This is the second sentence. And this the third.", 0, 64);
196 }
197
198 static void test_webkit_atk_get_text_at_offset_forms(void)
199 {
200     WebKitWebView* webView;
201     AtkObject* obj;
202     GMainLoop* loop;
203     AtkText* text_obj;
204
205     webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
206     g_object_ref_sink(webView);
207     GtkAllocation alloc = { 0, 0, 800, 600 };
208     gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc);
209     webkit_web_view_load_string(webView, contents, NULL, NULL, NULL);
210     loop = g_main_loop_new(NULL, TRUE);
211
212     g_timeout_add(100, (GSourceFunc)bail_out, loop);
213     g_main_loop_run(loop);
214
215     /* Get to the inner AtkText object */
216     obj = gtk_widget_get_accessible(GTK_WIDGET(webView));
217     g_assert(obj);
218     obj = atk_object_ref_accessible_child(obj, 0);
219     g_assert(obj);
220     obj = atk_object_ref_accessible_child(obj, 0);
221     g_assert(obj);
222
223     text_obj = ATK_TEXT(obj);
224     g_assert(ATK_IS_TEXT(text_obj));
225
226     run_get_text_tests(text_obj);
227
228     g_object_unref(webView);
229 }
230
231 static void test_webkit_atk_get_text_at_offset(void)
232 {
233     WebKitWebView* webView;
234     AtkObject* obj;
235     GMainLoop* loop;
236     AtkText* text_obj;
237
238     webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
239     g_object_ref_sink(webView);
240     GtkAllocation alloc = { 0, 0, 800, 600 };
241     gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc);
242     webkit_web_view_load_string(webView, contents, NULL, NULL, NULL);
243     loop = g_main_loop_new(NULL, TRUE);
244
245     g_timeout_add(100, (GSourceFunc)bail_out, loop);
246     g_main_loop_run(loop);
247
248     /* Get to the inner AtkText object */
249     obj = gtk_widget_get_accessible(GTK_WIDGET(webView));
250     g_assert(obj);
251     obj = atk_object_ref_accessible_child(obj, 0);
252     g_assert(obj);
253     obj = atk_object_ref_accessible_child(obj, 0);
254     g_assert(obj);
255
256     text_obj = ATK_TEXT(obj);
257     g_assert(ATK_IS_TEXT(text_obj));
258
259     run_get_text_tests(text_obj);
260
261     g_object_unref(webView);
262 }
263
264 static void test_webkit_atk_get_text_at_offset_newlines(void)
265 {
266     WebKitWebView* webView;
267     AtkObject* obj;
268     GMainLoop* loop;
269     AtkText* text_obj;
270
271     webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
272     g_object_ref_sink(webView);
273     GtkAllocation alloc = { 0, 0, 800, 600 };
274     gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc);
275     webkit_web_view_load_string(webView, contentsWithNewlines, NULL, NULL, NULL);
276     loop = g_main_loop_new(NULL, TRUE);
277
278     g_timeout_add(100, (GSourceFunc)bail_out, loop);
279     g_main_loop_run(loop);
280
281     /* Get to the inner AtkText object */
282     obj = gtk_widget_get_accessible(GTK_WIDGET(webView));
283     g_assert(obj);
284     obj = atk_object_ref_accessible_child(obj, 0);
285     g_assert(obj);
286     obj = atk_object_ref_accessible_child(obj, 0);
287     g_assert(obj);
288
289     text_obj = ATK_TEXT(obj);
290     g_assert(ATK_IS_TEXT(text_obj));
291
292     run_get_text_tests(text_obj);
293
294     g_object_unref(webView);
295 }
296
297 int main(int argc, char** argv)
298 {
299     g_thread_init(NULL);
300     gtk_test_init(&argc, &argv, NULL);
301
302     g_test_bug_base("https://bugs.webkit.org/");
303     g_test_add_func("/webkit/atk/get_text_at_offset", test_webkit_atk_get_text_at_offset);
304     g_test_add_func("/webkit/atk/get_text_at_offset_forms", test_webkit_atk_get_text_at_offset_forms);
305     g_test_add_func("/webkit/atk/get_text_at_offset_newlines", test_webkit_atk_get_text_at_offset_newlines);
306     return g_test_run ();
307 }
308
309 #else
310 int main(int argc, char** argv)
311 {
312     g_critical("You will need at least glib-2.16.0 and gtk-2.14.0 to run the unit tests. Doing nothing now.");
313     return 0;
314 }
315
316 #endif