diff options
Diffstat (limited to 'Source/WebKit/gtk/tests')
31 files changed, 6729 insertions, 0 deletions
diff --git a/Source/WebKit/gtk/tests/resources/blank.ico b/Source/WebKit/gtk/tests/resources/blank.ico Binary files differnew file mode 100644 index 0000000..ea848b9 --- /dev/null +++ b/Source/WebKit/gtk/tests/resources/blank.ico diff --git a/Source/WebKit/gtk/tests/resources/test.html b/Source/WebKit/gtk/tests/resources/test.html new file mode 100644 index 0000000..98f7d4f --- /dev/null +++ b/Source/WebKit/gtk/tests/resources/test.html @@ -0,0 +1,6 @@ +<html> +<head><title>test</title></head> +<body>test</body> +</html>></head> +<body>test</body> +</html> diff --git a/Source/WebKit/gtk/tests/resources/test.ogg b/Source/WebKit/gtk/tests/resources/test.ogg Binary files differnew file mode 100644 index 0000000..7f3a3b9 --- /dev/null +++ b/Source/WebKit/gtk/tests/resources/test.ogg diff --git a/Source/WebKit/gtk/tests/resources/test.pdf b/Source/WebKit/gtk/tests/resources/test.pdf Binary files differnew file mode 100644 index 0000000..2424c19 --- /dev/null +++ b/Source/WebKit/gtk/tests/resources/test.pdf diff --git a/Source/WebKit/gtk/tests/resources/test.txt b/Source/WebKit/gtk/tests/resources/test.txt new file mode 100644 index 0000000..9daeafb --- /dev/null +++ b/Source/WebKit/gtk/tests/resources/test.txt @@ -0,0 +1 @@ +test diff --git a/Source/WebKit/gtk/tests/test_utils.c b/Source/WebKit/gtk/tests/test_utils.c new file mode 100644 index 0000000..646fd25 --- /dev/null +++ b/Source/WebKit/gtk/tests/test_utils.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2010 Arno Renevier + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "test_utils.h" + +#include <glib.h> +#include <glib/gstdio.h> + +int testutils_relative_chdir(const gchar* target_filename, const gchar* executable_path) +{ + if (g_path_is_absolute(executable_path)) { + if (g_chdir(g_path_get_dirname(executable_path))) { + return -1; + } + } + + while (!g_file_test(target_filename, G_FILE_TEST_EXISTS)) { + gchar *path_name; + if (g_chdir("..")) { + return -1; + } + g_assert(!g_str_equal((path_name = g_get_current_dir()), "/")); + g_free(path_name); + } + + gchar* dirname = g_path_get_dirname(target_filename); + if (g_chdir(dirname)) { + g_free(dirname); + return -1; + } + + g_free(dirname); + return 0; +} diff --git a/Source/WebKit/gtk/tests/test_utils.h b/Source/WebKit/gtk/tests/test_utils.h new file mode 100644 index 0000000..e761f74 --- /dev/null +++ b/Source/WebKit/gtk/tests/test_utils.h @@ -0,0 +1,3 @@ +#include <glib.h> + +int testutils_relative_chdir(const gchar*, const gchar*); diff --git a/Source/WebKit/gtk/tests/testatk.c b/Source/WebKit/gtk/tests/testatk.c new file mode 100644 index 0000000..1ee6c55 --- /dev/null +++ b/Source/WebKit/gtk/tests/testatk.c @@ -0,0 +1,1345 @@ +/* + * Copyright (C) 2009 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <errno.h> +#include <glib.h> +#include <glib/gstdio.h> +#include <gtk/gtk.h> +#include <unistd.h> +#include <webkit/webkit.h> + +#if GTK_CHECK_VERSION(2, 14, 0) + +static const char* centeredContents = "<html><body><p style='text-align: center;'>Short line</p><p style='text-align: center;'>Long-size line with some foo bar baz content</p><p style='text-align: center;'>Short line</p><p style='text-align: center;'>This is a multi-line paragraph<br />where the first line<br />is the biggest one</p></body></html>"; + +static const char* contents = "<html><body><p>This is a test. This is the second sentence. And this the third.</p></body></html>"; + +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>"; + +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>"; + +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>"; + +static const char* contentsInParagraphAndBodySimple = "<html><body><p>This is a test.</p>Hello world.</body></html>"; + +static const char* contentsInParagraphAndBodyModerate = "<html><body><p>This is a test.</p>Hello world.<br /><font color='#00cc00'>This sentence is green.</font><br />This one is not.</body></html>"; + +static const char* contentsInTable = "<html><body><table><tr><td>foo</td><td>bar</td></tr></table></body></html>"; + +static const char* contentsInTableWithHeaders = "<html><body><table><tr><th>foo</th><th>bar</th><th colspan='2'>baz</th></tr><tr><th>qux</th><td>1</td><td>2</td><td>3</td></tr><tr><th rowspan='2'>quux</th><td>4</td><td>5</td><td>6</td></tr><tr><td>6</td><td>7</td><td>8</td></tr><tr><th>corge</th><td>9</td><td>10</td><td>11</td></tr></table><table><tr><td>1</td><td>2</td></tr><tr><td>3</td><td>4</td></tr></table></body></html>"; + +static const char* comboBoxSelector = "<html><body><select><option selected value='foo'>foo</option><option value='bar'>bar</option></select></body></html>"; + +static const char* formWithTextInputs = "<html><body><form><input type='text' name='entry' /></form></body></html>"; + +static const char* hypertextAndHyperlinks = "<html><body><p>A paragraph with no links at all</p><p><a href='http://foo.bar.baz/'>A line</a> with <a href='http://bar.baz.foo/'>a link in the middle</a> as well as at the beginning and <a href='http://baz.foo.bar/'>at the end</a></p></body></html>"; + +static const char* layoutAndDataTables = "<html><body><table><tr><th>Odd</th><th>Even</th></tr><tr><td>1</td><td>2</td></tr></table><table><tr><td>foo</td><td>bar</td></tr></table></body></html>"; + +static const char* linksWithInlineImages = "<html><head><style>a.http:before {content: url(no-image.png);}</style><body><p><a class='http' href='foo'>foo</a> bar baz</p><p>foo <a class='http' href='bar'>bar</a> baz</p><p>foo bar <a class='http' href='baz'>baz</a></p></body></html>"; + +static const char* listsOfItems = "<html><body><ul><li>text only</li><li><a href='foo'>link only</a></li><li>text and a <a href='bar'>link</a></li></ul><ol><li>text only</li><li><a href='foo'>link only</a></li><li>text and a <a href='bar'>link</a></li></ol></body></html>"; + +static const char* textForSelections = "<html><body><p>A paragraph with plain text</p><p>A paragraph with <a href='http://webkit.org'>a link</a> in the middle</p></body></html>"; + +static const char* textWithAttributes = "<html><head><style>.st1 {font-family: monospace; color:rgb(120,121,122);} .st2 {text-decoration:underline; background-color:rgb(80,81,82);}</style></head><body><p style=\"font-size:14; text-align:right;\">This is the <i>first</i><b> sentence of this text.</b></p><p class=\"st1\">This sentence should have an style applied <span class=\"st2\">and this part should have another one</span>.</p><p>x<sub>1</sub><sup>2</sup>=x<sub>2</sub><sup>3</sup></p><p style=\"text-align:center;\">This sentence is the <strike>last</strike> one.</p></body></html>"; + +static void waitForAccessibleObjects() +{ + /* Manually spin the main context to make sure the accessible + objects are properly created before continuing. */ + while (g_main_context_pending(0)) + g_main_context_iteration(0, TRUE); +} + +typedef gchar* (*AtkGetTextFunction) (AtkText*, gint, AtkTextBoundary, gint*, gint*); + +static void testGetTextFunction(AtkText* textObject, AtkGetTextFunction fn, AtkTextBoundary boundary, gint offset, const char* textResult, gint startOffsetResult, gint endOffsetResult) +{ + gint startOffset; + gint endOffset; + char* text = fn(textObject, offset, boundary, &startOffset, &endOffset); + g_assert_cmpstr(text, ==, textResult); + g_assert_cmpint(startOffset, ==, startOffsetResult); + g_assert_cmpint(endOffset, ==, endOffsetResult); + g_free(text); +} + +static void runGetTextTests(AtkText* textObject) +{ + char* text = atk_text_get_text(textObject, 0, -1); + g_assert_cmpstr(text, ==, "This is a test. This is the second sentence. And this the third."); + g_free(text); + + /* ATK_TEXT_BOUNDARY_CHAR */ + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_CHAR, + 0, "T", 0, 1); + + testGetTextFunction(textObject, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_CHAR, + 0, "h", 1, 2); + + testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_CHAR, + 0, "", 0, 0); + + testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_CHAR, + 1, "T", 0, 1); + + /* ATK_TEXT_BOUNDARY_WORD_START */ + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START, + 0, "This ", 0, 5); + + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START, + 4, "This ", 0, 5); + + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START, + 10, "test. ", 10, 16); + + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START, + 58, "third.", 58, 64); + + testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_START, + 5, "This ", 0, 5); + + testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_START, + 7, "This ", 0, 5); + + testGetTextFunction(textObject, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_START, + 0, "is ", 5, 8); + + testGetTextFunction(textObject, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_START, + 4, "is ", 5, 8); + + testGetTextFunction(textObject, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_START, + 3, "is ", 5, 8); + + /* ATK_TEXT_BOUNDARY_WORD_END */ + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END, + 0, "This", 0, 4); + + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END, + 4, " is", 4, 7); + + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END, + 5, " is", 4, 7); + + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END, + 9, " test", 9, 14); + + testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_END, + 5, "This", 0, 4); + + testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_END, + 4, "This", 0, 4); + + testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_END, + 7, " is", 4, 7); + + testGetTextFunction(textObject, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_END, + 5, " a", 7, 9); + + testGetTextFunction(textObject, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_END, + 4, " a", 7, 9); + + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END, + 58, " third", 57, 63); + + /* ATK_TEXT_BOUNDARY_SENTENCE_START */ + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_START, + 0, "This is a test. ", 0, 16); + + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_START, + 15, "This is a test. ", 0, 16); + + testGetTextFunction(textObject, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_SENTENCE_START, + 0, "This is the second sentence. ", 16, 45); + + testGetTextFunction(textObject, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_SENTENCE_START, + 15, "This is the second sentence. ", 16, 45); + + testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_START, + 16, "This is a test. ", 0, 16); + + testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_START, + 44, "This is a test. ", 0, 16); + + testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_START, + 15, "", 0, 0); + + /* ATK_TEXT_BOUNDARY_SENTENCE_END */ + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, + 0, "This is a test.", 0, 15); + + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, + 15, " This is the second sentence.", 15, 44); + + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, + 16, " This is the second sentence.", 15, 44); + + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, + 17, " This is the second sentence.", 15, 44); + + testGetTextFunction(textObject, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, + 0, " This is the second sentence.", 15, 44); + + testGetTextFunction(textObject, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, + 15, " And this the third.", 44, 64); + + testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, + 16, "This is a test.", 0, 15); + + testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, + 15, "This is a test.", 0, 15); + + testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, + 14, "", 0, 0); + + testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, + 44, " This is the second sentence.", 15, 44); + + /* It's trick to test these properly right now, since our a11y + implementation splits different lines in different a11y items. */ + /* ATK_TEXT_BOUNDARY_LINE_START */ + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_LINE_START, + 0, "This is a test. This is the second sentence. And this the third.", 0, 64); + + /* ATK_TEXT_BOUNDARY_LINE_END */ + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_LINE_END, + 0, "This is a test. This is the second sentence. And this the third.", 0, 64); +} + +static void testWebkitAtkComboBox() +{ + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(webView); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, comboBoxSelector, 0, 0, 0); + + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); + + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); + + AtkObject* formObject = atk_object_ref_accessible_child(object, 0); + g_assert(formObject); + + AtkObject* comboBox = atk_object_ref_accessible_child(formObject, 0); + g_assert(ATK_IS_OBJECT(comboBox)); + + AtkObject* menuPopup = atk_object_ref_accessible_child(comboBox, 0); + g_assert(ATK_IS_OBJECT(menuPopup)); + + AtkObject* item1 = atk_object_ref_accessible_child(menuPopup, 0); + g_assert(ATK_IS_OBJECT(item1)); + + AtkObject* item2 = atk_object_ref_accessible_child(menuPopup, 1); + g_assert(ATK_IS_OBJECT(item2)); + + /* Check roles. */ + g_assert(atk_object_get_role(comboBox) == ATK_ROLE_COMBO_BOX); + g_assert(atk_object_get_role(menuPopup) == ATK_ROLE_MENU); + g_assert(atk_object_get_role(item1) == ATK_ROLE_MENU_ITEM); + g_assert(atk_object_get_role(item2) == ATK_ROLE_MENU_ITEM); + + /* Check the implementation of the AtkSelection interface. */ + g_assert(ATK_IS_SELECTION(comboBox)); + AtkSelection* atkSelection = ATK_SELECTION(comboBox); + g_assert_cmpint(atk_selection_get_selection_count(atkSelection), ==, 1); + g_assert(atk_selection_is_child_selected(atkSelection, 0)); + g_assert(!atk_selection_is_child_selected(atkSelection, 1)); + AtkObject* selectedItem = atk_selection_ref_selection(atkSelection, 0); + g_assert(selectedItem == item1); + g_object_unref(selectedItem); + + /* Check the implementations of the AtkAction interface. */ + g_assert(ATK_IS_ACTION(comboBox)); + AtkAction* atkAction = ATK_ACTION(comboBox); + g_assert_cmpint(atk_action_get_n_actions(atkAction), ==, 1); + g_assert(atk_action_do_action(atkAction, 0)); + + g_assert(ATK_IS_ACTION(menuPopup)); + atkAction = ATK_ACTION(menuPopup); + g_assert_cmpint(atk_action_get_n_actions(atkAction), ==, 1); + g_assert(atk_action_do_action(atkAction, 0)); + + g_assert(ATK_IS_ACTION(item1)); + atkAction = ATK_ACTION(item1); + g_assert_cmpint(atk_action_get_n_actions(atkAction), ==, 1); + g_assert(atk_action_do_action(atkAction, 0)); + + g_assert(ATK_IS_ACTION(item2)); + atkAction = ATK_ACTION(item2); + g_assert_cmpint(atk_action_get_n_actions(atkAction), ==, 1); + g_assert(atk_action_do_action(atkAction, 0)); + + /* After selecting the second item, selection should have changed. */ + g_assert_cmpint(atk_selection_get_selection_count(atkSelection), ==, 1); + g_assert(!atk_selection_is_child_selected(atkSelection, 0)); + g_assert(atk_selection_is_child_selected(atkSelection, 1)); + selectedItem = atk_selection_ref_selection(atkSelection, 0); + g_assert(selectedItem == item2); + g_object_unref(selectedItem); + + /* Check the implementation of the AtkText interface. */ + g_assert(ATK_IS_TEXT(item1)); + AtkText* atkText = ATK_TEXT(item1); + char *text = atk_text_get_text(atkText, 0, -1); + g_assert_cmpstr(text, ==, "foo"); + g_free(text); + text = atk_text_get_text(atkText, 0, 2); + g_assert_cmpstr(text, ==, "fo"); + g_free(text); + + g_assert(ATK_IS_TEXT(item2)); + atkText = ATK_TEXT(item2); + text = atk_text_get_text(atkText, 0, -1); + g_assert_cmpstr(text, ==, "bar"); + g_free(text); + text = atk_text_get_text(atkText, 1, 3); + g_assert_cmpstr(text, ==, "ar"); + g_free(text); + + g_object_unref(formObject); + g_object_unref(comboBox); + g_object_unref(menuPopup); + g_object_unref(item1); + g_object_unref(item2); + g_object_unref(webView); +} + +static void testWebkitAtkGetTextAtOffsetForms() +{ + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(webView); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, contents, 0, 0, 0); + + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); + + /* Get to the inner AtkText object. */ + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); + object = atk_object_ref_accessible_child(object, 0); + g_assert(object); + + AtkText* textObject = ATK_TEXT(object); + g_assert(ATK_IS_TEXT(textObject)); + + runGetTextTests(textObject); + + g_object_unref(webView); +} + +static void testWebkitAtkGetTextAtOffset() +{ + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(webView); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, contents, 0, 0, 0); + + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); + + /* Get to the inner AtkText object. */ + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); + object = atk_object_ref_accessible_child(object, 0); + g_assert(object); + + AtkText* textObject = ATK_TEXT(object); + g_assert(ATK_IS_TEXT(textObject)); + + runGetTextTests(textObject); + + g_object_unref(webView); +} + +static void testWebkitAtkGetTextAtOffsetNewlines() +{ + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(webView); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, contentsWithNewlines, 0, 0, 0); + + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); + + /* Get to the inner AtkText object. */ + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); + object = atk_object_ref_accessible_child(object, 0); + g_assert(object); + + AtkText* textObject = ATK_TEXT(object); + g_assert(ATK_IS_TEXT(textObject)); + + runGetTextTests(textObject); + + g_object_unref(webView); +} + +static void testWebkitAtkGetTextAtOffsetTextarea() +{ + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(webView); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, contentsInTextarea, 0, 0, 0); + + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); + + /* Get to the inner AtkText object. */ + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); + object = atk_object_ref_accessible_child(object, 0); + g_assert(object); + object = atk_object_ref_accessible_child(object, 0); + g_assert(object); + + AtkText* textObject = ATK_TEXT(object); + g_assert(ATK_IS_TEXT(textObject)); + + runGetTextTests(textObject); + + g_object_unref(webView); +} + +static void testWebkitAtkGetTextAtOffsetTextInput() +{ + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(webView); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, contentsInTextInput, 0, 0, 0); + + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); + + /* Get to the inner AtkText object. */ + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); + object = atk_object_ref_accessible_child(object, 0); + g_assert(object); + object = atk_object_ref_accessible_child(object, 0); + g_assert(object); + + AtkText* textObject = ATK_TEXT(object); + g_assert(ATK_IS_TEXT(textObject)); + + runGetTextTests(textObject); + + g_object_unref(webView); +} + +static void testWebkitAtkGetTextInParagraphAndBodySimple() +{ + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(webView); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, contentsInParagraphAndBodySimple, 0, 0, 0); + + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); + + /* Get to the inner AtkText object. */ + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); + AtkObject* object1 = atk_object_ref_accessible_child(object, 0); + g_assert(object1); + AtkObject* object2 = atk_object_ref_accessible_child(object, 1); + g_assert(object2); + + AtkText* textObject1 = ATK_TEXT(object1); + g_assert(ATK_IS_TEXT(textObject1)); + AtkText* textObject2 = ATK_TEXT(object2); + g_assert(ATK_IS_TEXT(textObject2)); + + char *text = atk_text_get_text(textObject1, 0, -1); + g_assert_cmpstr(text, ==, "This is a test."); + + text = atk_text_get_text(textObject2, 0, 12); + g_assert_cmpstr(text, ==, "Hello world."); + + g_object_unref(object1); + g_object_unref(object2); + g_object_unref(webView); +} + +static void testWebkitAtkGetTextInParagraphAndBodyModerate() +{ + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(webView); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, contentsInParagraphAndBodyModerate, 0, 0, 0); + + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); + + /* Get to the inner AtkText object. */ + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); + AtkObject* object1 = atk_object_ref_accessible_child(object, 0); + g_assert(object1); + AtkObject* object2 = atk_object_ref_accessible_child(object, 1); + g_assert(object2); + + AtkText* textObject1 = ATK_TEXT(object1); + g_assert(ATK_IS_TEXT(textObject1)); + AtkText* textObject2 = ATK_TEXT(object2); + g_assert(ATK_IS_TEXT(textObject2)); + + char *text = atk_text_get_text(textObject1, 0, -1); + g_assert_cmpstr(text, ==, "This is a test."); + + text = atk_text_get_text(textObject2, 0, 53); + g_assert_cmpstr(text, ==, "Hello world.\nThis sentence is green.\nThis one is not."); + + g_object_unref(object1); + g_object_unref(object2); + g_object_unref(webView); +} + +static void testWebkitAtkGetTextInTable() +{ + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(webView); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, contentsInTable, 0, 0, 0); + + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); + + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); + object = atk_object_ref_accessible_child(object, 0); + g_assert(object); + + /* Tables should not implement AtkText. */ + g_assert(!G_TYPE_INSTANCE_GET_INTERFACE(object, ATK_TYPE_TEXT, AtkTextIface)); + + g_object_unref(object); + g_object_unref(webView); +} + +static void testWebkitAtkGetHeadersInTable() +{ + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(webView); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, contentsInTableWithHeaders, 0, 0, 0); + + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); + + AtkObject* axWebView = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(axWebView); + + /* Check table with both column and row headers. */ + AtkObject* table = atk_object_ref_accessible_child(axWebView, 0); + g_assert(table); + g_assert(atk_object_get_role(table) == ATK_ROLE_TABLE); + + AtkObject* colHeader = atk_table_get_column_header(ATK_TABLE(table), 0); + g_assert(colHeader); + g_assert(atk_object_get_role(colHeader) == ATK_ROLE_TABLE_CELL); + g_assert(atk_object_get_index_in_parent(colHeader) == 0); + + colHeader = atk_table_get_column_header(ATK_TABLE(table), 1); + g_assert(colHeader); + g_assert(atk_object_get_role(colHeader) == ATK_ROLE_TABLE_CELL); + g_assert(atk_object_get_index_in_parent(colHeader) == 1); + + colHeader = atk_table_get_column_header(ATK_TABLE(table), 2); + g_assert(colHeader); + g_assert(atk_object_get_role(colHeader) == ATK_ROLE_TABLE_CELL); + g_assert(atk_object_get_index_in_parent(colHeader) == 2); + + colHeader = atk_table_get_column_header(ATK_TABLE(table), 3); + g_assert(colHeader); + g_assert(atk_object_get_role(colHeader) == ATK_ROLE_TABLE_CELL); + g_assert(atk_object_get_index_in_parent(colHeader) == 2); + + AtkObject* rowHeader = atk_table_get_row_header(ATK_TABLE(table), 0); + g_assert(rowHeader); + g_assert(atk_object_get_role(rowHeader) == ATK_ROLE_TABLE_CELL); + g_assert(atk_object_get_index_in_parent(rowHeader) == 0); + + rowHeader = atk_table_get_row_header(ATK_TABLE(table), 1); + g_assert(rowHeader); + g_assert(atk_object_get_role(rowHeader) == ATK_ROLE_TABLE_CELL); + g_assert(atk_object_get_index_in_parent(rowHeader) == 3); + + rowHeader = atk_table_get_row_header(ATK_TABLE(table), 2); + g_assert(rowHeader); + g_assert(atk_object_get_role(rowHeader) == ATK_ROLE_TABLE_CELL); + g_assert(atk_object_get_index_in_parent(rowHeader) == 7); + + rowHeader = atk_table_get_row_header(ATK_TABLE(table), 3); + g_assert(rowHeader); + g_assert(atk_object_get_role(rowHeader) == ATK_ROLE_TABLE_CELL); + g_assert(atk_object_get_index_in_parent(rowHeader) == 7); + + g_object_unref(table); + + /* Check table with no headers at all. */ + table = atk_object_ref_accessible_child(axWebView, 1); + g_assert(table); + g_assert(atk_object_get_role(table) == ATK_ROLE_TABLE); + + colHeader = atk_table_get_column_header(ATK_TABLE(table), 0); + g_assert(colHeader == 0); + + colHeader = atk_table_get_column_header(ATK_TABLE(table), 1); + g_assert(colHeader == 0); + + rowHeader = atk_table_get_row_header(ATK_TABLE(table), 0); + g_assert(rowHeader == 0); + + rowHeader = atk_table_get_row_header(ATK_TABLE(table), 1); + g_assert(rowHeader == 0); + + g_object_unref(table); + g_object_unref(webView); +} + +static gint compAtkAttribute(AtkAttribute* a1, AtkAttribute* a2) +{ + gint strcmpVal = g_strcmp0(a1->name, a2->name); + if (strcmpVal) + return strcmpVal; + return g_strcmp0(a1->value, a2->value); +} + +static gint compAtkAttributeName(AtkAttribute* a1, AtkAttribute* a2) +{ + return g_strcmp0(a1->name, a2->name); +} + +static gboolean atkAttributeSetAttributeNameHasValue(AtkAttributeSet* set, const gchar* attributeName, const gchar* value) +{ + AtkAttribute at; + at.name = (gchar*)attributeName; + GSList* element = g_slist_find_custom(set, &at, (GCompareFunc)compAtkAttributeName); + return element && !g_strcmp0(((AtkAttribute*)(element->data))->value, value); +} + +static gboolean atkAttributeSetContainsAttributeName(AtkAttributeSet* set, const gchar* attributeName) +{ + AtkAttribute at; + at.name = (gchar*)attributeName; + return g_slist_find_custom(set, &at, (GCompareFunc)compAtkAttributeName) ? true : false; +} + +static gboolean atkAttributeSetAttributeHasValue(AtkAttributeSet* set, AtkTextAttribute attribute, const gchar* value) +{ + return atkAttributeSetAttributeNameHasValue(set, atk_text_attribute_get_name(attribute), value); +} + +static gboolean atkAttributeSetAreEqual(AtkAttributeSet* set1, AtkAttributeSet* set2) +{ + if (!set1) + return !set2; + + set1 = g_slist_sort(set1, (GCompareFunc)compAtkAttribute); + set2 = g_slist_sort(set2, (GCompareFunc)compAtkAttribute); + + while (set1) { + if (!set2 || compAtkAttribute(set1->data, set2->data)) + return FALSE; + + set1 = set1->next; + set2 = set2->next; + } + + return (!set2); +} + +static void testWebkitAtkTextAttributes() +{ + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(webView); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, textWithAttributes, 0, 0, 0); + + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); + + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); + + AtkObject* child = atk_object_ref_accessible_child(object, 0); + g_assert(child && ATK_IS_TEXT(child)); + AtkText* childText = ATK_TEXT(child); + + gint startOffset; + gint endOffset; + AtkAttributeSet* set1 = atk_text_get_run_attributes(childText, 0, &startOffset, &endOffset); + g_assert_cmpint(startOffset, ==, 0); + g_assert_cmpint(endOffset, ==, 12); + g_assert(atkAttributeSetAreEqual(set1, 0)); + + AtkAttributeSet* set2 = atk_text_get_run_attributes(childText, 15, &startOffset, &endOffset); + g_assert_cmpint(startOffset, ==, 12); + g_assert_cmpint(endOffset, ==, 17); + g_assert(atkAttributeSetAttributeHasValue(set2, ATK_TEXT_ATTR_STYLE, "italic")); + + AtkAttributeSet* set3 = atk_text_get_run_attributes(childText, 17, &startOffset, &endOffset); + g_assert_cmpint(startOffset, ==, 17); + g_assert_cmpint(endOffset, ==, 40); + g_assert(atkAttributeSetAttributeHasValue(set3, ATK_TEXT_ATTR_WEIGHT, "700")); + + AtkAttributeSet* set4 = atk_text_get_default_attributes(childText); + g_assert(atkAttributeSetAttributeHasValue(set4, ATK_TEXT_ATTR_STYLE, "normal")); + g_assert(atkAttributeSetAttributeHasValue(set4, ATK_TEXT_ATTR_JUSTIFICATION, "right")); + g_assert(atkAttributeSetAttributeHasValue(set4, ATK_TEXT_ATTR_SIZE, "14")); + atk_attribute_set_free(set1); + atk_attribute_set_free(set2); + atk_attribute_set_free(set3); + atk_attribute_set_free(set4); + + child = atk_object_ref_accessible_child(object, 1); + g_assert(child && ATK_IS_TEXT(child)); + childText = ATK_TEXT(child); + + set1 = atk_text_get_default_attributes(childText); + g_assert(atkAttributeSetAttributeHasValue(set1, ATK_TEXT_ATTR_FAMILY_NAME, "monospace")); + g_assert(atkAttributeSetAttributeHasValue(set1, ATK_TEXT_ATTR_STYLE, "normal")); + g_assert(atkAttributeSetAttributeHasValue(set1, ATK_TEXT_ATTR_STRIKETHROUGH, "false")); + g_assert(atkAttributeSetAttributeHasValue(set1, ATK_TEXT_ATTR_WEIGHT, "400")); + g_assert(atkAttributeSetAttributeHasValue(set1, ATK_TEXT_ATTR_FG_COLOR, "120,121,122")); + + set2 = atk_text_get_run_attributes(childText, 43, &startOffset, &endOffset); + g_assert_cmpint(startOffset, ==, 43); + g_assert_cmpint(endOffset, ==, 80); + /* Checks that default attributes of text are not returned when called to atk_text_get_run_attributes. */ + g_assert(!atkAttributeSetAttributeHasValue(set2, ATK_TEXT_ATTR_FG_COLOR, "120,121,122")); + g_assert(atkAttributeSetAttributeHasValue(set2, ATK_TEXT_ATTR_UNDERLINE, "single")); + g_assert(atkAttributeSetAttributeHasValue(set2, ATK_TEXT_ATTR_BG_COLOR, "80,81,82")); + atk_attribute_set_free(set1); + atk_attribute_set_free(set2); + + child = atk_object_ref_accessible_child(object, 2); + g_assert(child && ATK_IS_TEXT(child)); + childText = ATK_TEXT(child); + + set1 = atk_text_get_run_attributes(childText, 0, &startOffset, &endOffset); + set2 = atk_text_get_run_attributes(childText, 3, &startOffset, &endOffset); + g_assert(atkAttributeSetAreEqual(set1, set2)); + atk_attribute_set_free(set2); + + set2 = atk_text_get_run_attributes(childText, 1, &startOffset, &endOffset); + set3 = atk_text_get_run_attributes(childText, 5, &startOffset, &endOffset); + g_assert(atkAttributeSetAreEqual(set2, set3)); + g_assert(!atkAttributeSetAreEqual(set1, set2)); + atk_attribute_set_free(set3); + + set3 = atk_text_get_run_attributes(childText, 2, &startOffset, &endOffset); + set4 = atk_text_get_run_attributes(childText, 6, &startOffset, &endOffset); + g_assert(atkAttributeSetAreEqual(set3, set4)); + g_assert(!atkAttributeSetAreEqual(set1, set3)); + g_assert(!atkAttributeSetAreEqual(set2, set3)); + atk_attribute_set_free(set1); + atk_attribute_set_free(set2); + atk_attribute_set_free(set3); + atk_attribute_set_free(set4); + + child = atk_object_ref_accessible_child(object, 3); + g_assert(child && ATK_IS_TEXT(child)); + childText = ATK_TEXT(child); + set1 = atk_text_get_run_attributes(childText, 24, &startOffset, &endOffset); + g_assert_cmpint(startOffset, ==, 21); + g_assert_cmpint(endOffset, ==, 25); + g_assert(atkAttributeSetAttributeHasValue(set1, ATK_TEXT_ATTR_STRIKETHROUGH, "true")); + + set2 = atk_text_get_run_attributes(childText, 25, &startOffset, &endOffset); + g_assert_cmpint(startOffset, ==, 25); + g_assert_cmpint(endOffset, ==, 30); + g_assert(atkAttributeSetAreEqual(set2, 0)); + + set3 = atk_text_get_default_attributes(childText); + g_assert(atkAttributeSetAttributeHasValue(set3, ATK_TEXT_ATTR_JUSTIFICATION, "center")); + atk_attribute_set_free(set1); + atk_attribute_set_free(set2); + atk_attribute_set_free(set3); +} + +static void testWebkitAtkTextSelections() +{ + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(webView); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, textForSelections, 0, 0, 0); + + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); + + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); + + AtkText* paragraph1 = ATK_TEXT(atk_object_ref_accessible_child(object, 0)); + g_assert(ATK_IS_TEXT(paragraph1)); + AtkText* paragraph2 = ATK_TEXT(atk_object_ref_accessible_child(object, 1)); + g_assert(ATK_IS_TEXT(paragraph2)); + AtkText* link = ATK_TEXT(atk_object_ref_accessible_child(ATK_OBJECT(paragraph2), 0)); + g_assert(ATK_IS_TEXT(link)); + + /* First paragraph (simple text). */ + + /* Basic initial checks. */ + g_assert_cmpint(atk_text_get_n_selections(paragraph1), ==, 0); + + gint startOffset; + gint endOffset; + gchar* selectedText = atk_text_get_selection(paragraph1, 0, &startOffset, &endOffset); + g_assert_cmpint(startOffset, ==, 0); + g_assert_cmpint(endOffset, ==, 0); + g_assert_cmpstr(selectedText, ==, 0); + g_free (selectedText); + + /* Try removing a non existing (yet) selection. */ + gboolean result = atk_text_remove_selection(paragraph1, 0); + g_assert(!result); + + /* Try setting a 0-char selection. */ + result = atk_text_set_selection(paragraph1, 0, 5, 5); + g_assert(result); + + /* Make a selection and test it. */ + result = atk_text_set_selection(paragraph1, 0, 5, 25); + g_assert(result); + g_assert_cmpint(atk_text_get_n_selections(paragraph1), ==, 1); + selectedText = atk_text_get_selection(paragraph1, 0, &startOffset, &endOffset); + g_assert_cmpint(startOffset, ==, 5); + g_assert_cmpint(endOffset, ==, 25); + g_assert_cmpstr(selectedText, ==, "agraph with plain te"); + g_free (selectedText); + /* Try removing the selection from other AtkText object (should fail). */ + result = atk_text_remove_selection(paragraph2, 0); + g_assert(!result); + + /* Remove the selection and test everything again. */ + result = atk_text_remove_selection(paragraph1, 0); + g_assert(result); + g_assert_cmpint(atk_text_get_n_selections(paragraph1), ==, 0); + selectedText = atk_text_get_selection(paragraph1, 0, &startOffset, &endOffset); + /* Now offsets should be the same, set to the last position of the caret. */ + g_assert_cmpint(startOffset, ==, endOffset); + g_assert_cmpint(startOffset, ==, 25); + g_assert_cmpint(endOffset, ==, 25); + g_assert_cmpstr(selectedText, ==, 0); + g_free (selectedText); + + /* Second paragraph (text + link + text). */ + + /* Set a selection partially covering the link and test it. */ + result = atk_text_set_selection(paragraph2, 0, 7, 21); + g_assert(result); + + /* Test the paragraph first. */ + g_assert_cmpint(atk_text_get_n_selections(paragraph2), ==, 1); + selectedText = atk_text_get_selection(paragraph2, 0, &startOffset, &endOffset); + g_assert_cmpint(startOffset, ==, 7); + g_assert_cmpint(endOffset, ==, 21); + g_assert_cmpstr(selectedText, ==, "raph with a li"); + g_free (selectedText); + + /* Now test just the link. */ + g_assert_cmpint(atk_text_get_n_selections(link), ==, 1); + selectedText = atk_text_get_selection(link, 0, &startOffset, &endOffset); + g_assert_cmpint(startOffset, ==, 0); + g_assert_cmpint(endOffset, ==, 4); + g_assert_cmpstr(selectedText, ==, "a li"); + g_free (selectedText); + + /* Make a selection after the link and check selection for the whole paragraph. */ + result = atk_text_set_selection(paragraph2, 0, 27, 37); + g_assert(result); + g_assert_cmpint(atk_text_get_n_selections(paragraph2), ==, 1); + selectedText = atk_text_get_selection(paragraph2, 0, &startOffset, &endOffset); + g_assert_cmpint(startOffset, ==, 27); + g_assert_cmpint(endOffset, ==, 37); + g_assert_cmpstr(selectedText, ==, "the middle"); + g_free (selectedText); + + /* Remove selections and text everything again. */ + result = atk_text_remove_selection(paragraph2, 0); + g_assert(result); + g_assert_cmpint(atk_text_get_n_selections(paragraph2), ==, 0); + selectedText = atk_text_get_selection(paragraph2, 0, &startOffset, &endOffset); + /* Now offsets should be the same (no selection). */ + g_assert_cmpint(startOffset, ==, endOffset); + g_assert_cmpstr(selectedText, ==, 0); + g_free (selectedText); + + g_assert_cmpint(atk_text_get_n_selections(link), ==, 0); + selectedText = atk_text_get_selection(link, 0, &startOffset, &endOffset); + /* Now offsets should be the same (no selection). */ + g_assert_cmpint(startOffset, ==, endOffset); + g_assert_cmpstr(selectedText, ==, 0); + g_free (selectedText); + + g_object_unref(paragraph1); + g_object_unref(paragraph2); + g_object_unref(webView); +} + +static void testWebkitAtkGetExtents() +{ + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(webView); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, centeredContents, 0, 0, 0); + + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); + + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); + + AtkText* shortText1 = ATK_TEXT(atk_object_ref_accessible_child(object, 0)); + g_assert(ATK_IS_TEXT(shortText1)); + AtkText* longText = ATK_TEXT(atk_object_ref_accessible_child(object, 1)); + g_assert(ATK_IS_TEXT(longText)); + AtkText* shortText2 = ATK_TEXT(atk_object_ref_accessible_child(object, 2)); + g_assert(ATK_IS_TEXT(shortText2)); + AtkText* multilineText = ATK_TEXT(atk_object_ref_accessible_child(object, 3)); + g_assert(ATK_IS_TEXT(multilineText)); + + /* Start with window extents. */ + AtkTextRectangle sline_window1, sline_window2, lline_window, mline_window; + atk_text_get_range_extents(shortText1, 0, 10, ATK_XY_WINDOW, &sline_window1); + atk_text_get_range_extents(longText, 0, 44, ATK_XY_WINDOW, &lline_window); + atk_text_get_range_extents(shortText2, 0, 10, ATK_XY_WINDOW, &sline_window2); + atk_text_get_range_extents(multilineText, 0, 60, ATK_XY_WINDOW, &mline_window); + + /* Check vertical line position. */ + g_assert_cmpint(sline_window1.y + sline_window1.height, <=, lline_window.y); + g_assert_cmpint(lline_window.y + lline_window.height + sline_window2.height, <=, mline_window.y); + + /* Paragraphs 1 and 3 have identical text and alignment. */ + g_assert_cmpint(sline_window1.x, ==, sline_window2.x); + g_assert_cmpint(sline_window1.width, ==, sline_window2.width); + g_assert_cmpint(sline_window1.height, ==, sline_window2.height); + + /* All lines should be the same height; line 2 is the widest line. */ + g_assert_cmpint(sline_window1.height, ==, lline_window.height); + g_assert_cmpint(sline_window1.width, <, lline_window.width); + + /* Make sure the character extents jive with the range extents. */ + gint x; + gint y; + gint width; + gint height; + + /* First paragraph (short text). */ + atk_text_get_character_extents(shortText1, 0, &x, &y, &width, &height, ATK_XY_WINDOW); + g_assert_cmpint(x, ==, sline_window1.x); + g_assert_cmpint(y, ==, sline_window1.y); + g_assert_cmpint(height, ==, sline_window1.height); + + atk_text_get_character_extents(shortText1, 9, &x, &y, &width, &height, ATK_XY_WINDOW); + g_assert_cmpint(x, ==, sline_window1.x + sline_window1.width - width); + g_assert_cmpint(y, ==, sline_window1.y); + g_assert_cmpint(height, ==, sline_window1.height); + + /* Second paragraph (long text). */ + atk_text_get_character_extents(longText, 0, &x, &y, &width, &height, ATK_XY_WINDOW); + g_assert_cmpint(x, ==, lline_window.x); + g_assert_cmpint(y, ==, lline_window.y); + g_assert_cmpint(height, ==, lline_window.height); + + atk_text_get_character_extents(longText, 43, &x, &y, &width, &height, ATK_XY_WINDOW); + g_assert_cmpint(x, ==, lline_window.x + lline_window.width - width); + g_assert_cmpint(y, ==, lline_window.y); + g_assert_cmpint(height, ==, lline_window.height); + + /* Third paragraph (short text). */ + atk_text_get_character_extents(shortText2, 0, &x, &y, &width, &height, ATK_XY_WINDOW); + g_assert_cmpint(x, ==, sline_window2.x); + g_assert_cmpint(y, ==, sline_window2.y); + g_assert_cmpint(height, ==, sline_window2.height); + + atk_text_get_character_extents(shortText2, 9, &x, &y, &width, &height, ATK_XY_WINDOW); + g_assert_cmpint(x, ==, sline_window2.x + sline_window2.width - width); + g_assert_cmpint(y, ==, sline_window2.y); + g_assert_cmpint(height, ==, sline_window2.height); + + /* Four paragraph (3 lines multi-line text). */ + atk_text_get_character_extents(multilineText, 0, &x, &y, &width, &height, ATK_XY_WINDOW); + g_assert_cmpint(x, ==, mline_window.x); + g_assert_cmpint(y, ==, mline_window.y); + g_assert_cmpint(3 * height, ==, mline_window.height); + + atk_text_get_character_extents(multilineText, 59, &x, &y, &width, &height, ATK_XY_WINDOW); + /* Last line won't fill the whole width of the rectangle. */ + g_assert_cmpint(x, <=, mline_window.x + mline_window.width - width); + g_assert_cmpint(y, ==, mline_window.y + mline_window.height - height); + g_assert_cmpint(height, <=, mline_window.height); + + g_object_unref(shortText1); + g_object_unref(shortText2); + g_object_unref(longText); + g_object_unref(multilineText); + g_object_unref(webView); +} + +static void testWebkitAtkLayoutAndDataTables() +{ + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(webView); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, layoutAndDataTables, 0, 0, 0); + + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); + + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); + + /* Check the non-layout table (data table). */ + + AtkObject* table1 = atk_object_ref_accessible_child(object, 0); + g_assert(ATK_IS_TABLE(table1)); + AtkAttributeSet* set1 = atk_object_get_attributes(table1); + g_assert(set1); + g_assert(!atkAttributeSetContainsAttributeName(set1, "layout-guess")); + atk_attribute_set_free(set1); + + /* Check the layout table. */ + + AtkObject* table2 = atk_object_ref_accessible_child(object, 1); + g_assert(ATK_IS_TABLE(table2)); + AtkAttributeSet* set2 = atk_object_get_attributes(table2); + g_assert(set2); + g_assert(atkAttributeSetContainsAttributeName(set2, "layout-guess")); + g_assert(atkAttributeSetAttributeNameHasValue(set2, "layout-guess", "true")); + atk_attribute_set_free(set2); + + g_object_unref(table1); + g_object_unref(table2); + g_object_unref(webView); +} + +static void testWebkitAtkLinksWithInlineImages() +{ + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(webView); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, linksWithInlineImages, 0, 0, 0); + + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); + + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); + + /* First paragraph (link at the beginning). */ + AtkObject* paragraph = atk_object_ref_accessible_child(object, 0); + g_assert(ATK_IS_TEXT(paragraph)); + gint startOffset; + gint endOffset; + gchar* text = atk_text_get_text_at_offset(ATK_TEXT(paragraph), 0, ATK_TEXT_BOUNDARY_LINE_START, &startOffset, &endOffset); + g_assert(text); + g_assert_cmpstr(text, ==, "foo bar baz"); + g_assert_cmpint(startOffset, ==, 0); + g_assert_cmpint(endOffset, ==, 11); + g_free(text); + g_object_unref(paragraph); + + /* Second paragraph (link in the middle). */ + paragraph = atk_object_ref_accessible_child(object, 1); + g_assert(ATK_IS_TEXT(paragraph)); + text = atk_text_get_text_at_offset(ATK_TEXT(paragraph), 0, ATK_TEXT_BOUNDARY_LINE_START, &startOffset, &endOffset); + g_assert(text); + g_assert_cmpstr(text, ==, "foo bar baz"); + g_assert_cmpint(startOffset, ==, 0); + g_assert_cmpint(endOffset, ==, 11); + g_free(text); + g_object_unref(paragraph); + + /* Third paragraph (link at the end). */ + paragraph = atk_object_ref_accessible_child(object, 2); + g_assert(ATK_IS_TEXT(paragraph)); + text = atk_text_get_text_at_offset(ATK_TEXT(paragraph), 0, ATK_TEXT_BOUNDARY_LINE_START, &startOffset, &endOffset); + g_assert(text); + g_assert_cmpstr(text, ==, "foo bar baz"); + g_assert_cmpint(startOffset, ==, 0); + g_assert_cmpint(endOffset, ==, 11); + g_free(text); + g_object_unref(paragraph); + + g_object_unref(webView); +} + +static void testWebkitAtkHypertextAndHyperlinks() +{ + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(webView); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, hypertextAndHyperlinks, 0, 0, 0); + + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); + + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); + + AtkObject* paragraph1 = atk_object_ref_accessible_child(object, 0); + g_assert(ATK_OBJECT(paragraph1)); + g_assert(atk_object_get_role(paragraph1) == ATK_ROLE_PARAGRAPH); + g_assert(ATK_IS_HYPERTEXT(paragraph1)); + + /* No links in the first paragraph. */ + gint nLinks = atk_hypertext_get_n_links(ATK_HYPERTEXT(paragraph1)); + g_assert_cmpint(nLinks, ==, 0); + + AtkObject* paragraph2 = atk_object_ref_accessible_child(object, 1); + g_assert(ATK_OBJECT(paragraph2)); + g_assert(atk_object_get_role(paragraph2) == ATK_ROLE_PARAGRAPH); + g_assert(ATK_IS_HYPERTEXT(paragraph2)); + + /* Check links in the second paragraph. + nLinks = atk_hypertext_get_n_links(ATK_HYPERTEXT(paragraph2)); + g_assert_cmpint(nLinks, ==, 3); */ + + AtkHyperlink* hLink1 = atk_hypertext_get_link(ATK_HYPERTEXT(paragraph2), 0); + g_assert(ATK_HYPERLINK(hLink1)); + AtkObject* hLinkObject1 = atk_hyperlink_get_object(hLink1, 0); + g_assert(ATK_OBJECT(hLinkObject1)); + g_assert(atk_object_get_role(hLinkObject1) == ATK_ROLE_LINK); + g_assert_cmpint(atk_hyperlink_get_start_index(hLink1), ==, 0); + g_assert_cmpint(atk_hyperlink_get_end_index(hLink1), ==, 6); + g_assert_cmpint(atk_hyperlink_get_n_anchors(hLink1), ==, 1); + g_assert_cmpstr(atk_hyperlink_get_uri(hLink1, 0), ==, "http://foo.bar.baz/"); + + AtkHyperlink* hLink2 = atk_hypertext_get_link(ATK_HYPERTEXT(paragraph2), 1); + g_assert(ATK_HYPERLINK(hLink2)); + AtkObject* hLinkObject2 = atk_hyperlink_get_object(hLink2, 0); + g_assert(ATK_OBJECT(hLinkObject2)); + g_assert(atk_object_get_role(hLinkObject2) == ATK_ROLE_LINK); + g_assert_cmpint(atk_hyperlink_get_start_index(hLink2), ==, 12); + g_assert_cmpint(atk_hyperlink_get_end_index(hLink2), ==, 32); + g_assert_cmpint(atk_hyperlink_get_n_anchors(hLink2), ==, 1); + g_assert_cmpstr(atk_hyperlink_get_uri(hLink2, 0), ==, "http://bar.baz.foo/"); + + AtkHyperlink* hLink3 = atk_hypertext_get_link(ATK_HYPERTEXT(paragraph2), 2); + g_assert(ATK_HYPERLINK(hLink3)); + AtkObject* hLinkObject3 = atk_hyperlink_get_object(hLink3, 0); + g_assert(ATK_OBJECT(hLinkObject3)); + g_assert(atk_object_get_role(hLinkObject3) == ATK_ROLE_LINK); + g_assert_cmpint(atk_hyperlink_get_start_index(hLink3), ==, 65); + g_assert_cmpint(atk_hyperlink_get_end_index(hLink3), ==, 75); + g_assert_cmpint(atk_hyperlink_get_n_anchors(hLink3), ==, 1); + g_assert_cmpstr(atk_hyperlink_get_uri(hLink3, 0), ==, "http://baz.foo.bar/"); + + /* Finally check the AtkAction interface for a given AtkHyperlink. */ + g_assert(ATK_IS_ACTION(hLink1)); + g_assert_cmpint(atk_action_get_n_actions(ATK_ACTION(hLink1)), ==, 1); + g_assert_cmpstr(atk_action_get_keybinding(ATK_ACTION(hLink1), 0), ==, ""); + g_assert_cmpstr(atk_action_get_name(ATK_ACTION(hLink1), 0), ==, "jump"); + g_assert(atk_action_do_action(ATK_ACTION(hLink1), 0)); + + g_object_unref(paragraph1); + g_object_unref(paragraph2); + g_object_unref(webView); +} + +static void testWebkitAtkListsOfItems() +{ + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(webView); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, listsOfItems, 0, 0, 0); + + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); + + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); + + /* Unordered list. */ + + AtkObject* uList = atk_object_ref_accessible_child(object, 0); + g_assert(ATK_OBJECT(uList)); + g_assert(atk_object_get_role(uList) == ATK_ROLE_LIST); + g_assert_cmpint(atk_object_get_n_accessible_children(uList), ==, 3); + + AtkObject* item1 = atk_object_ref_accessible_child(uList, 0); + g_assert(ATK_IS_TEXT(item1)); + AtkObject* item2 = atk_object_ref_accessible_child(uList, 1); + g_assert(ATK_IS_TEXT(item2)); + AtkObject* item3 = atk_object_ref_accessible_child(uList, 2); + g_assert(ATK_IS_TEXT(item3)); + + g_assert_cmpint(atk_object_get_n_accessible_children(item1), ==, 0); + g_assert_cmpint(atk_object_get_n_accessible_children(item2), ==, 1); + g_assert_cmpint(atk_object_get_n_accessible_children(item3), ==, 1); + + g_assert_cmpstr(atk_text_get_text(ATK_TEXT(item1), 0, -1), ==, "\342\200\242 text only"); + g_assert_cmpstr(atk_text_get_text(ATK_TEXT(item2), 0, -1), ==, "\342\200\242 link only"); + g_assert_cmpstr(atk_text_get_text(ATK_TEXT(item3), 0, -1), ==, "\342\200\242 text and a link"); + + g_object_unref(item1); + g_object_unref(item2); + g_object_unref(item3); + + /* Ordered list. */ + + AtkObject* oList = atk_object_ref_accessible_child(object, 1); + g_assert(ATK_OBJECT(oList)); + g_assert(atk_object_get_role(oList) == ATK_ROLE_LIST); + g_assert_cmpint(atk_object_get_n_accessible_children(oList), ==, 3); + + item1 = atk_object_ref_accessible_child(oList, 0); + g_assert(ATK_IS_TEXT(item1)); + item2 = atk_object_ref_accessible_child(oList, 1); + g_assert(ATK_IS_TEXT(item2)); + item3 = atk_object_ref_accessible_child(oList, 2); + g_assert(ATK_IS_TEXT(item3)); + + g_assert_cmpstr(atk_text_get_text(ATK_TEXT(item1), 0, -1), ==, "1. text only"); + g_assert_cmpstr(atk_text_get_text(ATK_TEXT(item2), 0, -1), ==, "2. link only"); + g_assert_cmpstr(atk_text_get_text(ATK_TEXT(item3), 0, -1), ==, "3. text and a link"); + + g_assert_cmpint(atk_object_get_n_accessible_children(item1), ==, 0); + g_assert_cmpint(atk_object_get_n_accessible_children(item2), ==, 1); + g_assert_cmpint(atk_object_get_n_accessible_children(item3), ==, 1); + + g_object_unref(item1); + g_object_unref(item2); + g_object_unref(item3); + + g_object_unref(uList); + g_object_unref(oList); + g_object_unref(webView); +} + +static gboolean textInserted = FALSE; +static gboolean textDeleted = FALSE; + +static void textChangedCb(AtkText* text, gint pos, gint len, const gchar* detail) +{ + g_assert(text && ATK_IS_OBJECT(text)); + + if (!g_strcmp0(detail, "insert")) + textInserted = TRUE; + else if (!g_strcmp0(detail, "delete")) + textDeleted = TRUE; +} + +static gboolean checkTextChanges(gpointer unused) +{ + g_assert_cmpint(textInserted, ==, TRUE); + g_assert_cmpint(textDeleted, ==, TRUE); + return FALSE; +} + +static void testWebkitAtkTextChangedNotifications() +{ + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(webView); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, formWithTextInputs, 0, 0, 0); + + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); + + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); + + AtkObject* form = atk_object_ref_accessible_child(object, 0); + g_assert(ATK_IS_OBJECT(form)); + + AtkObject* textEntry = atk_object_ref_accessible_child(form, 0); + g_assert(ATK_IS_EDITABLE_TEXT(textEntry)); + g_assert(atk_object_get_role(ATK_OBJECT(textEntry)) == ATK_ROLE_ENTRY); + + g_signal_connect(textEntry, "text-changed::insert", + G_CALLBACK(textChangedCb), + (gpointer)"insert"); + g_signal_connect(textEntry, "text-changed::delete", + G_CALLBACK(textChangedCb), + (gpointer)"delete"); + + gint pos = 0; + atk_editable_text_insert_text(ATK_EDITABLE_TEXT(textEntry), "foo bar baz", 11, &pos); + atk_editable_text_delete_text(ATK_EDITABLE_TEXT(textEntry), 4, 7); + textInserted = FALSE; + textDeleted = FALSE; + + g_idle_add((GSourceFunc)checkTextChanges, 0); + + g_object_unref(form); + g_object_unref(textEntry); + g_object_unref(webView); +} + +int main(int argc, char** argv) +{ + g_thread_init(0); + gtk_test_init(&argc, &argv, 0); + + g_test_bug_base("https://bugs.webkit.org/"); + g_test_add_func("/webkit/atk/comboBox", testWebkitAtkComboBox); + g_test_add_func("/webkit/atk/getTextAtOffset", testWebkitAtkGetTextAtOffset); + g_test_add_func("/webkit/atk/getTextAtOffsetForms", testWebkitAtkGetTextAtOffsetForms); + g_test_add_func("/webkit/atk/getTextAtOffsetNewlines", testWebkitAtkGetTextAtOffsetNewlines); + g_test_add_func("/webkit/atk/getTextAtOffsetTextarea", testWebkitAtkGetTextAtOffsetTextarea); + g_test_add_func("/webkit/atk/getTextAtOffsetTextInput", testWebkitAtkGetTextAtOffsetTextInput); + g_test_add_func("/webkit/atk/getTextInParagraphAndBodySimple", testWebkitAtkGetTextInParagraphAndBodySimple); + g_test_add_func("/webkit/atk/getTextInParagraphAndBodyModerate", testWebkitAtkGetTextInParagraphAndBodyModerate); + g_test_add_func("/webkit/atk/getTextInTable", testWebkitAtkGetTextInTable); + g_test_add_func("/webkit/atk/getHeadersInTable", testWebkitAtkGetHeadersInTable); + g_test_add_func("/webkit/atk/textAttributes", testWebkitAtkTextAttributes); + g_test_add_func("/webkit/atk/textSelections", testWebkitAtkTextSelections); + g_test_add_func("/webkit/atk/getExtents", testWebkitAtkGetExtents); + g_test_add_func("/webkit/atk/hypertextAndHyperlinks", testWebkitAtkHypertextAndHyperlinks); + g_test_add_func("/webkit/atk/layoutAndDataTables", testWebkitAtkLayoutAndDataTables); + g_test_add_func("/webkit/atk/linksWithInlineImages", testWebkitAtkLinksWithInlineImages); + g_test_add_func("/webkit/atk/listsOfItems", testWebkitAtkListsOfItems); + g_test_add_func("/webkit/atk/textChangedNotifications", testWebkitAtkTextChangedNotifications); + return g_test_run (); +} + +#else +int main(int argc, char** argv) +{ + g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now."); + return 0; +} + +#endif diff --git a/Source/WebKit/gtk/tests/testatkroles.c b/Source/WebKit/gtk/tests/testatkroles.c new file mode 100644 index 0000000..5ad6b5f --- /dev/null +++ b/Source/WebKit/gtk/tests/testatkroles.c @@ -0,0 +1,428 @@ +/* + * Copyright © 2010 Joanmarie Diggs + * Copyright © 2010 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <glib.h> +#include <glib/gstdio.h> +#include <gtk/gtk.h> +#include <webkit/webkit.h> + +#if GTK_CHECK_VERSION(2, 14, 0) + +/* Non form roles */ +#define HTML_DOCUMENT_FRAME "<html><body>This is a test.</body></html>" +#define HTML_HEADING "<html><body><h1>1</h1><h2>2</h2><h3>3</h3><h4>4</h4><h5>5</h5><h6>6</h6></body></html>" +#define HTML_IMAGE "<html><body><img src='foobar.png' alt='This is a test.'/></body></html>" +#define HTML_LINK_TEXT "<html><body><a href='foobar.html'>This is a test.</a></body></html>" +#define HTML_LIST "<html><body><ul><li>1</li><li>2</li></ul><ol><li>1</li><li>2</li></ol></body></html>" +#define HTML_PARAGRAPH "<html><body><p>This is a test.</p></body></html>" +#define HTML_SECTION "<html><body><div>This is a test.</div></body></html>" +#define HTML_TABLE "<html><body><table border='1'><tr><td>This is</td><td>a test.</td></tr></table></body></html>" +#define HTML_SEPARATOR "<html><body><hr/></body></html>" +#define HTML_COMBOBOX "<html><body><select size='1'><option>one</option><option>two</option><option>three</option></select></body></html>" +/* Form roles */ +#define HTML_FORM "<html><body><form>This is a test.</form></body></html>" +#define HTML_CHECK_BOX "<html><body><input type='checkbox' />This is a test.</body></html>" +#define HTML_LABELED_ENTRY "<html><body><label for='foo'>Name:</label><input type='text' id='foo' /></body></html>" +#define HTML_LISTBOX "<html><body><select size='3'><option>one</option><option>two</option><option>three</option></select></body></html>" +#define HTML_PASSWORD_TEXT "<html><body><input type='password' /></body></html>" +#define HTML_PUSH_BUTTON "<html><body><input type='submit' value='ok' />This is a test.</body></html>" +#define HTML_RADIO_BUTTON "<html><body><input type='radio' />This is a test.</body></html>" + +typedef struct { + AtkObject* documentFrame; + AtkObject* obj; + AtkRole role; + GtkWidget* webView; + GtkAllocation alloc; + GMainLoop* loop; +} AtkRolesFixture; + +static gboolean finish_loading(AtkRolesFixture* fixture) +{ + if (g_main_loop_is_running(fixture->loop)) + g_main_loop_quit(fixture->loop); + + fixture->documentFrame = gtk_widget_get_accessible(fixture->webView); + g_assert(fixture->documentFrame); + + return FALSE; +} + +static void atk_roles_fixture_setup(AtkRolesFixture* fixture, gconstpointer data) +{ + fixture->loop = g_main_loop_new(NULL, TRUE); + fixture->alloc = (GtkAllocation) { 0, 0, 800, 600 }; + fixture->webView = webkit_web_view_new(); + g_object_ref_sink(fixture->webView); + + gtk_widget_size_allocate(fixture->webView, &fixture->alloc); + + if (data != NULL) + webkit_web_view_load_string(WEBKIT_WEB_VIEW (fixture->webView), (const char*) data, NULL, NULL, NULL); + + g_idle_add((GSourceFunc) finish_loading, fixture); + g_main_loop_run(fixture->loop); +} + +static void atk_roles_fixture_teardown(AtkRolesFixture* fixture, gconstpointer data) +{ + g_object_unref(fixture->webView); + g_main_loop_unref(fixture->loop); +} + +static void get_child_and_test_role(AtkObject* obj, gint pos, AtkRole role) +{ + AtkObject* child; + AtkRole child_role; + + child = atk_object_ref_accessible_child(obj, pos); + g_assert(child); + child_role = atk_object_get_role(child); + g_assert(child_role == role); + + g_object_unref(child); +} + +static void test_webkit_atk_get_role_document_frame(AtkRolesFixture* fixture, gconstpointer data) +{ + fixture->role = atk_object_get_role(fixture->documentFrame); + g_assert(fixture->role == ATK_ROLE_DOCUMENT_FRAME); +} + +static void test_webkit_atk_get_role_heading(AtkRolesFixture* fixture, gconstpointer data) +{ + get_child_and_test_role(fixture->documentFrame, 0, ATK_ROLE_HEADING); + get_child_and_test_role(fixture->documentFrame, 1, ATK_ROLE_HEADING); + get_child_and_test_role(fixture->documentFrame, 2, ATK_ROLE_HEADING); + get_child_and_test_role(fixture->documentFrame, 3, ATK_ROLE_HEADING); + get_child_and_test_role(fixture->documentFrame, 4, ATK_ROLE_HEADING); + get_child_and_test_role(fixture->documentFrame, 5, ATK_ROLE_HEADING); +} + +static void test_webkit_atk_get_role_image(AtkRolesFixture* fixture, gconstpointer data) +{ + // This is an extraneous object of ATK_ROLE_PANEL which we should get rid of. + fixture->obj = atk_object_ref_accessible_child(fixture->documentFrame, 0); + g_assert(fixture->obj); + + get_child_and_test_role(fixture->obj, 0, ATK_ROLE_IMAGE); + + g_object_unref(fixture->obj); +} + +static void test_webkit_atk_get_role_link(AtkRolesFixture* fixture, gconstpointer data) +{ + // This is an extraneous object of ATK_ROLE_PANEL which we should get rid of. + fixture->obj = atk_object_ref_accessible_child(fixture->documentFrame, 0); + g_assert(fixture->obj); + + get_child_and_test_role(fixture->obj, 0, ATK_ROLE_LINK); + + g_object_unref(fixture->obj); +} + +static void test_webkit_atk_get_role_list_and_item(AtkRolesFixture* fixture, gconstpointer data) +{ + AtkObject* listObj; + + listObj = atk_object_ref_accessible_child(fixture->documentFrame, 0); + g_assert(listObj); + fixture->role = atk_object_get_role(listObj); + g_assert(fixture->role == ATK_ROLE_LIST); + + get_child_and_test_role(listObj, 0, ATK_ROLE_LIST_ITEM); + get_child_and_test_role(listObj, 1, ATK_ROLE_LIST_ITEM); + g_object_unref(listObj); + + listObj = atk_object_ref_accessible_child(fixture->documentFrame, 1); + g_assert(listObj); + fixture->role = atk_object_get_role(listObj); + g_assert(fixture->role == ATK_ROLE_LIST); + + get_child_and_test_role(listObj, 0, ATK_ROLE_LIST_ITEM); + get_child_and_test_role(listObj, 1, ATK_ROLE_LIST_ITEM); + g_object_unref(listObj); +} + +static void test_webkit_atk_get_role_paragraph(AtkRolesFixture* fixture, gconstpointer data) +{ + get_child_and_test_role(fixture->documentFrame, 0, ATK_ROLE_PARAGRAPH); +} + +static void test_webkit_atk_get_role_section(AtkRolesFixture* fixture, gconstpointer data) +{ + get_child_and_test_role(fixture->documentFrame, 0, ATK_ROLE_SECTION); +} + +// Does not yet test table cells because of bug 30895. +static void test_webkit_atk_get_role_table(AtkRolesFixture* fixture, gconstpointer data) +{ + get_child_and_test_role(fixture->documentFrame, 0, ATK_ROLE_TABLE); +} + +static void test_webkit_atk_get_role_separator(AtkRolesFixture *fixture, gconstpointer data) +{ + get_child_and_test_role(fixture->documentFrame, 0, ATK_ROLE_SEPARATOR); +} + +static void test_webkit_atk_get_role_combobox(AtkRolesFixture *fixture, gconstpointer data) +{ + AtkObject* comboboxMenu; + + // This is an extraneous object of ATK_ROLE_PANEL which we should get rid of. + fixture->obj = atk_object_ref_accessible_child(fixture->documentFrame, 0); + g_assert(fixture->obj); + + fixture->obj = atk_object_ref_accessible_child(fixture->obj, 0); + g_assert(fixture->obj); + fixture->role = atk_object_get_role(fixture->obj); + g_assert(fixture->role == ATK_ROLE_COMBO_BOX); + + comboboxMenu = atk_object_ref_accessible_child(fixture->obj, 0); + g_assert(comboboxMenu); + fixture->role = atk_object_get_role(comboboxMenu); + g_assert(fixture->role == ATK_ROLE_MENU); + + get_child_and_test_role(comboboxMenu, 0, ATK_ROLE_MENU_ITEM); + get_child_and_test_role(comboboxMenu, 1, ATK_ROLE_MENU_ITEM); + get_child_and_test_role(comboboxMenu, 2, ATK_ROLE_MENU_ITEM); + + g_object_unref(fixture->obj); + g_object_unref(comboboxMenu); +} + +/* Form roles */ +static void test_webkit_atk_get_role_form(AtkRolesFixture *fixture, gconstpointer data) +{ + get_child_and_test_role(fixture->documentFrame, 0, ATK_ROLE_FORM); +} + +static void test_webkit_atk_get_role_check_box(AtkRolesFixture* fixture, gconstpointer data) +{ + // This is an extraneous object of ATK_ROLE_PANEL which we should get rid of. + fixture->obj = atk_object_ref_accessible_child(fixture->documentFrame, 0); + g_assert(fixture->obj); + + get_child_and_test_role(fixture->obj, 0, ATK_ROLE_CHECK_BOX); + + g_object_unref(fixture->obj); +} + +static void test_webkit_atk_get_role_entry(AtkRolesFixture* fixture, gconstpointer data) +{ + // This is an extraneous object of ATK_ROLE_PANEL which we should get rid of. + fixture->obj = atk_object_ref_accessible_child(fixture->documentFrame, 0); + g_assert(fixture->obj); + + get_child_and_test_role(fixture->obj, 1, ATK_ROLE_ENTRY); + + g_object_unref(fixture->obj); +} + +static void test_webkit_atk_get_role_label(AtkRolesFixture* fixture, gconstpointer data) +{ + // This is an extraneous object of ATK_ROLE_PANEL which we should get rid of. + fixture->obj = atk_object_ref_accessible_child(fixture->documentFrame, 0); + g_assert(fixture->obj); + + get_child_and_test_role(fixture->obj, 0, ATK_ROLE_LABEL); + + g_object_unref(fixture->obj); +} + +static void test_webkit_atk_get_role_listbox(AtkRolesFixture* fixture, gconstpointer data) +{ + AtkObject* listboxObj; + // This is an extraneous object of ATK_ROLE_PANEL which we should get rid of. + fixture->obj = atk_object_ref_accessible_child(fixture->documentFrame, 0); + g_assert(fixture->obj); + + listboxObj = atk_object_ref_accessible_child(fixture->obj, 0); + g_assert(listboxObj); + fixture->role = atk_object_get_role(listboxObj); + g_assert(fixture->role == ATK_ROLE_LIST); + + get_child_and_test_role(listboxObj, 0, ATK_ROLE_LIST_ITEM); + get_child_and_test_role(listboxObj, 1, ATK_ROLE_LIST_ITEM); + get_child_and_test_role(listboxObj, 2, ATK_ROLE_LIST_ITEM); + + g_object_unref(fixture->obj); + g_object_unref(listboxObj); +} + +static void test_webkit_atk_get_role_password_text(AtkRolesFixture* fixture, gconstpointer data) +{ + // This is an extraneous object of ATK_ROLE_PANEL which we should get rid of. + fixture->obj = atk_object_ref_accessible_child(fixture->documentFrame, 0); + g_assert(fixture->obj); + + get_child_and_test_role(fixture->obj, 0, ATK_ROLE_PASSWORD_TEXT); + + g_object_unref(fixture->obj); +} + +static void test_webkit_atk_get_role_push_button(AtkRolesFixture* fixture, gconstpointer data) +{ + // This is an extraneous object of ATK_ROLE_PANEL which we should get rid of. + fixture->obj = atk_object_ref_accessible_child(fixture->documentFrame, 0); + g_assert(fixture->obj); + + get_child_and_test_role(fixture->obj, 0, ATK_ROLE_PUSH_BUTTON); + + g_object_unref(fixture->obj); +} + +static void test_webkit_atk_get_role_radio_button(AtkRolesFixture* fixture, gconstpointer data) +{ + // This is an extraneous object of ATK_ROLE_PANEL which we should get rid of. + fixture->obj = atk_object_ref_accessible_child(fixture->documentFrame, 0); + g_assert(fixture->obj); + + get_child_and_test_role(fixture->obj, 0, ATK_ROLE_RADIO_BUTTON); + + g_object_unref(fixture->obj); +} + +int main(int argc, char** argv) +{ + g_thread_init(NULL); + gtk_test_init(&argc, &argv, NULL); + + g_test_bug_base("https://bugs.webkit.org/"); + + g_test_add("/webkit/atk/test_webkit_atk_get_role_document_frame", + AtkRolesFixture, HTML_DOCUMENT_FRAME, + atk_roles_fixture_setup, + test_webkit_atk_get_role_document_frame, + atk_roles_fixture_teardown); + + g_test_add("/webkit/atk/test_webkit_atk_get_role_heading", + AtkRolesFixture, HTML_HEADING, + atk_roles_fixture_setup, + test_webkit_atk_get_role_heading, + atk_roles_fixture_teardown); + + g_test_add("/webkit/atk/test_webkit_atk_get_role_image", + AtkRolesFixture, HTML_IMAGE, + atk_roles_fixture_setup, + test_webkit_atk_get_role_image, + atk_roles_fixture_teardown); + + g_test_add("/webkit/atk/test_webkit_atk_get_role_link", + AtkRolesFixture, HTML_LINK_TEXT, + atk_roles_fixture_setup, + test_webkit_atk_get_role_link, + atk_roles_fixture_teardown); + + g_test_add("/webkit/atk/test_webkit_atk_get_role_list_and_item", + AtkRolesFixture, HTML_LIST, + atk_roles_fixture_setup, + test_webkit_atk_get_role_list_and_item, + atk_roles_fixture_teardown); + + g_test_add("/webkit/atk/test_webkit_atk_get_role_paragraph", + AtkRolesFixture, HTML_PARAGRAPH, + atk_roles_fixture_setup, + test_webkit_atk_get_role_paragraph, + atk_roles_fixture_teardown); + + g_test_add("/webkit/atk/test_webkit_atk_get_role_section", + AtkRolesFixture, HTML_SECTION, + atk_roles_fixture_setup, + test_webkit_atk_get_role_section, + atk_roles_fixture_teardown); + + g_test_add("/webkit/atk/test_webkit_atk_get_role_table", + AtkRolesFixture, HTML_TABLE, + atk_roles_fixture_setup, + test_webkit_atk_get_role_table, + atk_roles_fixture_teardown); + + g_test_add("/webkit/atk/test_webkit_atk_get_role_separator", + AtkRolesFixture, HTML_SEPARATOR, + atk_roles_fixture_setup, + test_webkit_atk_get_role_separator, + atk_roles_fixture_teardown); + + g_test_add("/webkit/atk/test_webkit_atk_get_role_combobox", + AtkRolesFixture, HTML_COMBOBOX, + atk_roles_fixture_setup, + test_webkit_atk_get_role_combobox, + atk_roles_fixture_teardown); + + /* Form roles */ + g_test_add("/webkit/atk/test_webkit_atk_get_role_form", + AtkRolesFixture, HTML_FORM, + atk_roles_fixture_setup, + test_webkit_atk_get_role_form, + atk_roles_fixture_teardown); + g_test_add("/webkit/atk/test_webkit_atk_get_role_check_box", + AtkRolesFixture, HTML_CHECK_BOX, + atk_roles_fixture_setup, + test_webkit_atk_get_role_check_box, + atk_roles_fixture_teardown); + + g_test_add("/webkit/atk/test_webkit_atk_get_role_entry", + AtkRolesFixture, HTML_LABELED_ENTRY, + atk_roles_fixture_setup, + test_webkit_atk_get_role_entry, + atk_roles_fixture_teardown); + + g_test_add("/webkit/atk/test_webkit_atk_get_role_label", + AtkRolesFixture, HTML_LABELED_ENTRY, + atk_roles_fixture_setup, + test_webkit_atk_get_role_label, + atk_roles_fixture_teardown); + + g_test_add("/webkit/atk/test_webkit_atk_get_role_listbox", + AtkRolesFixture, HTML_LISTBOX, + atk_roles_fixture_setup, + test_webkit_atk_get_role_listbox, + atk_roles_fixture_teardown); + + g_test_add("/webkit/atk/test_webkit_atk_get_role_password_text", + AtkRolesFixture, HTML_PASSWORD_TEXT, + atk_roles_fixture_setup, + test_webkit_atk_get_role_password_text, + atk_roles_fixture_teardown); + + g_test_add("/webkit/atk/test_webkit_atk_get_role_push_button", + AtkRolesFixture, HTML_PUSH_BUTTON, + atk_roles_fixture_setup, + test_webkit_atk_get_role_push_button, + atk_roles_fixture_teardown); + + g_test_add("/webkit/atk/test_webkit_atk_get_role_radio_button", + AtkRolesFixture, HTML_RADIO_BUTTON, + atk_roles_fixture_setup, + test_webkit_atk_get_role_radio_button, + atk_roles_fixture_teardown); + + return g_test_run(); +} + +#else +int main(int argc, char** argv) +{ + g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now."); + return 0; +} + +#endif diff --git a/Source/WebKit/gtk/tests/testcopyandpaste.c b/Source/WebKit/gtk/tests/testcopyandpaste.c new file mode 100644 index 0000000..1b5fb7b --- /dev/null +++ b/Source/WebKit/gtk/tests/testcopyandpaste.c @@ -0,0 +1,276 @@ +/* + * Copyright (C) 2010 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <errno.h> +#include <unistd.h> +#include <string.h> +#include <glib/gstdio.h> +#include <webkit/webkit.h> +#include <JavaScriptCore/JSStringRef.h> +#include <JavaScriptCore/JSContextRef.h> + +#if GTK_CHECK_VERSION(2, 14, 0) + +typedef struct { + char* page; + char* expectedContent; +} TestInfo; + +typedef struct { + GtkWidget* window; + WebKitWebView* webView; + GMainLoop* loop; + TestInfo* info; +} CopyAndPasteFixture; + +TestInfo* +test_info_new(const char* page, const char* expectedContent) +{ + TestInfo* info; + info = g_slice_new0(TestInfo); + info->page = g_strdup(page); + if (expectedContent) + info->expectedContent = g_strdup(expectedContent); + return info; +} + +void +test_info_destroy(TestInfo* info) +{ + g_free(info->page); + g_free(info->expectedContent); + g_slice_free(TestInfo, info); +} + +static void copy_and_paste_fixture_setup(CopyAndPasteFixture* fixture, gconstpointer data) +{ + fixture->loop = g_main_loop_new(NULL, TRUE); + + fixture->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + fixture->webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + + gtk_container_add(GTK_CONTAINER(fixture->window), GTK_WIDGET(fixture->webView)); +} + +static void copy_and_paste_fixture_teardown(CopyAndPasteFixture* fixture, gconstpointer data) +{ + gtk_widget_destroy(fixture->window); + g_main_loop_unref(fixture->loop); + test_info_destroy(fixture->info); +} + +static void load_status_cb(WebKitWebView* webView, GParamSpec* spec, gpointer data) +{ + CopyAndPasteFixture* fixture = (CopyAndPasteFixture*)data; + WebKitLoadStatus status = webkit_web_view_get_load_status(webView); + if (status != WEBKIT_LOAD_FINISHED) + return; + + GtkClipboard* clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); + gtk_clipboard_clear(clipboard); + + webkit_web_view_copy_clipboard(webView); + + gchar* text = gtk_clipboard_wait_for_text(clipboard); + g_assert(text || !fixture->info->expectedContent); + g_assert(!text || !strcmp(text, fixture->info->expectedContent)); + g_free(text); + + // Verify that the markup starts with the proper content-type meta tag prefix. + GtkSelectionData* selectionData = gtk_clipboard_wait_for_contents(clipboard, gdk_atom_intern("text/html", FALSE)); + if (selectionData) { + static const char* markupPrefix = "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">"; + char* markup = g_strndup((const char*) gtk_selection_data_get_data(selectionData), + gtk_selection_data_get_length(selectionData)); + g_assert(strlen(markupPrefix) <= strlen(markup)); + g_assert(!strncmp(markupPrefix, markup, strlen(markupPrefix))); + g_free(markup); + } + + g_assert(!gtk_clipboard_wait_is_uris_available(clipboard)); + g_assert(!gtk_clipboard_wait_is_image_available(clipboard)); + + g_main_loop_quit(fixture->loop); +} + +gboolean map_event_cb(GtkWidget *widget, GdkEvent* event, gpointer data) +{ + gtk_widget_grab_focus(widget); + CopyAndPasteFixture* fixture = (CopyAndPasteFixture*)data; + webkit_web_view_load_string(fixture->webView, fixture->info->page, + "text/html", "utf-8", "file://"); + return FALSE; +} + +static void test_copy_and_paste(CopyAndPasteFixture* fixture, gconstpointer data) +{ + fixture->info = (TestInfo*)data; + g_signal_connect(fixture->window, "map-event", + G_CALLBACK(map_event_cb), fixture); + + gtk_widget_show(fixture->window); + gtk_widget_show(GTK_WIDGET(fixture->webView)); + gtk_window_present(GTK_WINDOW(fixture->window)); + + g_signal_connect(fixture->webView, "notify::load-status", + G_CALLBACK(load_status_cb), fixture); + + g_main_loop_run(fixture->loop); +} + +static CopyAndPasteFixture* currentFixture; +static JSValueRef runPasteTestCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + // Simulate a paste keyboard sequence. + GdkEvent* event = gdk_event_new(GDK_KEY_PRESS); + event->key.keyval = gdk_unicode_to_keyval('v'); + event->key.state = GDK_CONTROL_MASK; + event->key.window = gtk_widget_get_window(GTK_WIDGET(currentFixture->webView)); + g_object_ref(event->key.window); +#ifndef GTK_API_VERSION_2 + GdkDeviceManager* manager = gdk_display_get_device_manager(gdk_window_get_display(event->key.window)); + gdk_event_set_device(event, gdk_device_manager_get_client_pointer(manager)); +#endif + + GdkKeymapKey* keys; + gint n_keys; + if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), event->key.keyval, &keys, &n_keys)) { + event->key.hardware_keycode = keys[0].keycode; + g_free(keys); + } + + gtk_main_do_event(event); + event->key.type = GDK_KEY_RELEASE; + gtk_main_do_event(event); + gdk_event_free(event); + + JSStringRef scriptString = JSStringCreateWithUTF8CString("document.body.innerHTML;"); + JSValueRef value = JSEvaluateScript(context, scriptString, 0, 0, 0, 0); + JSStringRelease(scriptString); + + g_assert(JSValueIsString(context, value)); + JSStringRef actual = JSValueToStringCopy(context, value, exception); + g_assert(!exception || !*exception); + g_assert(currentFixture->info->expectedContent); + JSStringRef expected = JSStringCreateWithUTF8CString(currentFixture->info->expectedContent); + g_assert(JSStringIsEqual(expected, actual)); + + JSStringRelease(expected); + JSStringRelease(actual); + g_main_loop_quit(currentFixture->loop); + return JSValueMakeUndefined(context); +} + +static void window_object_cleared_callback(WebKitWebView* web_view, WebKitWebFrame* web_frame, JSGlobalContextRef context, JSObjectRef window_object, gpointer data) +{ + JSStringRef name = JSStringCreateWithUTF8CString("runTest"); + JSObjectRef testComplete = JSObjectMakeFunctionWithCallback(context, name, runPasteTestCallback); + JSObjectSetProperty(context, window_object, name, testComplete, kJSPropertyAttributeNone, 0); + JSStringRelease(name); +} + +static void pasting_test_get_data_callback(GtkClipboard* clipboard, GtkSelectionData* selection_data, guint info, gpointer data) +{ + gtk_selection_data_set(selection_data, gdk_atom_intern("text/html", FALSE), 8, (const guchar*) data, strlen((char*)data) + 1); +} + +static void pasting_test_clear_data_callback(GtkClipboard* clipboard, gpointer data) +{ + g_free(data); +} + +static void test_pasting_markup(CopyAndPasteFixture* fixture, gconstpointer data) +{ + fixture->info = (TestInfo*)data; + currentFixture = fixture; + + GtkTargetList* targetList = gtk_target_list_new(0, 0); + gtk_target_list_add(targetList, gdk_atom_intern("text/html", FALSE), 0, 0); + + int numberOfTargets = 1; + GtkTargetEntry* targetTable = gtk_target_table_new_from_list(targetList, &numberOfTargets); + gtk_clipboard_set_with_data(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), + targetTable, numberOfTargets, + pasting_test_get_data_callback, + pasting_test_clear_data_callback, + g_strdup(fixture->info->expectedContent)); + gtk_target_list_unref(targetList); + gtk_target_table_free(targetTable, numberOfTargets); + + g_signal_connect(fixture->window, "map-event", + G_CALLBACK(map_event_cb), fixture); + g_signal_connect(fixture->webView, "window-object-cleared", + G_CALLBACK(window_object_cleared_callback), fixture); + + gtk_widget_show(fixture->window); + gtk_widget_show(GTK_WIDGET(fixture->webView)); + gtk_window_present(GTK_WINDOW(fixture->window)); + + g_main_loop_run(fixture->loop); +} + + +int main(int argc, char** argv) +{ + g_thread_init(NULL); + gtk_test_init(&argc, &argv, NULL); + + g_test_bug_base("https://bugs.webkit.org/"); + const char* selected_span_html = "<html><body>" + "<span id=\"mainspan\">All work and no play <span>make Jack a dull</span> boy.</span>" + "<script>document.getSelection().collapse();\n" + "document.getSelection().selectAllChildren(document.getElementById('mainspan'));\n" + "</script></body></html>"; + const char* no_selection_html = "<html><body>" + "<span id=\"mainspan\">All work and no play <span>make Jack a dull</span> boy</span>" + "<script>document.getSelection().collapse();\n" + "</script></body></html>"; + + g_test_add("/webkit/copyandpaste/selection", CopyAndPasteFixture, + test_info_new(selected_span_html, "All work and no play make Jack a dull boy."), + copy_and_paste_fixture_setup, + test_copy_and_paste, + copy_and_paste_fixture_teardown); + g_test_add("/webkit/copyandpaste/no-selection", CopyAndPasteFixture, + test_info_new(no_selection_html, 0), + copy_and_paste_fixture_setup, + test_copy_and_paste, + copy_and_paste_fixture_teardown); + + const char* paste_test_html = "<html>" + "<body onLoad=\"document.body.focus(); runTest();\" contentEditable=\"true\">" + "</body></html>"; + g_test_add("/webkit/copyandpaste/paste-markup", CopyAndPasteFixture, + test_info_new(paste_test_html, "bobby"), + copy_and_paste_fixture_setup, + test_pasting_markup, + copy_and_paste_fixture_teardown); + + return g_test_run(); +} + +#else + +int main(int argc, char** argv) +{ + g_critical("You will need at least GTK+ 2.14.0 to run the unit tests."); + return 0; +} + +#endif diff --git a/Source/WebKit/gtk/tests/testdomdocument.c b/Source/WebKit/gtk/tests/testdomdocument.c new file mode 100644 index 0000000..aa6cbb3 --- /dev/null +++ b/Source/WebKit/gtk/tests/testdomdocument.c @@ -0,0 +1,375 @@ +/* + * Copyright (C) 2010 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "test_utils.h" + +#include <glib.h> +#include <glib/gstdio.h> +#include <gtk/gtk.h> +#include <webkit/webkit.h> + +#if GTK_CHECK_VERSION(2, 14, 0) + +#define HTML_DOCUMENT_TITLE "<html><head><title>This is the title</title></head><body></body></html>" +#define HTML_DOCUMENT_ELEMENTS "<html><body><ul><li>1</li><li>2</li><li>3</li></ul></body></html>" +#define HTML_DOCUMENT_ELEMENTS_CLASS "<html><body><div class=\"test\"></div><div class=\"strange\"></div><div class=\"test\"></div></body></html>" +#define HTML_DOCUMENT_ELEMENTS_ID "<html><body><div id=\"testok\"></div><div id=\"testbad\">first</div><div id=\"testbad\">second</div></body></html>" +#define HTML_DOCUMENT_LINKS "<html><head><title>Title</title></head><body><a href=\"about:blank\">blank</a><a href=\"http://www.google.com\">google</a><a href=\"http://www.webkit.org\">webkit</a></body></html>" +#define HTML_DOCUMENT_IFRAME "<html><head><title>IFrame</title></head><body><iframe id='iframe'></iframe><div id='test'></div></body></html>" + +typedef struct { + GtkWidget* webView; + GMainLoop* loop; +} DomDocumentFixture; + +static gboolean finish_loading(DomDocumentFixture* fixture) +{ + if (g_main_loop_is_running(fixture->loop)) + g_main_loop_quit(fixture->loop); + + return FALSE; +} + +static void dom_document_fixture_setup(DomDocumentFixture* fixture, gconstpointer data) +{ + fixture->loop = g_main_loop_new(NULL, TRUE); + fixture->webView = webkit_web_view_new(); + g_object_ref_sink(fixture->webView); + + if (data != NULL) + webkit_web_view_load_string(WEBKIT_WEB_VIEW (fixture->webView), (const char*) data, NULL, NULL, NULL); + + g_idle_add((GSourceFunc)finish_loading, fixture); + g_main_loop_run(fixture->loop); +} + +static void dom_document_fixture_teardown(DomDocumentFixture* fixture, gconstpointer data) +{ + if (fixture->webView) + g_object_unref(fixture->webView); + g_main_loop_unref(fixture->loop); +} + +static void test_dom_document_title(DomDocumentFixture* fixture, gconstpointer data) +{ + g_assert(fixture); + WebKitWebView* view = (WebKitWebView*)fixture->webView; + g_assert(view); + WebKitDOMDocument* document = webkit_web_view_get_dom_document(view); + g_assert(document); + gchar* title = webkit_dom_document_get_title(document); + g_assert(title); + g_assert_cmpstr(title, ==, "This is the title"); + g_free(title); + webkit_dom_document_set_title(document, "This is the second title"); + title = webkit_dom_document_get_title(document); + g_assert(title); + g_assert_cmpstr(title, ==, "This is the second title"); + g_free(title); +} + +static void test_dom_document_get_elements_by_tag_name(DomDocumentFixture* fixture, gconstpointer data) +{ + g_assert(fixture); + WebKitWebView* view = (WebKitWebView*)fixture->webView; + g_assert(view); + WebKitDOMDocument* document = webkit_web_view_get_dom_document(view); + g_assert(document); + WebKitDOMNodeList* list = webkit_dom_document_get_elements_by_tag_name(document, "li"); + g_assert(list); + gulong length = webkit_dom_node_list_get_length(list); + g_assert_cmpint(length, ==, 3); + + guint i; + + for (i = 0; i < length; i++) { + WebKitDOMNode* item = webkit_dom_node_list_item(list, i); + g_assert(item); + WebKitDOMElement* element = (WebKitDOMElement*)item; + g_assert(element); + g_assert_cmpstr(webkit_dom_element_get_tag_name(element), ==, "LI"); + WebKitDOMHTMLElement* htmlElement = (WebKitDOMHTMLElement*)element; + char* n = g_strdup_printf("%d", i+1); + g_assert_cmpstr(webkit_dom_html_element_get_inner_text(htmlElement), ==, n); + g_free(n); + } + + g_object_unref(list); +} + +static void test_dom_document_get_elements_by_class_name(DomDocumentFixture* fixture, gconstpointer data) +{ + g_assert(fixture); + WebKitWebView* view = (WebKitWebView*)fixture->webView; + g_assert(view); + WebKitDOMDocument* document = webkit_web_view_get_dom_document(view); + g_assert(document); + WebKitDOMNodeList* list = webkit_dom_document_get_elements_by_class_name(document, "test"); + g_assert(list); + gulong length = webkit_dom_node_list_get_length(list); + g_assert_cmpint(length, ==, 2); + + guint i; + + for (i = 0; i < length; i++) { + WebKitDOMNode* item = webkit_dom_node_list_item(list, i); + g_assert(item); + WebKitDOMElement* element = (WebKitDOMElement*)item; + g_assert(element); + g_assert_cmpstr(webkit_dom_element_get_tag_name(element), ==, "DIV"); + } + + g_object_unref(list); +} + +static void test_dom_document_get_element_by_id(DomDocumentFixture* fixture, gconstpointer data) +{ + g_assert(fixture); + WebKitWebView* view = (WebKitWebView*)fixture->webView; + g_assert(view); + WebKitDOMDocument* document = webkit_web_view_get_dom_document(view); + g_assert(document); + WebKitDOMElement* element = webkit_dom_document_get_element_by_id(document, "testok"); + g_assert(element); + element = webkit_dom_document_get_element_by_id(document, "this-id-does-not-exist"); + g_assert(element == 0); + /* The DOM spec says the return value is undefined when there's + * more than one element with the same id; in our case the first + * one will be returned */ + element = webkit_dom_document_get_element_by_id(document, "testbad"); + g_assert(element); + WebKitDOMHTMLElement* htmlElement = (WebKitDOMHTMLElement*)element; + g_assert_cmpstr(webkit_dom_html_element_get_inner_text(htmlElement), ==, "first"); +} + +static void test_dom_document_get_links(DomDocumentFixture* fixture, gconstpointer data) +{ + g_assert(fixture); + WebKitWebView* view = (WebKitWebView*)fixture->webView; + g_assert(view); + WebKitDOMDocument* document = webkit_web_view_get_dom_document(view); + g_assert(document); + WebKitDOMHTMLCollection *collection = webkit_dom_document_get_links(document); + g_assert(collection); + gulong length = webkit_dom_html_collection_get_length(collection); + g_assert_cmpint(length, ==, 3); + + guint i; + + for (i = 0; i < length; i++) { + static const char* names[] = { "blank", "google", "webkit" }; + static const char* uris[] = { "about:blank", "http://www.google.com/", "http://www.webkit.org/" }; + WebKitDOMNode *node = webkit_dom_html_collection_item(collection, i); + g_assert(node); + WebKitDOMElement* element = (WebKitDOMElement*)node; + g_assert_cmpstr(webkit_dom_element_get_tag_name(element), ==, "A"); + WebKitDOMHTMLElement *htmlElement = (WebKitDOMHTMLElement*)element; + g_assert_cmpstr(webkit_dom_html_element_get_inner_text(htmlElement), ==, names[i]); + WebKitDOMHTMLAnchorElement *anchor = (WebKitDOMHTMLAnchorElement*)element; + g_assert_cmpstr(webkit_dom_html_anchor_element_get_href(anchor), ==, uris[i]); + } + g_object_unref(collection); +} + +static void weak_notify(gpointer data, GObject* zombie) +{ + guint* count = (guint*)data; + (*count)++; +} + +static void test_dom_document_garbage_collection(DomDocumentFixture* fixture, gconstpointer data) +{ + guint count = 0; + g_assert(fixture); + WebKitWebView* view = (WebKitWebView*)fixture->webView; + g_assert(view); + WebKitDOMDocument* document = webkit_web_view_get_dom_document(view); + g_assert(document); + g_object_weak_ref(G_OBJECT(document), (GWeakNotify)weak_notify, &count); + WebKitDOMHTMLHeadElement* head = webkit_dom_document_get_head(document); + g_assert(head); + g_object_weak_ref(G_OBJECT(head), (GWeakNotify)weak_notify, &count); + WebKitDOMHTMLElement* body = webkit_dom_document_get_body(document); + g_assert(body); + g_object_weak_ref(G_OBJECT(body), (GWeakNotify)weak_notify, &count); + WebKitDOMHTMLCollection *collection = webkit_dom_document_get_links(document); + g_assert(collection); + g_object_weak_ref(G_OBJECT(collection), (GWeakNotify)weak_notify, &count); + + webkit_web_view_load_string(WEBKIT_WEB_VIEW(view), HTML_DOCUMENT_LINKS, NULL, NULL, NULL); + + while (g_main_context_pending(NULL)) + g_main_context_iteration(NULL, FALSE); + + g_assert_cmpuint(count, ==, 3); + + g_object_unref(collection); + g_assert_cmpuint(count, ==, 4); + + count = 0; + + document = webkit_web_view_get_dom_document(view); + g_assert(document); + g_object_weak_ref(G_OBJECT(document), (GWeakNotify)weak_notify, &count); + head = webkit_dom_document_get_head(document); + g_assert(head); + g_object_weak_ref(G_OBJECT(head), (GWeakNotify)weak_notify, &count); + body = webkit_dom_document_get_body(document); + g_assert(body); + g_object_weak_ref(G_OBJECT(body), (GWeakNotify)weak_notify, &count); + collection = webkit_dom_document_get_links(document); + g_assert(collection); + g_object_weak_ref(G_OBJECT(collection), (GWeakNotify)weak_notify, &count); + /* Ask twice for the same object */ + WebKitDOMHTMLCollection* collection2 = webkit_dom_document_get_links(document); + g_assert(collection2); + g_object_weak_ref(G_OBJECT(collection2), (GWeakNotify)weak_notify, &count); + + g_object_unref(document); + g_object_unref(head); + g_object_unref(body); + g_object_unref(collection); + g_object_unref(collection2); + + g_assert_cmpuint(count, ==, 5); + + webkit_web_view_load_string(WEBKIT_WEB_VIEW(view), HTML_DOCUMENT_IFRAME, NULL, NULL, NULL); + + while (g_main_context_pending(NULL)) + g_main_context_iteration(NULL, FALSE); + + count = 0; + + document = webkit_web_view_get_dom_document(view); + WebKitDOMElement* div = webkit_dom_document_get_element_by_id(document, "test"); + g_assert(div); + g_object_weak_ref(G_OBJECT(div), (GWeakNotify)weak_notify, &count); + WebKitDOMElement* iframe = webkit_dom_document_get_element_by_id(document, "iframe"); + g_assert(iframe); + + webkit_dom_element_set_attribute(iframe, "src", "data:<html><head></head></html>", NULL); + + while (g_main_context_pending(NULL)) + g_main_context_iteration(NULL, FALSE); + + WebKitDOMDocument* iframeDocument = webkit_dom_html_iframe_element_get_content_document(WEBKIT_DOM_HTML_IFRAME_ELEMENT(iframe)); + g_assert(iframeDocument); + head = webkit_dom_document_get_head(iframeDocument); + g_assert(head); + g_object_weak_ref(G_OBJECT(head), (GWeakNotify)weak_notify, &count); + + webkit_dom_element_set_attribute(iframe, "src", "about:blank", NULL); + + while (g_main_context_pending(NULL)) + g_main_context_iteration(NULL, FALSE); + + g_assert_cmpuint(count, ==, 1); + + webkit_web_view_load_string(WEBKIT_WEB_VIEW(view), HTML_DOCUMENT_LINKS, NULL, NULL, NULL); + + while (g_main_context_pending(NULL)) + g_main_context_iteration(NULL, FALSE); + + g_assert_cmpuint(count, ==, 2); + + count = 0; + + document = webkit_web_view_get_dom_document(view); + g_assert(document); + g_object_weak_ref(G_OBJECT(document), (GWeakNotify)weak_notify, &count); + /* Ask twice for the Document */ + WebKitDOMDocument* document2 = webkit_web_view_get_dom_document(view); + g_assert(document2); + g_object_weak_ref(G_OBJECT(document2), (GWeakNotify)weak_notify, &count); + head = webkit_dom_document_get_head(document); + g_assert(head); + g_object_weak_ref(G_OBJECT(head), (GWeakNotify)weak_notify, &count); + body = webkit_dom_document_get_body(document); + g_assert(body); + g_object_weak_ref(G_OBJECT(body), (GWeakNotify)weak_notify, &count); + collection = webkit_dom_document_get_links(document); + g_assert(collection); + g_object_weak_ref(G_OBJECT(collection), (GWeakNotify)weak_notify, &count); + + gtk_widget_destroy(fixture->webView); + fixture->webView = NULL; + + g_assert_cmpuint(count, ==, 4); + + g_object_unref(collection); + + g_assert_cmpuint(count, ==, 5); +} + +int main(int argc, char** argv) +{ + if (!g_thread_supported()) + g_thread_init(NULL); + + gtk_test_init(&argc, &argv, NULL); + + g_test_bug_base("https://bugs.webkit.org/"); + + g_test_add("/webkit/domdocument/test_title", + DomDocumentFixture, HTML_DOCUMENT_TITLE, + dom_document_fixture_setup, + test_dom_document_title, + dom_document_fixture_teardown); + + g_test_add("/webkit/domdocument/test_get_elements_by_tag_name", + DomDocumentFixture, HTML_DOCUMENT_ELEMENTS, + dom_document_fixture_setup, + test_dom_document_get_elements_by_tag_name, + dom_document_fixture_teardown); + + g_test_add("/webkit/domdocument/test_get_elements_by_class_name", + DomDocumentFixture, HTML_DOCUMENT_ELEMENTS_CLASS, + dom_document_fixture_setup, + test_dom_document_get_elements_by_class_name, + dom_document_fixture_teardown); + + g_test_add("/webkit/domdocument/test_get_element_by_id", + DomDocumentFixture, HTML_DOCUMENT_ELEMENTS_ID, + dom_document_fixture_setup, + test_dom_document_get_element_by_id, + dom_document_fixture_teardown); + + g_test_add("/webkit/domdocument/test_get_links", + DomDocumentFixture, HTML_DOCUMENT_LINKS, + dom_document_fixture_setup, + test_dom_document_get_links, + dom_document_fixture_teardown); + + g_test_add("/webkit/domdocument/test_garbage_collection", + DomDocumentFixture, HTML_DOCUMENT_LINKS, + dom_document_fixture_setup, + test_dom_document_garbage_collection, + dom_document_fixture_teardown); + + return g_test_run(); +} + +#else +int main(int argc, char** argv) +{ + g_critical("You will gtk-2.14.0 to run the unit tests. Doing nothing now."); + return 0; +} + +#endif diff --git a/Source/WebKit/gtk/tests/testdomdomwindow.c b/Source/WebKit/gtk/tests/testdomdomwindow.c new file mode 100644 index 0000000..b15558e --- /dev/null +++ b/Source/WebKit/gtk/tests/testdomdomwindow.c @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2010 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "test_utils.h" + +#include <glib.h> +#include <glib/gstdio.h> +#include <gtk/gtk.h> +#include <webkit/webkit.h> + +#if GTK_CHECK_VERSION(2, 14, 0) + +#define HTML_DOCUMENT "<html><head><title>This is the title</title></head><body><p id='test'>test</p></body></html>" + +typedef struct { + GtkWidget* webView; + GtkWidget* window; + WebKitDOMDOMWindow* domWindow; + GMainLoop* loop; + + gboolean loaded; + gboolean clicked; + gconstpointer data; +} DomDomviewFixture; + +static gboolean finish_loading(DomDomviewFixture* fixture) +{ + if (g_main_loop_is_running(fixture->loop)) + g_main_loop_quit(fixture->loop); + + return FALSE; +} + +static void dom_domview_fixture_setup(DomDomviewFixture* fixture, gconstpointer data) +{ + fixture->loop = g_main_loop_new(NULL, TRUE); + fixture->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + fixture->webView = webkit_web_view_new(); + fixture->data = data; + + gtk_container_add(GTK_CONTAINER(fixture->window), GTK_WIDGET(fixture->webView)); +} + +static void dom_domview_fixture_teardown(DomDomviewFixture* fixture, gconstpointer data) +{ + gtk_widget_destroy(fixture->window); + g_main_loop_unref(fixture->loop); +} + +static gboolean loadedCallback(WebKitDOMDOMWindow* view, WebKitDOMEvent* event, DomDomviewFixture* fixture) +{ + g_assert(fixture->loaded == FALSE); + fixture->loaded = TRUE; + + return FALSE; +} + +static gboolean clickedCallback(WebKitDOMDOMWindow* view, WebKitDOMEvent* event, DomDomviewFixture* fixture) +{ + WebKitDOMEventTarget* target; + gushort phase; + + g_assert(event); + g_assert(WEBKIT_DOM_IS_EVENT(event)); + + // We should catch this in the bubbling up phase, since we are connecting to the toplevel object + phase = webkit_dom_event_get_event_phase(event); + g_assert_cmpint(phase, ==, 3); + + target = webkit_dom_event_get_current_target(event); + g_assert(target == WEBKIT_DOM_EVENT_TARGET(view)); + + g_assert(fixture->clicked == FALSE); + fixture->clicked = TRUE; + + finish_loading(fixture); + + return FALSE; +} + +gboolean map_event_cb(GtkWidget *widget, GdkEvent* event, DomDomviewFixture* fixture) +{ + webkit_web_view_load_string(WEBKIT_WEB_VIEW (fixture->webView), (const char*)fixture->data, NULL, NULL, NULL); + + return FALSE; +} + +static void load_event_callback(WebKitWebView* webView, GParamSpec* spec, DomDomviewFixture* fixture) +{ + WebKitLoadStatus status = webkit_web_view_get_load_status(webView); + if (status == WEBKIT_LOAD_FINISHED) { + g_signal_connect(fixture->domWindow, "click-event", G_CALLBACK(clickedCallback), fixture); + + g_assert(fixture->clicked == FALSE); + gtk_test_widget_click(GTK_WIDGET(fixture->webView), 1, 0); + } + +} + +static void test_dom_domview_signals(DomDomviewFixture* fixture, gconstpointer data) +{ + g_assert(fixture); + WebKitWebView* view = (WebKitWebView*)fixture->webView; + g_assert(view); + WebKitDOMDocument* document = webkit_web_view_get_dom_document(view); + g_assert(document); + WebKitDOMDOMWindow* domWindow = webkit_dom_document_get_default_view(document); + g_assert(domWindow); + + fixture->domWindow = domWindow; + + g_signal_connect(fixture->domWindow, "load-event", G_CALLBACK(loadedCallback), fixture); + g_signal_connect(fixture->window, "map-event", G_CALLBACK(map_event_cb), fixture); + g_signal_connect(fixture->webView, "notify::load-status", G_CALLBACK(load_event_callback), fixture); + + gtk_widget_show_all(fixture->window); + gtk_window_present(GTK_WINDOW(fixture->window)); + + g_main_loop_run(fixture->loop); + + g_assert(fixture->loaded); + g_assert(fixture->clicked); +} + +static gboolean +clicked_cb(WebKitDOMEventTarget* target, WebKitDOMEvent* event, DomDomviewFixture* fixture) +{ + g_assert(fixture->clicked == FALSE); + fixture->clicked = TRUE; + finish_loading(fixture); + return FALSE; +} + +static void load_status_callback(WebKitWebView* webView, GParamSpec* spec, DomDomviewFixture* fixture) +{ + WebKitLoadStatus status = webkit_web_view_get_load_status(webView); + if (status == WEBKIT_LOAD_FINISHED) { + WebKitDOMDocument* document; + WebKitDOMDOMWindow* domWindow; + WebKitDOMElement* element; + WebKitDOMEvent* event; + glong clientX, clientY; + + document = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(fixture->webView)); + g_assert(document); + domWindow = webkit_dom_document_get_default_view(document); + g_assert(domWindow); + fixture->domWindow = domWindow; + + element = webkit_dom_document_get_element_by_id(document, "test"); + g_assert(element); + event = webkit_dom_document_create_event(document, "MouseEvent", NULL); + g_assert(event); + g_assert(WEBKIT_DOM_IS_EVENT(event)); + g_assert(WEBKIT_DOM_IS_MOUSE_EVENT(event)); + clientX = webkit_dom_element_get_client_left(element); + clientY = webkit_dom_element_get_client_top(element); + webkit_dom_mouse_event_init_mouse_event(WEBKIT_DOM_MOUSE_EVENT(event), + "click", TRUE, TRUE, + fixture->domWindow, 0, 0, 0, clientX, clientY, + FALSE, FALSE, FALSE, FALSE, + 1, WEBKIT_DOM_EVENT_TARGET(element)); + g_signal_connect(element, "click-event", G_CALLBACK(clicked_cb), fixture); + g_assert(fixture->clicked == FALSE); + webkit_dom_event_target_dispatch_event(WEBKIT_DOM_EVENT_TARGET(element), event, NULL); + } + +} + +static void test_dom_domview_dispatch_event(DomDomviewFixture* fixture, gconstpointer data) +{ + g_signal_connect(fixture->window, "map-event", G_CALLBACK(map_event_cb), fixture); + g_signal_connect(fixture->webView, "notify::load-status", G_CALLBACK(load_status_callback), fixture); + + gtk_widget_show_all(fixture->window); + gtk_window_present(GTK_WINDOW(fixture->window)); + + g_main_loop_run (fixture->loop); + g_assert(fixture->clicked); +} + +int main(int argc, char** argv) +{ + if (!g_thread_supported()) + g_thread_init(NULL); + + gtk_test_init(&argc, &argv, NULL); + + g_test_bug_base("https://bugs.webkit.org/"); + + g_test_add("/webkit/domdomview/signals", + DomDomviewFixture, HTML_DOCUMENT, + dom_domview_fixture_setup, + test_dom_domview_signals, + dom_domview_fixture_teardown); + + g_test_add("/webkit/domdomview/dispatch_event", + DomDomviewFixture, HTML_DOCUMENT, + dom_domview_fixture_setup, + test_dom_domview_dispatch_event, + dom_domview_fixture_teardown); + + return g_test_run(); +} + +#else +int main(int argc, char** argv) +{ + g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now."); + return 0; +} + +#endif diff --git a/Source/WebKit/gtk/tests/testdomnode.c b/Source/WebKit/gtk/tests/testdomnode.c new file mode 100644 index 0000000..893b7cc --- /dev/null +++ b/Source/WebKit/gtk/tests/testdomnode.c @@ -0,0 +1,206 @@ +/* + * Copyright (C) 2010 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "test_utils.h" + +#include <glib.h> +#include <glib/gstdio.h> +#include <gtk/gtk.h> +#include <webkit/webkit.h> + +#if GTK_CHECK_VERSION(2, 14, 0) + +#define HTML_DOCUMENT_HIERARCHY_NAVIGATION "<html><head><title>This is the title</title></head><body><p>1</p><p>2</p><p>3</p></body></html>" +#define HTML_DOCUMENT_NODE_INSERTION "<html><body></body></html>" + +typedef struct { + GtkWidget* webView; + GMainLoop* loop; +} DomNodeFixture; + +static gboolean finish_loading(DomNodeFixture* fixture) +{ + if (g_main_loop_is_running(fixture->loop)) + g_main_loop_quit(fixture->loop); + + return FALSE; +} + +static void dom_node_fixture_setup(DomNodeFixture* fixture, gconstpointer data) +{ + fixture->loop = g_main_loop_new(NULL, TRUE); + fixture->webView = webkit_web_view_new(); + g_object_ref_sink(fixture->webView); + + if (data != NULL) + webkit_web_view_load_string(WEBKIT_WEB_VIEW(fixture->webView), (const char*)data, NULL, NULL, NULL); + + g_idle_add((GSourceFunc)finish_loading, fixture); + g_main_loop_run(fixture->loop); +} + +static void dom_node_fixture_teardown(DomNodeFixture* fixture, gconstpointer data) +{ + g_object_unref(fixture->webView); + g_main_loop_unref(fixture->loop); +} + +static void test_dom_node_hierarchy_navigation(DomNodeFixture* fixture, gconstpointer data) +{ + WebKitDOMDocument* document; + WebKitDOMHTMLHeadElement* head; + WebKitDOMHTMLBodyElement* body; + WebKitDOMNodeList* list; + WebKitDOMNode* ptr; + gulong i, length; + + document = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(fixture->webView)); + g_assert(document); + g_assert(WEBKIT_DOM_IS_DOCUMENT(document)); + head = webkit_dom_document_get_head(document); + g_assert(head); + g_assert(WEBKIT_DOM_IS_HTML_HEAD_ELEMENT(head)); + + /* Title, head's child */ + g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(head))); + list = webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(head)); + g_assert_cmpint(webkit_dom_node_list_get_length(list), ==, 1); + ptr = webkit_dom_node_list_item(list, 0); + g_assert(ptr); + g_assert(WEBKIT_DOM_IS_HTML_TITLE_ELEMENT(ptr)); + g_object_unref(list); + + /* Body, Head sibling */ + ptr = webkit_dom_node_get_next_sibling(WEBKIT_DOM_NODE(head)); + g_assert(ptr); + body = WEBKIT_DOM_HTML_BODY_ELEMENT(ptr); + g_assert(WEBKIT_DOM_IS_HTML_BODY_ELEMENT(body)); + + /* There is no third sibling */ + ptr = webkit_dom_node_get_next_sibling(ptr); + g_assert(ptr == NULL); + + /* Body's previous sibling is Head */ + ptr = webkit_dom_node_get_previous_sibling(WEBKIT_DOM_NODE(body)); + g_assert(ptr); + g_assert(WEBKIT_DOM_IS_HTML_HEAD_ELEMENT(ptr)); + + /* Body has 3 children */ + g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body))); + list = webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body)); + length = webkit_dom_node_list_get_length(list); + g_assert_cmpint(length, ==, 3); + + /* The three of them are P tags */ + for (i = 0; i < length; i++) { + ptr = webkit_dom_node_list_item(list, i); + g_assert(ptr); + g_assert(WEBKIT_DOM_IS_HTML_PARAGRAPH_ELEMENT(ptr)); + } + + /* Go backwards */ + for (i = 0; ptr; ptr = webkit_dom_node_get_previous_sibling(ptr), i++) + /* Nothing */; + + g_assert_cmpint(i, ==, 3); + g_object_unref(list); +} + +static void test_dom_node_insertion(DomNodeFixture* fixture, gconstpointer data) +{ + WebKitDOMDocument* document; + WebKitDOMHTMLElement* body; + WebKitDOMElement* p, *div; + WebKitDOMNodeList* list; + WebKitDOMNode* node; + + document = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(fixture->webView)); + g_assert(document); + body = webkit_dom_document_get_body(document); + g_assert(body); + g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(body)); + + /* Body shouldn't have any children at this point */ + g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body)) == FALSE); + + /* Insert one P element */ + p = webkit_dom_document_create_element(document, "P", NULL); + webkit_dom_node_append_child(WEBKIT_DOM_NODE(body), WEBKIT_DOM_NODE(p), NULL); + + /* Now it should have one, the same that we inserted */ + g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body))); + list = webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body)); + g_assert_cmpint(webkit_dom_node_list_get_length(list), ==, 1); + node = webkit_dom_node_list_item(list, 0); + g_assert(node); + g_assert(webkit_dom_node_is_same_node(WEBKIT_DOM_NODE(p), node)); + g_object_unref(list); + + /* Replace the P tag with a DIV tag */ + div = webkit_dom_document_create_element(document, "DIV", NULL); + webkit_dom_node_replace_child(WEBKIT_DOM_NODE(body), WEBKIT_DOM_NODE(div), WEBKIT_DOM_NODE(p), NULL); + g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body))); + list = webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body)); + g_assert_cmpint(webkit_dom_node_list_get_length(list), ==, 1); + node = webkit_dom_node_list_item(list, 0); + g_assert(node); + g_assert(webkit_dom_node_is_same_node(WEBKIT_DOM_NODE(div), node)); + g_object_unref(list); + + /* Now remove the tag */ + webkit_dom_node_remove_child(WEBKIT_DOM_NODE(body), node, NULL); + list = webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body)); + g_assert_cmpint(webkit_dom_node_list_get_length(list), ==, 0); + g_object_unref(list); + + /* TODO: insert_before, which does not seem to be working correctly */ +} + +int main(int argc, char** argv) +{ + if (!g_thread_supported()) + g_thread_init(NULL); + + gtk_test_init(&argc, &argv, NULL); + + g_test_bug_base("https://bugs.webkit.org/"); + + g_test_add("/webkit/domnode/test_hierarchy_navigation", + DomNodeFixture, HTML_DOCUMENT_HIERARCHY_NAVIGATION, + dom_node_fixture_setup, + test_dom_node_hierarchy_navigation, + dom_node_fixture_teardown); + + g_test_add("/webkit/domnode/test_insertion", + DomNodeFixture, HTML_DOCUMENT_NODE_INSERTION, + dom_node_fixture_setup, + test_dom_node_insertion, + dom_node_fixture_teardown); + + return g_test_run(); +} + +#else +int main(int argc, char** argv) +{ + g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now."); + return 0; +} + +#endif diff --git a/Source/WebKit/gtk/tests/testdownload.c b/Source/WebKit/gtk/tests/testdownload.c new file mode 100644 index 0000000..f6ae865 --- /dev/null +++ b/Source/WebKit/gtk/tests/testdownload.c @@ -0,0 +1,272 @@ +/* + * Copyright (C) 2009 Christian Dywan <christian@twotoasts.de> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <errno.h> +#include <unistd.h> +#include <glib/gstdio.h> +#include <webkit/webkit.h> + +#if GTK_CHECK_VERSION(2, 14, 0) + +GMainLoop* loop; +char* temporaryFilename = NULL; +WebKitDownload* theDownload = NULL; + +static void +test_webkit_download_create(void) +{ + WebKitNetworkRequest* request; + WebKitDownload* download; + const gchar* uri = "http://example.com"; + gchar* tmpDir; + + request = webkit_network_request_new(uri); + download = webkit_download_new(request); + g_object_unref(request); + g_assert_cmpstr(webkit_download_get_uri(download), ==, uri); + g_assert(webkit_download_get_network_request(download) == request); + g_assert(g_strrstr(uri, webkit_download_get_suggested_filename(download))); + g_assert(webkit_download_get_status(download) == WEBKIT_DOWNLOAD_STATUS_CREATED); + g_assert(!webkit_download_get_total_size(download)); + g_assert(!webkit_download_get_current_size(download)); + g_assert(!webkit_download_get_progress(download)); + g_assert(!webkit_download_get_elapsed_time(download)); + tmpDir = g_filename_to_uri(g_get_tmp_dir(), NULL, NULL); + webkit_download_set_destination_uri(download, tmpDir); + g_assert_cmpstr(tmpDir, ==, webkit_download_get_destination_uri(download));; + g_free(tmpDir); + g_object_unref(download); +} + +static gboolean +navigation_policy_decision_requested_cb(WebKitWebView* web_view, + WebKitWebFrame* web_frame, + WebKitNetworkRequest* request, + WebKitWebNavigationAction* action, + WebKitWebPolicyDecision* decision, + gpointer data) +{ + webkit_web_policy_decision_download(decision); + return TRUE; +} + +static void +notify_status_cb(GObject* object, GParamSpec* pspec, gpointer data) +{ + WebKitDownload* download = WEBKIT_DOWNLOAD(object); + switch (webkit_download_get_status(download)) { + case WEBKIT_DOWNLOAD_STATUS_FINISHED: + case WEBKIT_DOWNLOAD_STATUS_ERROR: + g_main_loop_quit(loop); + break; + case WEBKIT_DOWNLOAD_STATUS_CANCELLED: + g_assert_not_reached(); + break; + default: + break; + } +} + +static gboolean +set_filename(gchar* filename) +{ + gchar *uri = g_filename_to_uri(filename, NULL, NULL); + + webkit_download_set_destination_uri(theDownload, uri); + g_free(uri); + + webkit_download_start(theDownload); + return FALSE; +} + +static void +handle_download_requested_cb(WebKitDownload* download, + gboolean* beenThere, + gboolean asynch) +{ + theDownload = download; + *beenThere = TRUE; + + if (temporaryFilename) { + if (asynch) { + g_idle_add((GSourceFunc)set_filename, temporaryFilename); + } else { + gchar *uri = g_filename_to_uri(temporaryFilename, NULL, NULL); + if (uri) + webkit_download_set_destination_uri(download, uri); + g_free(uri); + } + } + + g_signal_connect(download, "notify::status", + G_CALLBACK(notify_status_cb), NULL); +} + +static gboolean +download_requested_cb(WebKitWebView* web_view, + WebKitDownload* download, + gboolean* beenThere) +{ + handle_download_requested_cb(download, beenThere, FALSE); + return TRUE; +} + +static gboolean +download_requested_asynch_cb(WebKitWebView* web_view, + WebKitDownload* download, + gboolean* beenThere) +{ + handle_download_requested_cb(download, beenThere, TRUE); + return TRUE; +} + +static void +test_webkit_download_perform(gboolean asynch) +{ + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + GCallback downloadRequestCallback = NULL; + + g_object_ref_sink(G_OBJECT(webView)); + + g_signal_connect(webView, "navigation-policy-decision-requested", + G_CALLBACK(navigation_policy_decision_requested_cb), + NULL); + + if (asynch) + downloadRequestCallback = G_CALLBACK(download_requested_asynch_cb); + else + downloadRequestCallback = G_CALLBACK(download_requested_cb); + + gboolean beenThere = FALSE; + g_signal_connect(webView, "download-requested", + downloadRequestCallback, &beenThere); + + /* Preparation; FIXME: we should move this code to a test + * utilities file, because we have a very similar one in + * testwebframe.c */ + GError *error = NULL; + gchar* filename; + int fd = g_file_open_tmp("webkit-testwebdownload-XXXXXX", &filename, &error); + close(fd); + + if (error) + g_critical("Failed to open a temporary file for writing: %s.", error->message); + + if (g_unlink(filename) == -1) + g_critical("Failed to delete the temporary file: %s.", g_strerror(errno)); + + theDownload = NULL; + temporaryFilename = filename; + + loop = g_main_loop_new(NULL, TRUE); + webkit_web_view_load_uri(webView, "http://gnome.org/"); + g_main_loop_run(loop); + + g_assert_cmpint(beenThere, ==, TRUE); + + g_assert_cmpint(g_file_test(temporaryFilename, G_FILE_TEST_IS_REGULAR), ==, TRUE); + + g_unlink(temporaryFilename); + g_free(temporaryFilename); + temporaryFilename = NULL; + + g_main_loop_unref(loop); + g_object_unref(webView); +} + +static void +test_webkit_download_synch(void) +{ + test_webkit_download_perform(FALSE); +} + +static void +test_webkit_download_asynch(void) +{ + test_webkit_download_perform(TRUE); +} + +static gboolean mime_type_policy_decision_requested_cb(WebKitWebView* view, WebKitWebFrame* frame, + WebKitNetworkRequest* request, const char* mime_type, + WebKitWebPolicyDecision* decision, gpointer data) +{ + webkit_web_policy_decision_download(decision); + return TRUE; +} + +static void idle_quit_loop_cb(WebKitWebView* web_view, GParamSpec* pspec, gpointer data) +{ + if (webkit_web_view_get_load_status(web_view) == WEBKIT_LOAD_FINISHED || + webkit_web_view_get_load_status(web_view) == WEBKIT_LOAD_FAILED) + g_main_loop_quit(loop); +} + +static void +test_webkit_download_data(void) +{ + gboolean beenThere = FALSE; + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(webView); + + g_signal_connect(webView, "download-requested", + G_CALLBACK(download_requested_cb), + &beenThere); + + g_signal_connect(webView, "notify::load-status", + G_CALLBACK(idle_quit_loop_cb), + NULL); + + g_signal_connect(webView, "mime-type-policy-decision-requested", + G_CALLBACK(mime_type_policy_decision_requested_cb), + NULL); + + loop = g_main_loop_new(NULL, TRUE); + + /* We're testing for a crash, so just not crashing is a pass */ + webkit_web_view_load_uri(webView, "data:application/octect-stream,"); + g_main_loop_run(loop); + + g_assert_cmpint(beenThere, ==, TRUE); + + g_main_loop_unref(loop); + g_object_unref(webView); +} + +int main(int argc, char** argv) +{ + g_thread_init(NULL); + gtk_test_init(&argc, &argv, NULL); + + g_test_bug_base("https://bugs.webkit.org/"); + g_test_add_func("/webkit/download/create", test_webkit_download_create); + g_test_add_func("/webkit/download/synch", test_webkit_download_synch); + g_test_add_func("/webkit/download/asynch", test_webkit_download_asynch); + g_test_add_func("/webkit/download/data", test_webkit_download_data); + return g_test_run (); +} + +#else + +int main(int argc, char** argv) +{ + g_critical("You will need at least GTK+ 2.14.0 to run the unit tests."); + return 0; +} + +#endif diff --git a/Source/WebKit/gtk/tests/testglobals.c b/Source/WebKit/gtk/tests/testglobals.c new file mode 100644 index 0000000..da0ffa3 --- /dev/null +++ b/Source/WebKit/gtk/tests/testglobals.c @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2010 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <gtk/gtk.h> +#include <libsoup/soup.h> +#include <webkit/webkit.h> + +#if GTK_CHECK_VERSION(2, 14, 0) + +// Make sure the session is initialized properly when webkit_get_default_session() is called. +static void test_globals_default_session() +{ + g_test_bug("36754"); + + SoupSession* session = webkit_get_default_session(); + soup_session_remove_feature_by_type(session, WEBKIT_TYPE_SOUP_AUTH_DIALOG); + + // This makes sure our initialization ran. + g_assert(soup_session_get_feature(session, SOUP_TYPE_CONTENT_DECODER) != NULL); + + // Creating a WebView should make sure the session is + // initialized, and not mess with our changes. + WebKitWebView* web_view = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(web_view); + g_object_unref(web_view); + + // These makes sure our modification was kept. + g_assert(soup_session_get_feature(session, SOUP_TYPE_CONTENT_DECODER) != NULL); + g_assert(soup_session_get_feature(session, WEBKIT_TYPE_SOUP_AUTH_DIALOG) == NULL); +} + +int main(int argc, char** argv) +{ + g_thread_init(NULL); + gtk_test_init(&argc, &argv, NULL); + + g_test_bug_base("https://bugs.webkit.org/"); + g_test_add_func("/webkit/globals/default_session", + test_globals_default_session); + return g_test_run(); +} + +#else +int main(int argc, char** argv) +{ + g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now."); + return 0; +} + +#endif diff --git a/Source/WebKit/gtk/tests/testhittestresult.c b/Source/WebKit/gtk/tests/testhittestresult.c new file mode 100644 index 0000000..0d7fb05 --- /dev/null +++ b/Source/WebKit/gtk/tests/testhittestresult.c @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2009 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <errno.h> +#include <unistd.h> +#include <glib/gstdio.h> +#include <webkit/webkit.h> + +#if GTK_CHECK_VERSION(2, 14, 0) + +typedef struct { + char* data; + guint flag; +} TestInfo; + +static GMainLoop* loop; + +typedef struct { + WebKitWebView* webView; + TestInfo* info; +} HitTestResultFixture; + +TestInfo* +test_info_new(const char* data, guint flag) +{ + TestInfo* info; + + info = g_slice_new(TestInfo); + info->data = g_strdup(data); + info->flag = flag; + + return info; +} + +void +test_info_destroy(TestInfo* info) +{ + g_free(info->data); + g_slice_free(TestInfo, info); +} + +static void hit_test_result_fixture_setup(HitTestResultFixture* fixture, gconstpointer data) +{ + fixture->webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(fixture->webView); + loop = g_main_loop_new(NULL, TRUE); + fixture->info = (TestInfo*)data; +} + +static void hit_test_result_fixture_teardown(HitTestResultFixture* fixture, gconstpointer data) +{ + g_object_unref(fixture->webView); + g_main_loop_unref(loop); + test_info_destroy(fixture->info); +} + +static void +load_status_cb(WebKitWebView* webView, + GParamSpec* spec, + gpointer data) +{ + WebKitLoadStatus status = webkit_web_view_get_load_status(webView); + TestInfo* info = (TestInfo*)data; + + if (status == WEBKIT_LOAD_FINISHED) { + WebKitHitTestResult* result; + guint context; + GdkEvent* event = gdk_event_new(GDK_BUTTON_PRESS); + WebKitDOMNode* node; + + /* Close enough to 0,0 */ + event->button.x = 5; + event->button.y = 5; + + result = webkit_web_view_get_hit_test_result(webView, (GdkEventButton*) event); + gdk_event_free(event); + g_assert(result); + + g_object_get(result, "context", &context, NULL); + g_assert(context & info->flag); + + g_object_get(result, "inner-node", &node, NULL); + g_assert(node); + g_assert(WEBKIT_DOM_IS_NODE(node)); + /* We can only test these node types at the moment. In the + * input case there seems to be an extra layer with a DIV on + * top of the input, which gets assigned to the inner-node. + * tag */ + if (info->flag == WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT) + g_assert(WEBKIT_DOM_IS_HTML_HTML_ELEMENT(node)); + else if (info->flag == WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE) + g_assert(WEBKIT_DOM_IS_HTML_IMAGE_ELEMENT(node)); + else if (info->flag == WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK) { + /* The hit test will give us the inner text node, we want + * the A tag */ + WebKitDOMNode* parent = webkit_dom_node_get_parent_node(node); + g_assert(WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT(parent)); + } + + g_object_unref(result); + g_main_loop_quit(loop); + } +} + +static void +test_webkit_hit_test_result(HitTestResultFixture* fixture, gconstpointer data) +{ + TestInfo* info = (TestInfo*)data; + GtkAllocation allocation = { 0, 0, 50, 50 }; + + webkit_web_view_load_string(fixture->webView, + info->data, + "text/html", + "utf-8", + "file://"); + gtk_widget_size_allocate(GTK_WIDGET(fixture->webView), &allocation); + g_signal_connect(fixture->webView, "notify::load-status", G_CALLBACK(load_status_cb), info); + g_main_loop_run(loop); +} + +int main(int argc, char** argv) +{ + g_thread_init(NULL); + gtk_test_init(&argc, &argv, NULL); + + g_test_bug_base("https://bugs.webkit.org/"); + + g_test_add("/webkit/hittestresult/document", HitTestResultFixture, + test_info_new("<html><body><h1>WebKitGTK+!</h1></body></html>", + WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT), + hit_test_result_fixture_setup, test_webkit_hit_test_result, hit_test_result_fixture_teardown); + /* We hardcode all elements to be at 0,0 so that we know where to + * generate the button events */ + g_test_add("/webkit/hittestresult/image", HitTestResultFixture, + test_info_new("<html><body><img style='position:absolute; left:0; top:0'src='0xdeadbeef' width=50 height=50></img></body></html>", + WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE), + hit_test_result_fixture_setup, test_webkit_hit_test_result, hit_test_result_fixture_teardown); + g_test_add("/webkit/hittestresult/editable", HitTestResultFixture, + test_info_new("<html><body><input style='position:absolute; left:0; top:0' size='35'></input>></body></html>", + WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE), + hit_test_result_fixture_setup, test_webkit_hit_test_result, hit_test_result_fixture_teardown); + g_test_add("/webkit/hittestresult/link", HitTestResultFixture, + test_info_new("<html><body><a style='position:absolute; left:0; top:0' href='http://www.example.com'>HELLO WORLD</a></body></html>", + WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK), + hit_test_result_fixture_setup, test_webkit_hit_test_result, hit_test_result_fixture_teardown); + + return g_test_run (); +} + +#else + +int main(int argc, char** argv) +{ + g_critical("You will need at least GTK+ 2.14.0 to run the unit tests."); + return 0; +} + +#endif diff --git a/Source/WebKit/gtk/tests/testhttpbackend.c b/Source/WebKit/gtk/tests/testhttpbackend.c new file mode 100644 index 0000000..f0fac16 --- /dev/null +++ b/Source/WebKit/gtk/tests/testhttpbackend.c @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2009 Gustavo Noronha Silva + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <errno.h> +#include <unistd.h> +#include <glib.h> +#include <glib/gstdio.h> +#include <gtk/gtk.h> +#include <webkit/webkit.h> + +#if GTK_CHECK_VERSION(2, 14, 0) + +// Not yet public API +SoupMessage* webkit_network_request_get_message(WebKitNetworkRequest* request); + +static gboolean navigation_policy_decision_requested_cb(WebKitWebView* web_view, + WebKitWebFrame* web_frame, + WebKitNetworkRequest* request, + WebKitWebNavigationAction* action, + WebKitWebPolicyDecision* decision, + gpointer data) +{ + SoupMessage* message = webkit_network_request_get_message(request); + + /* 1 -> webkit_network_request_with_core_request + * + * The SoupMessage is created exclusively for the emission of this + * signal. + */ + g_assert_cmpint(G_OBJECT(message)->ref_count, ==, 1); + + return FALSE; +} + +static void test_soup_message_lifetime() +{ + WebKitWebView* web_view = WEBKIT_WEB_VIEW(webkit_web_view_new()); + + g_object_ref_sink(web_view); + + g_signal_connect(web_view, "navigation-policy-decision-requested", + G_CALLBACK(navigation_policy_decision_requested_cb), + NULL); + + /* load_uri will trigger the navigation-policy-decision-requested + * signal emission; + */ + webkit_web_view_load_uri(web_view, "http://127.0.0.1/"); + + g_object_unref(web_view); +} + +int main(int argc, char** argv) +{ + g_thread_init(NULL); + gtk_test_init(&argc, &argv, NULL); + + g_test_bug_base("https://bugs.webkit.org/"); + g_test_add_func("/webkit/soupmessage/lifetime", test_soup_message_lifetime); + return g_test_run (); +} + +#else +int main(int argc, char** argv) +{ + g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now."); + return 0; +} + +#endif diff --git a/Source/WebKit/gtk/tests/testkeyevents.c b/Source/WebKit/gtk/tests/testkeyevents.c new file mode 100644 index 0000000..b41a032 --- /dev/null +++ b/Source/WebKit/gtk/tests/testkeyevents.c @@ -0,0 +1,402 @@ +/* + * Copyright (C) 2009, 2010 Martin Robinson <mrobinson@webkit.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <errno.h> +#include <unistd.h> +#include <string.h> +#include <glib/gstdio.h> +#include <webkit/webkit.h> +#include <JavaScriptCore/JSStringRef.h> +#include <JavaScriptCore/JSContextRef.h> + + +#if GTK_CHECK_VERSION(2, 14, 0) + +typedef struct { + char* page; + char* text; + gboolean shouldBeHandled; +} TestInfo; + +typedef struct { + GtkWidget* window; + WebKitWebView* webView; + GMainLoop* loop; + TestInfo* info; +} KeyEventFixture; + +TestInfo* +test_info_new(const char* page, gboolean shouldBeHandled) +{ + TestInfo* info; + + info = g_slice_new(TestInfo); + info->page = g_strdup(page); + info->shouldBeHandled = shouldBeHandled; + info->text = 0; + + return info; +} + +void +test_info_destroy(TestInfo* info) +{ + g_free(info->page); + g_free(info->text); + g_slice_free(TestInfo, info); +} + +static void key_event_fixture_setup(KeyEventFixture* fixture, gconstpointer data) +{ + fixture->loop = g_main_loop_new(NULL, TRUE); + + fixture->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + fixture->webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + + gtk_container_add(GTK_CONTAINER(fixture->window), GTK_WIDGET(fixture->webView)); +} + +static void key_event_fixture_teardown(KeyEventFixture* fixture, gconstpointer data) +{ + gtk_widget_destroy(fixture->window); + g_main_loop_unref(fixture->loop); + test_info_destroy(fixture->info); +} + +static gboolean key_press_event_cb(WebKitWebView* webView, GdkEvent* event, gpointer data) +{ + KeyEventFixture* fixture = (KeyEventFixture*)data; + gboolean handled = GTK_WIDGET_GET_CLASS(fixture->webView)->key_press_event(GTK_WIDGET(fixture->webView), &event->key); + g_assert_cmpint(handled, ==, fixture->info->shouldBeHandled); + + return FALSE; +} + +static gboolean key_release_event_cb(WebKitWebView* webView, GdkEvent* event, gpointer data) +{ + // WebCore never seems to mark keyup events as handled. + KeyEventFixture* fixture = (KeyEventFixture*)data; + gboolean handled = GTK_WIDGET_GET_CLASS(fixture->webView)->key_press_event(GTK_WIDGET(fixture->webView), &event->key); + g_assert(!handled); + + g_main_loop_quit(fixture->loop); + + return FALSE; +} + +static void test_keypress_events_load_status_cb(WebKitWebView* webView, GParamSpec* spec, gpointer data) +{ + KeyEventFixture* fixture = (KeyEventFixture*)data; + WebKitLoadStatus status = webkit_web_view_get_load_status(webView); + if (status == WEBKIT_LOAD_FINISHED) { + g_signal_connect(fixture->webView, "key-press-event", + G_CALLBACK(key_press_event_cb), fixture); + g_signal_connect(fixture->webView, "key-release-event", + G_CALLBACK(key_release_event_cb), fixture); + if (!gtk_test_widget_send_key(GTK_WIDGET(fixture->webView), + gdk_unicode_to_keyval('a'), 0)) + g_assert_not_reached(); + } + +} + +gboolean map_event_cb(GtkWidget *widget, GdkEvent* event, gpointer data) +{ + gtk_widget_grab_focus(widget); + KeyEventFixture* fixture = (KeyEventFixture*)data; + webkit_web_view_load_string(fixture->webView, fixture->info->page, + "text/html", "utf-8", "file://"); + return FALSE; +} + +static void setup_keyevent_test(KeyEventFixture* fixture, gconstpointer data, GCallback load_event_callback) +{ + fixture->info = (TestInfo*)data; + g_signal_connect(fixture->window, "map-event", + G_CALLBACK(map_event_cb), fixture); + + gtk_widget_show(fixture->window); + gtk_widget_show(GTK_WIDGET(fixture->webView)); + gtk_window_present(GTK_WINDOW(fixture->window)); + + g_signal_connect(fixture->webView, "notify::load-status", + load_event_callback, fixture); + + g_main_loop_run(fixture->loop); +} + +static void test_keypress_events(KeyEventFixture* fixture, gconstpointer data) +{ + setup_keyevent_test(fixture, data, G_CALLBACK(test_keypress_events_load_status_cb)); +} + +static gboolean element_text_equal_to(JSContextRef context, const gchar* text) +{ + JSStringRef scriptString = JSStringCreateWithUTF8CString( + "window.document.getElementById(\"in\").value;"); + JSValueRef value = JSEvaluateScript(context, scriptString, 0, 0, 0, 0); + JSStringRelease(scriptString); + + // If the value isn't a string, the element is probably a div + // so grab the innerText instead. + if (!JSValueIsString(context, value)) { + JSStringRef scriptString = JSStringCreateWithUTF8CString( + "window.document.getElementById(\"in\").innerText;"); + value = JSEvaluateScript(context, scriptString, 0, 0, 0, 0); + JSStringRelease(scriptString); + } + + g_assert(JSValueIsString(context, value)); + JSStringRef inputString = JSValueToStringCopy(context, value, 0); + g_assert(inputString); + + gint size = JSStringGetMaximumUTF8CStringSize(inputString); + gchar* cString = g_malloc(size); + JSStringGetUTF8CString(inputString, cString, size); + JSStringRelease(inputString); + + gboolean result = g_utf8_collate(cString, text) == 0; + g_free(cString); + return result; +} + +static void test_ime_load_status_cb(WebKitWebView* webView, GParamSpec* spec, gpointer data) +{ + KeyEventFixture* fixture = (KeyEventFixture*)data; + WebKitLoadStatus status = webkit_web_view_get_load_status(webView); + if (status != WEBKIT_LOAD_FINISHED) + return; + + JSGlobalContextRef context = webkit_web_frame_get_global_context( + webkit_web_view_get_main_frame(webView)); + g_assert(context); + + GtkIMContext* imContext = 0; + g_object_get(webView, "im-context", &imContext, NULL); + g_assert(imContext); + + // Test that commits that happen outside of key events + // change the text field immediately. This closely replicates + // the behavior of SCIM. + g_assert(element_text_equal_to(context, "")); + g_signal_emit_by_name(imContext, "commit", "a"); + g_assert(element_text_equal_to(context, "a")); + g_signal_emit_by_name(imContext, "commit", "b"); + g_assert(element_text_equal_to(context, "ab")); + g_signal_emit_by_name(imContext, "commit", "c"); + g_assert(element_text_equal_to(context, "abc")); + + g_object_unref(imContext); + g_main_loop_quit(fixture->loop); +} + +static void test_ime(KeyEventFixture* fixture, gconstpointer data) +{ + setup_keyevent_test(fixture, data, G_CALLBACK(test_ime_load_status_cb)); +} + +static gboolean verify_contents(gpointer data) +{ + KeyEventFixture* fixture = (KeyEventFixture*)data; + JSGlobalContextRef context = webkit_web_frame_get_global_context( + webkit_web_view_get_main_frame(fixture->webView)); + g_assert(context); + + g_assert(element_text_equal_to(context, fixture->info->text)); + g_main_loop_quit(fixture->loop); + return FALSE; +} + +static void test_blocking_load_status_cb(WebKitWebView* webView, GParamSpec* spec, gpointer data) +{ + KeyEventFixture* fixture = (KeyEventFixture*)data; + WebKitLoadStatus status = webkit_web_view_get_load_status(webView); + if (status != WEBKIT_LOAD_FINISHED) + return; + + // The first keypress event should not modify the field. + fixture->info->text = g_strdup("bc"); + if (!gtk_test_widget_send_key(GTK_WIDGET(fixture->webView), + gdk_unicode_to_keyval('a'), 0)) + g_assert_not_reached(); + if (!gtk_test_widget_send_key(GTK_WIDGET(fixture->webView), + gdk_unicode_to_keyval('b'), 0)) + g_assert_not_reached(); + if (!gtk_test_widget_send_key(GTK_WIDGET(fixture->webView), + gdk_unicode_to_keyval('c'), 0)) + g_assert_not_reached(); + + g_idle_add(verify_contents, fixture); +} + +static void test_blocking(KeyEventFixture* fixture, gconstpointer data) +{ + setup_keyevent_test(fixture, data, G_CALLBACK(test_blocking_load_status_cb)); +} + +#if defined(GDK_WINDOWING_X11) && GTK_CHECK_VERSION(2, 16, 0) +static void test_xim_load_status_cb(WebKitWebView* webView, GParamSpec* spec, gpointer data) +{ + KeyEventFixture* fixture = (KeyEventFixture*)data; + WebKitLoadStatus status = webkit_web_view_get_load_status(webView); + if (status != WEBKIT_LOAD_FINISHED) + return; + + GtkIMContext* imContext = 0; + g_object_get(webView, "im-context", &imContext, NULL); + g_assert(imContext); + + gchar* originalId = g_strdup(gtk_im_multicontext_get_context_id(GTK_IM_MULTICONTEXT(imContext))); + gtk_im_multicontext_set_context_id(GTK_IM_MULTICONTEXT(imContext), "xim"); + + // Test that commits that happen outside of key events + // change the text field immediately. This closely replicates + // the behavior of SCIM. + fixture->info->text = g_strdup("debian"); + if (!gtk_test_widget_send_key(GTK_WIDGET(fixture->webView), + gdk_unicode_to_keyval('d'), 0)) + g_assert_not_reached(); + if (!gtk_test_widget_send_key(GTK_WIDGET(fixture->webView), + gdk_unicode_to_keyval('e'), 0)) + g_assert_not_reached(); + if (!gtk_test_widget_send_key(GTK_WIDGET(fixture->webView), + gdk_unicode_to_keyval('b'), 0)) + g_assert_not_reached(); + if (!gtk_test_widget_send_key(GTK_WIDGET(fixture->webView), + gdk_unicode_to_keyval('i'), 0)) + g_assert_not_reached(); + if (!gtk_test_widget_send_key(GTK_WIDGET(fixture->webView), + gdk_unicode_to_keyval('a'), 0)) + g_assert_not_reached(); + if (!gtk_test_widget_send_key(GTK_WIDGET(fixture->webView), + gdk_unicode_to_keyval('n'), 0)) + g_assert_not_reached(); + + gtk_im_multicontext_set_context_id(GTK_IM_MULTICONTEXT(imContext), originalId); + g_free(originalId); + g_object_unref(imContext); + + g_idle_add(verify_contents, fixture); +} + +static void test_xim(KeyEventFixture* fixture, gconstpointer data) +{ + setup_keyevent_test(fixture, data, G_CALLBACK(test_xim_load_status_cb)); +} +#endif + +int main(int argc, char** argv) +{ + g_thread_init(NULL); + gtk_test_init(&argc, &argv, NULL); + + g_test_bug_base("https://bugs.webkit.org/"); + + + // We'll test input on a slew of different node types. Key events to + // text inputs and editable divs should be marked as handled. Key events + // to buttons and links should not. + const char* textinput_html = "<html><body><input id=\"in\" type=\"text\">" + "<script>document.getElementById('in').focus();</script></body></html>"; + const char* button_html = "<html><body><input id=\"in\" type=\"button\">" + "<script>document.getElementById('in').focus();</script></body></html>"; + const char* link_html = "<html><body><a href=\"http://www.gnome.org\" id=\"in\">" + "LINKY MCLINKERSON</a><script>document.getElementById('in').focus();</script>" + "</body></html>"; + const char* div_html = "<html><body><div id=\"in\" contenteditable=\"true\">" + "<script>document.getElementById('in').focus();</script></body></html>"; + + // These are similar to the blocks above, but they should block the first + // keypress modifying the editable node. + const char* textinput_html_blocking = "<html><body>" + "<input id=\"in\" type=\"text\" " + "onkeypress=\"if (first) {event.preventDefault();first=false;}\">" + "<script>first = true;\ndocument.getElementById('in').focus();</script>\n" + "</script></body></html>"; + const char* div_html_blocking = "<html><body>" + "<div id=\"in\" contenteditable=\"true\" " + "onkeypress=\"if (first) {event.preventDefault();first=false;}\">" + "<script>first = true; document.getElementById('in').focus();</script>\n" + "</script></body></html>"; + + g_test_add("/webkit/keyevents/event-textinput", KeyEventFixture, + test_info_new(textinput_html, TRUE), + key_event_fixture_setup, + test_keypress_events, + key_event_fixture_teardown); + g_test_add("/webkit/keyevents/event-buttons", KeyEventFixture, + test_info_new(button_html, FALSE), + key_event_fixture_setup, + test_keypress_events, + key_event_fixture_teardown); + g_test_add("/webkit/keyevents/event-link", KeyEventFixture, + test_info_new(link_html, FALSE), + key_event_fixture_setup, + test_keypress_events, + key_event_fixture_teardown); + g_test_add("/webkit/keyevent/event-div", KeyEventFixture, + test_info_new(div_html, TRUE), + key_event_fixture_setup, + test_keypress_events, + key_event_fixture_teardown); + g_test_add("/webkit/keyevent/ime-textinput", KeyEventFixture, + test_info_new(textinput_html, TRUE), + key_event_fixture_setup, + test_ime, + key_event_fixture_teardown); + g_test_add("/webkit/keyevent/ime-div", KeyEventFixture, + test_info_new(div_html, TRUE), + key_event_fixture_setup, + test_ime, + key_event_fixture_teardown); + g_test_add("/webkit/keyevent/block-textinput", KeyEventFixture, + test_info_new(textinput_html_blocking, TRUE), + key_event_fixture_setup, + test_blocking, + key_event_fixture_teardown); + g_test_add("/webkit/keyevent/block-div", KeyEventFixture, + test_info_new(div_html_blocking, TRUE), + key_event_fixture_setup, + test_blocking, + key_event_fixture_teardown); +#if defined(GDK_WINDOWING_X11) && GTK_CHECK_VERSION(2, 16, 0) + g_test_add("/webkit/keyevent/xim-textinput", KeyEventFixture, + test_info_new(textinput_html, TRUE), + key_event_fixture_setup, + test_xim, + key_event_fixture_teardown); + g_test_add("/webkit/keyevent/xim-div", KeyEventFixture, + test_info_new(div_html, TRUE), + key_event_fixture_setup, + test_xim, + key_event_fixture_teardown); +#endif + + return g_test_run(); +} + +#else + +int main(int argc, char** argv) +{ + g_critical("You will need at least GTK+ 2.14.0 to run the unit tests."); + return 0; +} + +#endif diff --git a/Source/WebKit/gtk/tests/testloading.c b/Source/WebKit/gtk/tests/testloading.c new file mode 100644 index 0000000..a0ec8c9 --- /dev/null +++ b/Source/WebKit/gtk/tests/testloading.c @@ -0,0 +1,445 @@ +/* + * Copyright (C) 2009, 2010 Gustavo Noronha Silva + * Copyright (C) 2009 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <gtk/gtk.h> +#include <libsoup/soup.h> +#include <string.h> +#include <webkit/webkit.h> + +#if GTK_CHECK_VERSION(2, 14, 0) + +/* This string has to be rather big because of the cancelled test - it + * looks like soup refuses to send or receive a too small chunk */ +#define HTML_STRING "<html><body>Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!</body></html>" + +SoupURI* base_uri; + +/* For real request testing */ +static void +server_callback(SoupServer* server, SoupMessage* msg, + const char* path, GHashTable* query, + SoupClientContext* context, gpointer data) +{ + if (msg->method != SOUP_METHOD_GET) { + soup_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED); + return; + } + + soup_message_set_status(msg, SOUP_STATUS_OK); + + if (g_str_equal(path, "/test_loading_status") || g_str_equal(path, "/test_loading_status2")) + soup_message_body_append(msg->response_body, SOUP_MEMORY_STATIC, HTML_STRING, strlen(HTML_STRING)); + else if (g_str_equal(path, "/test_load_error")) { + soup_message_set_status(msg, SOUP_STATUS_CANT_CONNECT); + } else if (g_str_equal(path, "/test_loading_cancelled")) { + soup_message_headers_set_encoding(msg->response_headers, SOUP_ENCODING_CHUNKED); + soup_message_body_append(msg->response_body, SOUP_MEMORY_STATIC, HTML_STRING, strlen(HTML_STRING)); + soup_server_unpause_message(server, msg); + return; + } + + soup_message_body_complete(msg->response_body); +} + +typedef struct { + WebKitWebView* webView; + GMainLoop *loop; + gboolean has_been_provisional; + gboolean has_been_committed; + gboolean has_been_first_visually_non_empty_layout; + gboolean has_been_finished; + gboolean has_been_failed; + gboolean has_been_load_error; +} WebLoadingFixture; + +static void web_loading_fixture_setup(WebLoadingFixture* fixture, gconstpointer data) +{ + fixture->webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + fixture->loop = g_main_loop_new(NULL, TRUE); + g_object_ref_sink(fixture->webView); + fixture->has_been_provisional = FALSE; + fixture->has_been_committed = FALSE; + fixture->has_been_first_visually_non_empty_layout = FALSE; + fixture->has_been_finished = FALSE; + fixture->has_been_failed = FALSE; + fixture->has_been_load_error = FALSE; +} + +static void web_loading_fixture_teardown(WebLoadingFixture* fixture, gconstpointer data) +{ + g_object_unref(fixture->webView); + g_main_loop_unref(fixture->loop); +} + +static char* get_uri_for_path(const char* path) +{ + SoupURI* uri; + char* uri_string; + + uri = soup_uri_new_with_base(base_uri, path); + uri_string = soup_uri_to_string(uri, FALSE); + soup_uri_free (uri); + + return uri_string; +} + +static void load_finished_cb(WebKitWebView* web_view, WebKitWebFrame* web_frame, WebLoadingFixture* fixture) +{ + g_assert(fixture->has_been_provisional); + g_assert(fixture->has_been_committed); + g_assert(fixture->has_been_first_visually_non_empty_layout); + + g_main_loop_quit(fixture->loop); +} + + +static void status_changed_cb(GObject* object, GParamSpec* pspec, WebLoadingFixture* fixture) +{ + WebKitLoadStatus status = webkit_web_view_get_load_status(WEBKIT_WEB_VIEW(object)); + + switch (status) { + case WEBKIT_LOAD_PROVISIONAL: + g_assert(!fixture->has_been_provisional); + g_assert(!fixture->has_been_committed); + g_assert(!fixture->has_been_first_visually_non_empty_layout); + fixture->has_been_provisional = TRUE; + break; + case WEBKIT_LOAD_COMMITTED: + g_assert(fixture->has_been_provisional); + g_assert(!fixture->has_been_committed); + g_assert(!fixture->has_been_first_visually_non_empty_layout); + fixture->has_been_committed = TRUE; + break; + case WEBKIT_LOAD_FIRST_VISUALLY_NON_EMPTY_LAYOUT: + g_assert(fixture->has_been_provisional); + g_assert(fixture->has_been_committed); + g_assert(!fixture->has_been_first_visually_non_empty_layout); + fixture->has_been_first_visually_non_empty_layout = TRUE; + break; + case WEBKIT_LOAD_FINISHED: + g_assert(fixture->has_been_provisional); + g_assert(fixture->has_been_committed); + g_assert(fixture->has_been_first_visually_non_empty_layout); + break; + default: + g_assert_not_reached(); + } +} + +static void test_loading_status(WebLoadingFixture* fixture, gconstpointer data) +{ + char* uri_string; + + g_assert_cmpint(webkit_web_view_get_load_status(fixture->webView), ==, WEBKIT_LOAD_PROVISIONAL); + + g_object_connect(G_OBJECT(fixture->webView), + "signal::notify::load-status", G_CALLBACK(status_changed_cb), fixture, + "signal::load-finished", G_CALLBACK(load_finished_cb), fixture, + NULL); + + uri_string = get_uri_for_path("/test_loading_status"); + + /* load_uri will trigger the navigation-policy-decision-requested + * signal emission; + */ + webkit_web_view_load_uri(fixture->webView, uri_string); + g_free(uri_string); + + g_main_loop_run(fixture->loop); +} + +static void load_error_status_changed_cb(GObject* object, GParamSpec* pspec, WebLoadingFixture* fixture) +{ + WebKitLoadStatus status = webkit_web_view_get_load_status(WEBKIT_WEB_VIEW(object)); + + switch(status) { + case WEBKIT_LOAD_PROVISIONAL: + g_assert(!fixture->has_been_provisional); + fixture->has_been_provisional = TRUE; + break; + case WEBKIT_LOAD_COMMITTED: + g_assert(!fixture->has_been_committed); + fixture->has_been_committed = TRUE; + break; + case WEBKIT_LOAD_FINISHED: + g_assert(fixture->has_been_provisional); + g_assert(fixture->has_been_load_error); + g_assert(fixture->has_been_failed); + g_assert(!fixture->has_been_finished); + fixture->has_been_finished = TRUE; + break; + case WEBKIT_LOAD_FAILED: + g_assert(!fixture->has_been_failed); + fixture->has_been_failed = TRUE; + g_main_loop_quit(fixture->loop); + break; + default: + break; + } +} + +static gboolean load_error_cb(WebKitWebView* webView, WebKitWebFrame* frame, const char* uri, GError *error, WebLoadingFixture* fixture) +{ + g_assert(fixture->has_been_provisional); + g_assert(!fixture->has_been_load_error); + fixture->has_been_load_error = TRUE; + + return FALSE; +} + +static void test_loading_error(WebLoadingFixture* fixture, gconstpointer data) +{ + char* uri_string; + + g_test_bug("28842"); + + g_signal_connect(fixture->webView, "load-error", G_CALLBACK(load_error_cb), fixture); + g_signal_connect(fixture->webView, "notify::load-status", G_CALLBACK(load_error_status_changed_cb), fixture); + + uri_string = get_uri_for_path("/test_load_error"); + webkit_web_view_load_uri(fixture->webView, uri_string); + g_free(uri_string); + + g_main_loop_run(fixture->loop); + + g_assert(fixture->has_been_provisional); + g_assert(!fixture->has_been_committed); + g_assert(fixture->has_been_load_error); + g_assert(fixture->has_been_failed); + g_assert(!fixture->has_been_finished); +} + +/* Cancelled load */ + +static gboolean load_cancelled_cb(WebKitWebView* webView, WebKitWebFrame* frame, const char* uri, GError *error, WebLoadingFixture* fixture) +{ + g_assert(fixture->has_been_provisional); + g_assert(fixture->has_been_failed); + g_assert(!fixture->has_been_load_error); + g_assert(error->code == WEBKIT_NETWORK_ERROR_CANCELLED); + fixture->has_been_load_error = TRUE; + + return TRUE; +} + +static gboolean stop_load (gpointer data) +{ + webkit_web_view_stop_loading(WEBKIT_WEB_VIEW(data)); + return FALSE; +} + +static void load_cancelled_status_changed_cb(GObject* object, GParamSpec* pspec, WebLoadingFixture* fixture) +{ + WebKitLoadStatus status = webkit_web_view_get_load_status(WEBKIT_WEB_VIEW(object)); + + switch(status) { + case WEBKIT_LOAD_PROVISIONAL: + g_assert(!fixture->has_been_provisional); + g_assert(!fixture->has_been_failed); + fixture->has_been_provisional = TRUE; + break; + case WEBKIT_LOAD_COMMITTED: + g_idle_add (stop_load, object); + break; + case WEBKIT_LOAD_FAILED: + g_assert(fixture->has_been_provisional); + g_assert(!fixture->has_been_failed); + g_assert(!fixture->has_been_load_error); + fixture->has_been_failed = TRUE; + g_main_loop_quit(fixture->loop); + break; + case WEBKIT_LOAD_FINISHED: + g_assert_not_reached(); + break; + default: + break; + } +} + +static void test_loading_cancelled(WebLoadingFixture* fixture, gconstpointer data) +{ + char* uri_string; + + g_test_bug("29644"); + + g_signal_connect(fixture->webView, "load-error", G_CALLBACK(load_cancelled_cb), fixture); + g_signal_connect(fixture->webView, "notify::load-status", G_CALLBACK(load_cancelled_status_changed_cb), fixture); + + uri_string = get_uri_for_path("/test_loading_cancelled"); + webkit_web_view_load_uri(fixture->webView, uri_string); + g_free(uri_string); + + g_main_loop_run(fixture->loop); +} + +static void load_goback_status_changed_cb(GObject* object, GParamSpec* pspec, WebLoadingFixture* fixture) +{ + WebKitLoadStatus status = webkit_web_view_get_load_status(WEBKIT_WEB_VIEW(object)); + + switch(status) { + case WEBKIT_LOAD_PROVISIONAL: + g_assert(!fixture->has_been_provisional); + fixture->has_been_provisional = TRUE; + break; + case WEBKIT_LOAD_COMMITTED: + g_assert(fixture->has_been_provisional); + fixture->has_been_committed = TRUE; + break; + case WEBKIT_LOAD_FAILED: + g_assert_not_reached(); + break; + case WEBKIT_LOAD_FINISHED: + g_assert(fixture->has_been_provisional); + g_assert(fixture->has_been_committed); + fixture->has_been_finished = TRUE; + g_main_loop_quit(fixture->loop); + break; + default: + break; + } +} + +static void load_wentback_status_changed_cb(GObject* object, GParamSpec* pspec, WebLoadingFixture* fixture) +{ + WebKitLoadStatus status = webkit_web_view_get_load_status(WEBKIT_WEB_VIEW(object)); + char* uri_string; + char* uri_string2; + + uri_string = get_uri_for_path("/test_loading_status"); + uri_string2 = get_uri_for_path("/test_loading_status2"); + + switch(status) { + case WEBKIT_LOAD_PROVISIONAL: + g_assert_cmpstr(webkit_web_view_get_uri(fixture->webView), ==, uri_string2); + break; + case WEBKIT_LOAD_COMMITTED: + g_assert_cmpstr(webkit_web_view_get_uri(fixture->webView), ==, uri_string); + break; + case WEBKIT_LOAD_FAILED: + g_assert_not_reached(); + break; + case WEBKIT_LOAD_FINISHED: + g_assert_cmpstr(webkit_web_view_get_uri(fixture->webView), ==, uri_string); + g_main_loop_quit(fixture->loop); + break; + default: + break; + } + + g_free(uri_string); + g_free(uri_string2); +} + +static void load_error_test(WebKitWebView* webview, WebKitWebFrame* frame, const char* uri, GError* error) +{ + g_debug("Error: %s", error->message); +} + +static void test_loading_goback(WebLoadingFixture* fixture, gconstpointer data) +{ + char* uri_string; + + g_signal_connect(fixture->webView, "notify::load-status", G_CALLBACK(load_goback_status_changed_cb), fixture); + + g_signal_connect(fixture->webView, "load-error", G_CALLBACK(load_error_test), fixture); + + uri_string = get_uri_for_path("/test_loading_status"); + webkit_web_view_load_uri(fixture->webView, uri_string); + g_free(uri_string); + + g_main_loop_run(fixture->loop); + + fixture->has_been_provisional = FALSE; + fixture->has_been_committed = FALSE; + fixture->has_been_first_visually_non_empty_layout = FALSE; + fixture->has_been_finished = FALSE; + fixture->has_been_failed = FALSE; + fixture->has_been_load_error = FALSE; + + uri_string = get_uri_for_path("/test_loading_status2"); + webkit_web_view_load_uri(fixture->webView, uri_string); + g_free(uri_string); + + g_main_loop_run(fixture->loop); + + g_signal_handlers_disconnect_by_func(fixture->webView, load_goback_status_changed_cb, fixture); + + fixture->has_been_provisional = FALSE; + fixture->has_been_committed = FALSE; + fixture->has_been_first_visually_non_empty_layout = FALSE; + fixture->has_been_finished = FALSE; + fixture->has_been_failed = FALSE; + fixture->has_been_load_error = FALSE; + + g_signal_connect(fixture->webView, "notify::load-status", G_CALLBACK(load_wentback_status_changed_cb), fixture); + webkit_web_view_go_back(fixture->webView); + + g_main_loop_run(fixture->loop); + + g_signal_handlers_disconnect_by_func(fixture->webView, load_wentback_status_changed_cb, fixture); +} + +int main(int argc, char** argv) +{ + SoupServer* server; + + g_thread_init(NULL); + gtk_test_init(&argc, &argv, NULL); + + server = soup_server_new(SOUP_SERVER_PORT, 0, NULL); + soup_server_run_async(server); + + soup_server_add_handler(server, NULL, server_callback, NULL, NULL); + + base_uri = soup_uri_new("http://127.0.0.1/"); + soup_uri_set_port(base_uri, soup_server_get_port(server)); + + g_test_bug_base("https://bugs.webkit.org/"); + g_test_add("/webkit/loading/status", + WebLoadingFixture, NULL, + web_loading_fixture_setup, + test_loading_status, + web_loading_fixture_teardown); + g_test_add("/webkit/loading/error", + WebLoadingFixture, NULL, + web_loading_fixture_setup, + test_loading_error, + web_loading_fixture_teardown); + g_test_add("/webkit/loading/cancelled", + WebLoadingFixture, NULL, + web_loading_fixture_setup, + test_loading_cancelled, + web_loading_fixture_teardown); + g_test_add("/webkit/loading/goback", + WebLoadingFixture, NULL, + web_loading_fixture_setup, + test_loading_goback, + web_loading_fixture_teardown); + return g_test_run(); +} + +#else +int main(int argc, char** argv) +{ + g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now."); + return 0; +} + +#endif diff --git a/Source/WebKit/gtk/tests/testmimehandling.c b/Source/WebKit/gtk/tests/testmimehandling.c new file mode 100644 index 0000000..41e170a --- /dev/null +++ b/Source/WebKit/gtk/tests/testmimehandling.c @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2009 Jan Michael Alonzo + * Copyright (C) 2009 Gustavo Noronha Silva + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "test_utils.h" + +#include <glib.h> +#include <glib/gstdio.h> +#include <libsoup/soup.h> +#include <string.h> +#include <webkit/webkit.h> +#include <unistd.h> + +#if GTK_CHECK_VERSION(2, 14, 0) + +GMainLoop* loop; +SoupSession *session; +char* base_uri; + +/* For real request testing */ +static void +server_callback(SoupServer *server, SoupMessage *msg, + const char *path, GHashTable *query, + SoupClientContext *context, gpointer data) +{ + if (msg->method != SOUP_METHOD_GET) { + soup_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED); + return; + } + + soup_message_set_status(msg, SOUP_STATUS_OK); + + /* PDF */ + if (g_str_equal(path, "/pdf")) { + char* contents; + gsize length; + GError* error = NULL; + + g_file_get_contents("test.pdf", &contents, &length, &error); + g_assert(!error); + + soup_message_body_append(msg->response_body, SOUP_MEMORY_TAKE, contents, length); + } else if (g_str_equal(path, "/html")) { + char* contents; + gsize length; + GError* error = NULL; + + g_file_get_contents("test.html", &contents, &length, &error); + g_assert(!error); + + soup_message_body_append(msg->response_body, SOUP_MEMORY_TAKE, contents, length); + } else if (g_str_equal(path, "/text")) { + char* contents; + gsize length; + GError* error = NULL; + + soup_message_headers_append(msg->response_headers, "Content-Disposition", "attachment; filename=test.txt"); + + g_file_get_contents("test.txt", &contents, &length, &error); + g_assert(!error); + + soup_message_body_append(msg->response_body, SOUP_MEMORY_TAKE, contents, length); + } else if (g_str_equal(path, "/ogg")) { + char* contents; + gsize length; + GError* error = NULL; + + g_file_get_contents("test.ogg", &contents, &length, &error); + g_assert(!error); + + soup_message_body_append(msg->response_body, SOUP_MEMORY_TAKE, contents, length); + } + + soup_message_body_complete(msg->response_body); +} + +static void idle_quit_loop_cb(WebKitWebView* web_view, GParamSpec* pspec, gpointer data) +{ + if (webkit_web_view_get_load_status(web_view) == WEBKIT_LOAD_FINISHED || + webkit_web_view_get_load_status(web_view) == WEBKIT_LOAD_FAILED) + g_main_loop_quit(loop); +} + +static gboolean mime_type_policy_decision_requested_cb(WebKitWebView* view, WebKitWebFrame* frame, + WebKitNetworkRequest* request, const char* mime_type, + WebKitWebPolicyDecision* decision, gpointer data) +{ + char* type = (char*)data; + + if (g_str_equal(type, "pdf")) { + g_assert_cmpstr(mime_type, ==, "application/pdf"); + g_assert(!webkit_web_view_can_show_mime_type(view, mime_type)); + } else if (g_str_equal(type, "html")) { + g_assert_cmpstr(mime_type, ==, "text/html"); + g_assert(webkit_web_view_can_show_mime_type(view, mime_type)); + } else if (g_str_equal(type, "text")) { + WebKitNetworkResponse* response = webkit_web_frame_get_network_response(frame); + SoupMessage* message = webkit_network_response_get_message(response); + char* disposition; + + g_assert(message); + soup_message_headers_get_content_disposition(message->response_headers, + &disposition, NULL); + g_object_unref(response); + + g_assert_cmpstr(disposition, ==, "attachment"); + g_free(disposition); + + g_assert_cmpstr(mime_type, ==, "text/plain"); + g_assert(webkit_web_view_can_show_mime_type(view, mime_type)); + } else if (g_str_equal(type, "ogg")) { + g_assert_cmpstr(mime_type, ==, "audio/x-vorbis+ogg"); + g_assert(webkit_web_view_can_show_mime_type(view, mime_type)); + } + + g_free(type); + + return FALSE; +} + +static void testRemoteMimeType(const void* data) +{ + const char* name = (const char*) data; + WebKitWebView* view = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(G_OBJECT(view)); + + loop = g_main_loop_new(NULL, TRUE); + + g_object_connect(G_OBJECT(view), + "signal::notify::load-status", idle_quit_loop_cb, NULL, + "signal::mime-type-policy-decision-requested", mime_type_policy_decision_requested_cb, g_strdup(name), + NULL); + + char* effective_uri = g_strdup_printf("%s%s", base_uri, name); + webkit_web_view_load_uri(view, effective_uri); + g_free(effective_uri); + + g_main_loop_run(loop); + + g_object_unref(view); +} + +static void testLocalMimeType(const void* data) +{ + const char* typeName = (const char*) data; + WebKitWebView* view = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(G_OBJECT(view)); + + loop = g_main_loop_new(NULL, TRUE); + + g_object_connect(G_OBJECT(view), + "signal::notify::load-status", idle_quit_loop_cb, NULL, + "signal::mime-type-policy-decision-requested", mime_type_policy_decision_requested_cb, g_strdup(typeName), + NULL); + + gchar* filename = g_strdup_printf("test.%s", typeName); + GFile* file = g_file_new_for_path(filename); + g_free(filename); + + gchar* fileURI = g_file_get_uri(file); + g_object_unref(file); + + webkit_web_view_load_uri(view, fileURI); + g_free(fileURI); + + g_main_loop_run(loop); + g_object_unref(view); +} + +int main(int argc, char** argv) +{ + SoupServer* server; + SoupURI* soup_uri; + + g_thread_init(NULL); + gtk_test_init(&argc, &argv, NULL); + + /* Hopefully make test independent of the path it's called from. */ + testutils_relative_chdir("Source/WebKit/gtk/tests/resources/test.html", argv[0]); + + server = soup_server_new(SOUP_SERVER_PORT, 0, NULL); + soup_server_run_async(server); + + soup_server_add_handler(server, NULL, server_callback, NULL, NULL); + + soup_uri = soup_uri_new("http://127.0.0.1/"); + soup_uri_set_port(soup_uri, soup_server_get_port(server)); + + base_uri = soup_uri_to_string(soup_uri, FALSE); + soup_uri_free(soup_uri); + + g_test_bug_base("https://bugs.webkit.org/"); + g_test_add_data_func("/webkit/mime/remote-PDF", "pdf", testRemoteMimeType); + g_test_add_data_func("/webkit/mime/remote-HTML", "html", testRemoteMimeType); + g_test_add_data_func("/webkit/mime/remote-TEXT", "text", testRemoteMimeType); + g_test_add_data_func("/webkit/mime/remote-OGG", "ogg", testRemoteMimeType); + g_test_add_data_func("/webkit/mime/local-PDF", "pdf", testLocalMimeType); + g_test_add_data_func("/webkit/mime/local-HTML", "html", testLocalMimeType); + g_test_add_data_func("/webkit/mime/local-TEXT", "text", testLocalMimeType); + g_test_add_data_func("/webkit/mime/local-OGG", "ogg", testLocalMimeType); + + return g_test_run(); +} + +#else +int main(int argc, char** argv) +{ + g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now."); + return 0; +} + +#endif diff --git a/Source/WebKit/gtk/tests/testnetworkrequest.c b/Source/WebKit/gtk/tests/testnetworkrequest.c new file mode 100644 index 0000000..fb6ec41 --- /dev/null +++ b/Source/WebKit/gtk/tests/testnetworkrequest.c @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2009 Gustavo Noronha Silva + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <errno.h> +#include <unistd.h> +#include <glib.h> +#include <glib/gstdio.h> +#include <gtk/gtk.h> +#include <stdlib.h> +#include <webkit/webkit.h> + +#if GTK_CHECK_VERSION(2, 14, 0) + +static void test_network_request_create_destroy() +{ + WebKitNetworkRequest* request; + SoupMessage* message; + + /* Test creation with URI */ + request = WEBKIT_NETWORK_REQUEST(g_object_new(WEBKIT_TYPE_NETWORK_REQUEST, "uri", "http://debian.org/", NULL)); + g_assert(WEBKIT_IS_NETWORK_REQUEST(request)); + message = webkit_network_request_get_message(request); + g_assert(!message); + g_object_unref(request); + + /* Test creation with SoupMessage */ + message = soup_message_new("GET", "http://debian.org/"); + request = WEBKIT_NETWORK_REQUEST(g_object_new(WEBKIT_TYPE_NETWORK_REQUEST, "message", message, NULL)); + g_assert(WEBKIT_IS_NETWORK_REQUEST(request)); + g_assert_cmpint(G_OBJECT(message)->ref_count, ==, 2); + g_object_unref(request); + g_assert_cmpint(G_OBJECT(message)->ref_count, ==, 1); + g_object_unref(message); + + /* Test creation with both SoupMessage and URI */ + message = soup_message_new("GET", "http://debian.org/"); + request = WEBKIT_NETWORK_REQUEST(g_object_new(WEBKIT_TYPE_NETWORK_REQUEST, "message", message, "uri", "http://gnome.org/", NULL)); + g_assert(WEBKIT_IS_NETWORK_REQUEST(request)); + g_assert_cmpint(G_OBJECT(message)->ref_count, ==, 2); + g_assert_cmpstr(webkit_network_request_get_uri(request), ==, "http://gnome.org/"); + g_object_unref(request); + g_assert_cmpint(G_OBJECT(message)->ref_count, ==, 1); + g_object_unref(message); +} + +static void test_network_request_properties() +{ + WebKitNetworkRequest* request; + SoupMessage* message; + gchar* soupURI; + + /* Test URI is set correctly when creating with URI */ + request = webkit_network_request_new("http://debian.org/"); + g_assert(WEBKIT_IS_NETWORK_REQUEST(request)); + g_assert_cmpstr(webkit_network_request_get_uri(request), ==, "http://debian.org/"); + g_object_unref(request); + + /* Test URI is set correctly when creating with Message */ + message = soup_message_new("GET", "http://debian.org/"); + request = WEBKIT_NETWORK_REQUEST(g_object_new(WEBKIT_TYPE_NETWORK_REQUEST, "message", message, NULL)); + g_assert(WEBKIT_IS_NETWORK_REQUEST(request)); + g_object_unref(message); + + message = webkit_network_request_get_message(request); + soupURI = soup_uri_to_string(soup_message_get_uri(message), FALSE); + g_assert_cmpstr(soupURI, ==, "http://debian.org/"); + g_free(soupURI); + + g_assert_cmpstr(webkit_network_request_get_uri(request), ==, "http://debian.org/"); + g_object_unref(request); +} + +int main(int argc, char** argv) +{ + g_thread_init(NULL); + gtk_test_init(&argc, &argv, NULL); + + g_test_bug_base("https://bugs.webkit.org/"); + g_test_add_func("/webkit/networkrequest/createdestroy", test_network_request_create_destroy); + g_test_add_func("/webkit/networkrequest/properties", test_network_request_properties); + return g_test_run (); +} + +#else +int main(int argc, char** argv) +{ + g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now."); + return 0; +} + +#endif diff --git a/Source/WebKit/gtk/tests/testnetworkresponse.c b/Source/WebKit/gtk/tests/testnetworkresponse.c new file mode 100644 index 0000000..90062c6 --- /dev/null +++ b/Source/WebKit/gtk/tests/testnetworkresponse.c @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2009 Gustavo Noronha Silva + * Copyright (C) 2009 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <errno.h> +#include <unistd.h> +#include <glib.h> +#include <glib/gstdio.h> +#include <gtk/gtk.h> +#include <stdlib.h> +#include <webkit/webkit.h> + +#if GTK_CHECK_VERSION(2, 14, 0) + +static void test_network_response_create_destroy() +{ + WebKitNetworkResponse* response; + SoupMessage* message; + + /* Test creation with URI */ + response = WEBKIT_NETWORK_RESPONSE(g_object_new(WEBKIT_TYPE_NETWORK_RESPONSE, "uri", "http://debian.org/", NULL)); + g_assert(WEBKIT_IS_NETWORK_RESPONSE(response)); + message = webkit_network_response_get_message(response); + g_assert(!message); + g_object_unref(response); + + /* Test creation with SoupMessage */ + message = soup_message_new("GET", "http://debian.org/"); + response = WEBKIT_NETWORK_RESPONSE(g_object_new(WEBKIT_TYPE_NETWORK_RESPONSE, "message", message, NULL)); + g_assert(WEBKIT_IS_NETWORK_RESPONSE(response)); + g_assert_cmpint(G_OBJECT(message)->ref_count, ==, 2); + g_object_unref(response); + g_assert_cmpint(G_OBJECT(message)->ref_count, ==, 1); + g_object_unref(message); + + /* Test creation with both SoupMessage and URI */ + message = soup_message_new("GET", "http://debian.org/"); + response = WEBKIT_NETWORK_RESPONSE(g_object_new(WEBKIT_TYPE_NETWORK_RESPONSE, "message", message, "uri", "http://gnome.org/", NULL)); + g_assert(WEBKIT_IS_NETWORK_RESPONSE(response)); + g_assert_cmpint(G_OBJECT(message)->ref_count, ==, 2); + g_assert_cmpstr(webkit_network_response_get_uri(response), ==, "http://gnome.org/"); + g_object_unref(response); + g_assert_cmpint(G_OBJECT(message)->ref_count, ==, 1); + g_object_unref(message); +} + +static void test_network_response_properties() +{ + WebKitNetworkResponse* response; + SoupMessage* message; + gchar* soupURI; + + /* Test URI is set correctly when creating with URI */ + response = webkit_network_response_new("http://debian.org/"); + g_assert(WEBKIT_IS_NETWORK_RESPONSE(response)); + g_assert_cmpstr(webkit_network_response_get_uri(response), ==, "http://debian.org/"); + g_object_unref(response); + + /* Test URI is set correctly when creating with Message */ + message = soup_message_new("GET", "http://debian.org/"); + response = WEBKIT_NETWORK_RESPONSE(g_object_new(WEBKIT_TYPE_NETWORK_RESPONSE, "message", message, NULL)); + g_assert(WEBKIT_IS_NETWORK_RESPONSE(response)); + g_object_unref(message); + + message = webkit_network_response_get_message(response); + soupURI = soup_uri_to_string(soup_message_get_uri(message), FALSE); + g_assert_cmpstr(soupURI, ==, "http://debian.org/"); + g_free(soupURI); + + g_assert_cmpstr(webkit_network_response_get_uri(response), ==, "http://debian.org/"); + g_object_unref(response); +} + +int main(int argc, char** argv) +{ + g_thread_init(NULL); + gtk_test_init(&argc, &argv, NULL); + + g_test_bug_base("https://bugs.webkit.org/"); + g_test_add_func("/webkit/networkresponse/createdestroy", test_network_response_create_destroy); + g_test_add_func("/webkit/networkresponse/properties", test_network_response_properties); + return g_test_run (); +} + +#else +int main(int argc, char** argv) +{ + g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now."); + return 0; +} + +#endif diff --git a/Source/WebKit/gtk/tests/testwebbackforwardlist.c b/Source/WebKit/gtk/tests/testwebbackforwardlist.c new file mode 100644 index 0000000..b9e395e --- /dev/null +++ b/Source/WebKit/gtk/tests/testwebbackforwardlist.c @@ -0,0 +1,337 @@ +/* + * Copyright (C) 2008 Holger Hans Peter Freyther + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <glib.h> +#include <gtk/gtk.h> +#include <webkit/webkit.h> + +#if GTK_CHECK_VERSION(2, 14, 0) + +static void test_webkit_web_history_item_lifetime(void) +{ + WebKitWebView* webView; + WebKitWebBackForwardList* backForwardList; + WebKitWebHistoryItem* currentItem; + WebKitWebHistoryItem* forwardItem; + WebKitWebHistoryItem* backItem; + WebKitWebHistoryItem* nthItem; + WebKitWebHistoryItem* item1; + WebKitWebHistoryItem* item2; + WebKitWebHistoryItem* item3; + WebKitWebHistoryItem* item4; + GList* backList = NULL; + GList* forwardList = NULL; + g_test_bug("19898"); + + webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(webView); + backForwardList = webkit_web_view_get_back_forward_list(webView); + g_assert_cmpint(G_OBJECT(backForwardList)->ref_count, ==, 1); + + /* add test items */ + item1 = webkit_web_history_item_new_with_data("http://example.com/1/", "Site 1"); + webkit_web_back_forward_list_add_item(backForwardList, item1); + g_object_unref(item1); + + item2 = webkit_web_history_item_new_with_data("http://example.com/2/", "Site 2"); + webkit_web_back_forward_list_add_item(backForwardList, item2); + g_object_unref(item2); + + item3 = webkit_web_history_item_new_with_data("http://example.com/3/", "Site 3"); + webkit_web_back_forward_list_add_item(backForwardList, item3); + g_object_unref(item3); + + item4 = webkit_web_history_item_new_with_data("http://example.com/4/", "Site 4"); + webkit_web_back_forward_list_add_item(backForwardList, item4); + g_object_unref(item4); + + /* make sure these functions don't add unnecessary ref to the history item */ + backItem = webkit_web_back_forward_list_get_back_item(backForwardList); + g_object_ref(backItem); + g_assert_cmpint(G_OBJECT(backItem)->ref_count, ==, 2); + g_object_unref(backItem); + g_assert_cmpint(G_OBJECT(backItem)->ref_count, ==, 1); + + currentItem = webkit_web_back_forward_list_get_current_item(backForwardList); + g_object_ref(currentItem); + g_assert_cmpint(G_OBJECT(currentItem)->ref_count, ==, 2); + g_object_unref(currentItem); + g_assert_cmpint(G_OBJECT(currentItem)->ref_count, ==, 1); + + webkit_web_back_forward_list_go_to_item(backForwardList, item2); + forwardItem = webkit_web_back_forward_list_get_forward_item(backForwardList); + g_object_ref(forwardItem); + g_assert_cmpint(G_OBJECT(forwardItem)->ref_count, ==, 2); + g_object_unref(forwardItem); + g_assert_cmpint(G_OBJECT(forwardItem)->ref_count, ==, 1); + + nthItem = webkit_web_back_forward_list_get_nth_item(backForwardList, 1); + g_object_ref(nthItem); + g_assert_cmpint(G_OBJECT(nthItem)->ref_count, ==, 2); + g_object_unref(nthItem); + g_assert_cmpint(G_OBJECT(nthItem)->ref_count, ==, 1); + + backList = webkit_web_back_forward_list_get_back_list_with_limit(backForwardList, 5); + for (; backList; backList = backList->next) + g_assert_cmpint(G_OBJECT(backList->data)->ref_count, ==, 1); + + forwardList = webkit_web_back_forward_list_get_forward_list_with_limit(backForwardList, 5); + for (; forwardList; forwardList = forwardList->next) + g_assert_cmpint(G_OBJECT(forwardList->data)->ref_count, ==, 1); + + g_list_free(forwardList); + g_list_free(backList); + g_assert_cmpint(G_OBJECT(item1)->ref_count, ==, 1); + g_assert_cmpint(G_OBJECT(item2)->ref_count, ==, 1); + g_assert_cmpint(G_OBJECT(item3)->ref_count, ==, 1); + g_assert_cmpint(G_OBJECT(item4)->ref_count, ==, 1); + g_assert_cmpint(G_OBJECT(backForwardList)->ref_count, ==, 1); + g_object_unref(webView); +} + +static void test_webkit_web_back_forward_list_order(void) +{ + WebKitWebView* webView; + WebKitWebBackForwardList* webBackForwardList; + WebKitWebHistoryItem* item1; + WebKitWebHistoryItem* item2; + WebKitWebHistoryItem* item3; + WebKitWebHistoryItem* item4; + WebKitWebHistoryItem* currentItem; + GList* backList = NULL; + GList* forwardList = NULL; + g_test_bug("22694"); + + webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(webView); + + webkit_web_view_set_maintains_back_forward_list(webView, TRUE); + webBackForwardList = webkit_web_view_get_back_forward_list(webView); + g_assert(webBackForwardList); + + // Check that there is no item. + g_assert(!webkit_web_back_forward_list_get_current_item(webBackForwardList)); + g_assert_cmpint(webkit_web_back_forward_list_get_forward_length(webBackForwardList), ==, 0); + g_assert_cmpint(webkit_web_back_forward_list_get_back_length(webBackForwardList), ==, 0); + g_assert(!webkit_web_view_can_go_forward(webView)); + g_assert(!webkit_web_view_can_go_back(webView)); + + // Add a new items + item1 = webkit_web_history_item_new_with_data("http://example.com/1/", "Site 1"); + webkit_web_back_forward_list_add_item(webBackForwardList, item1); + g_object_unref(item1); + g_assert(webkit_web_back_forward_list_contains_item(webBackForwardList, item1)); + + item2 = webkit_web_history_item_new_with_data("http://example.com/2/", "Site 2"); + webkit_web_back_forward_list_add_item(webBackForwardList, item2); + g_object_unref(item2); + g_assert(webkit_web_back_forward_list_contains_item(webBackForwardList, item2)); + + item3 = webkit_web_history_item_new_with_data("http://example.com/3/", "Site 3"); + webkit_web_back_forward_list_add_item(webBackForwardList, item3); + g_object_unref(item3); + g_assert(webkit_web_back_forward_list_contains_item(webBackForwardList, item3)); + + item4 = webkit_web_history_item_new_with_data("http://example.com/4/", "Site 4"); + webkit_web_back_forward_list_add_item(webBackForwardList, item4); + g_object_unref(item4); + g_assert(webkit_web_back_forward_list_contains_item(webBackForwardList, item4)); + + // check the back list order + backList = webkit_web_back_forward_list_get_back_list_with_limit(webBackForwardList, 5); + g_assert(backList); + + currentItem = WEBKIT_WEB_HISTORY_ITEM(backList->data); + g_assert_cmpstr(webkit_web_history_item_get_uri(currentItem), ==, "http://example.com/3/"); + g_assert_cmpstr(webkit_web_history_item_get_title(currentItem), ==, "Site 3"); + backList = backList->next; + + currentItem = WEBKIT_WEB_HISTORY_ITEM(backList->data); + g_assert_cmpstr(webkit_web_history_item_get_uri(currentItem), ==, "http://example.com/2/"); + g_assert_cmpstr(webkit_web_history_item_get_title(currentItem), ==, "Site 2"); + backList = backList->next; + + currentItem = WEBKIT_WEB_HISTORY_ITEM(backList->data); + g_assert_cmpstr(webkit_web_history_item_get_uri(currentItem), ==, "http://example.com/1/"); + g_assert_cmpstr(webkit_web_history_item_get_title(currentItem), ==, "Site 1"); + g_list_free(backList); + + // check the forward list order + g_assert(webkit_web_view_go_to_back_forward_item(webView, item1)); + forwardList = webkit_web_back_forward_list_get_forward_list_with_limit(webBackForwardList,5); + g_assert(forwardList); + + currentItem = WEBKIT_WEB_HISTORY_ITEM(forwardList->data); + g_assert_cmpstr(webkit_web_history_item_get_uri(currentItem), ==, "http://example.com/4/"); + g_assert_cmpstr(webkit_web_history_item_get_title(currentItem), ==, "Site 4"); + forwardList = forwardList->next; + + currentItem = WEBKIT_WEB_HISTORY_ITEM(forwardList->data); + g_assert_cmpstr(webkit_web_history_item_get_uri(currentItem), ==, "http://example.com/3/"); + g_assert_cmpstr(webkit_web_history_item_get_title(currentItem), ==, "Site 3"); + forwardList = forwardList->next; + + currentItem = WEBKIT_WEB_HISTORY_ITEM(forwardList->data); + g_assert_cmpstr(webkit_web_history_item_get_uri(currentItem), ==, "http://example.com/2/"); + g_assert_cmpstr(webkit_web_history_item_get_title(currentItem), ==, "Site 2"); + + g_list_free(forwardList); + g_object_unref(webView); +} + +static void test_webkit_web_back_forward_list_add_item(void) +{ + WebKitWebView* webView; + WebKitWebBackForwardList* webBackForwardList; + WebKitWebHistoryItem* addItem1; + WebKitWebHistoryItem* addItem2; + WebKitWebHistoryItem* backItem; + WebKitWebHistoryItem* currentItem; + g_test_bug("22988"); + + webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(webView); + + webkit_web_view_set_maintains_back_forward_list(webView, TRUE); + webBackForwardList = webkit_web_view_get_back_forward_list(webView); + g_assert(webBackForwardList); + + // Check that there is no item. + g_assert(!webkit_web_back_forward_list_get_current_item(webBackForwardList)); + g_assert_cmpint(webkit_web_back_forward_list_get_forward_length(webBackForwardList), ==, 0); + g_assert_cmpint(webkit_web_back_forward_list_get_back_length(webBackForwardList), ==, 0); + g_assert(!webkit_web_view_can_go_forward(webView)); + g_assert(!webkit_web_view_can_go_back(webView)); + + // Add a new item + addItem1 = webkit_web_history_item_new_with_data("http://example.com/", "Added site"); + webkit_web_back_forward_list_add_item(webBackForwardList, addItem1); + g_object_unref(addItem1); + g_assert(webkit_web_back_forward_list_contains_item(webBackForwardList, addItem1)); + + // Check that the added item is the current item. + currentItem = webkit_web_back_forward_list_get_current_item(webBackForwardList); + g_assert(currentItem); + g_assert_cmpint(webkit_web_back_forward_list_get_forward_length(webBackForwardList), ==, 0); + g_assert_cmpint(webkit_web_back_forward_list_get_back_length(webBackForwardList), ==, 0); + g_assert(!webkit_web_view_can_go_forward(webView)); + g_assert(!webkit_web_view_can_go_back(webView)); + g_assert_cmpstr(webkit_web_history_item_get_uri(currentItem), ==, "http://example.com/"); + g_assert_cmpstr(webkit_web_history_item_get_title(currentItem), ==, "Added site"); + + // Add another item. + addItem2 = webkit_web_history_item_new_with_data("http://example.com/2/", "Added site 2"); + webkit_web_back_forward_list_add_item(webBackForwardList, addItem2); + g_object_unref(addItem2); + g_assert(webkit_web_back_forward_list_contains_item(webBackForwardList, addItem2)); + + // Check that the added item is new current item. + currentItem = webkit_web_back_forward_list_get_current_item(webBackForwardList); + g_assert(currentItem); + g_assert_cmpint(webkit_web_back_forward_list_get_forward_length(webBackForwardList), ==, 0); + g_assert_cmpint(webkit_web_back_forward_list_get_back_length(webBackForwardList), ==, 1); + g_assert(!webkit_web_view_can_go_forward(webView)); + g_assert(webkit_web_view_can_go_back(webView)); + g_assert_cmpstr(webkit_web_history_item_get_uri(currentItem), ==, "http://example.com/2/"); + g_assert_cmpstr(webkit_web_history_item_get_title(currentItem), ==, "Added site 2"); + + backItem = webkit_web_back_forward_list_get_back_item(webBackForwardList); + g_assert(backItem); + g_assert_cmpstr(webkit_web_history_item_get_uri(backItem), ==, "http://example.com/"); + g_assert_cmpstr(webkit_web_history_item_get_title(backItem), ==, "Added site"); + + // Go to the first added item. + g_assert(webkit_web_view_go_to_back_forward_item(webView, addItem1)); + g_assert_cmpint(webkit_web_back_forward_list_get_forward_length(webBackForwardList), ==, 1); + g_assert_cmpint(webkit_web_back_forward_list_get_back_length(webBackForwardList), ==, 0); + g_assert(webkit_web_view_can_go_forward(webView)); + g_assert(!webkit_web_view_can_go_back(webView)); + + g_object_unref(webView); +} + +static void test_webkit_web_back_forward_list_clear(void) +{ + WebKitWebView* webView; + WebKitWebBackForwardList* webBackForwardList; + WebKitWebHistoryItem* addItem; + g_test_bug("36173"); + + webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(webView); + + webBackForwardList = webkit_web_view_get_back_forward_list(webView); + g_assert(webBackForwardList); + + // Check that there is no item. + g_assert_cmpint(webkit_web_back_forward_list_get_forward_length(webBackForwardList), ==, 0); + g_assert_cmpint(webkit_web_back_forward_list_get_back_length(webBackForwardList), ==, 0); + g_assert(!webkit_web_back_forward_list_get_current_item(webBackForwardList)); + g_assert(!webkit_web_view_can_go_forward(webView)); + g_assert(!webkit_web_view_can_go_back(webView)); + + // Check that clearing the empty list does not modify counters + webkit_web_back_forward_list_clear(webBackForwardList); + g_assert_cmpint(webkit_web_back_forward_list_get_forward_length(webBackForwardList), ==, 0); + g_assert_cmpint(webkit_web_back_forward_list_get_back_length(webBackForwardList), ==, 0); + g_assert(!webkit_web_back_forward_list_get_current_item(webBackForwardList)); + g_assert(!webkit_web_view_can_go_forward(webView)); + g_assert(!webkit_web_view_can_go_back(webView)); + + // Add a new item + addItem = webkit_web_history_item_new_with_data("http://example.com/", "Added site"); + webkit_web_back_forward_list_add_item(webBackForwardList, addItem); + g_object_unref(addItem); + g_assert(webkit_web_back_forward_list_contains_item(webBackForwardList, addItem)); + + // Check that after clearing the list the added item is no longer in the list + webkit_web_back_forward_list_clear(webBackForwardList); + g_assert(!webkit_web_back_forward_list_contains_item(webBackForwardList, addItem)); + + // Check that after clearing it, the list is empty + g_assert_cmpint(webkit_web_back_forward_list_get_forward_length(webBackForwardList), ==, 0); + g_assert_cmpint(webkit_web_back_forward_list_get_back_length(webBackForwardList), ==, 0); + g_assert(!webkit_web_back_forward_list_get_current_item(webBackForwardList)); + g_assert(!webkit_web_view_can_go_forward(webView)); + g_assert(!webkit_web_view_can_go_back(webView)); + + g_object_unref(webView); +} + +int main(int argc, char** argv) +{ + g_thread_init(NULL); + gtk_test_init(&argc, &argv, NULL); + + g_test_bug_base("https://bugs.webkit.org/"); + g_test_add_func("/webkit/webbackforwardlist/add_item", test_webkit_web_back_forward_list_add_item); + g_test_add_func("/webkit/webbackforwardlist/list_order", test_webkit_web_back_forward_list_order); + g_test_add_func("/webkit/webhistoryitem/lifetime", test_webkit_web_history_item_lifetime); + g_test_add_func("/webkit/webbackforwardlist/clear", test_webkit_web_back_forward_list_clear); + return g_test_run (); +} + +#else +int main(int argc, char** argv) +{ + g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now."); + return 0; +} + +#endif diff --git a/Source/WebKit/gtk/tests/testwebdatasource.c b/Source/WebKit/gtk/tests/testwebdatasource.c new file mode 100644 index 0000000..96d95e4 --- /dev/null +++ b/Source/WebKit/gtk/tests/testwebdatasource.c @@ -0,0 +1,253 @@ +/* + * Copyright (C) 2009 Jan Michael Alonzo + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <glib.h> +#include <gtk/gtk.h> +#include <webkit/webkit.h> + +#if GTK_CHECK_VERSION(2, 14, 0) + +static const gshort defaultTimeout = 10; +guint waitTimer; +gboolean shouldWait; + +typedef struct { + WebKitWebView* webView; + WebKitWebFrame* mainFrame; +} WebDataSourceFixture; + +static void test_webkit_web_data_source_get_initial_request() +{ + WebKitWebView* view; + WebKitWebFrame* frame; + WebKitWebDataSource* dataSource; + WebKitNetworkRequest* initialRequest; + + view = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(view); + frame = webkit_web_view_get_main_frame(view); + + WebKitNetworkRequest* request = webkit_network_request_new("http://www.google.com"); + webkit_web_frame_load_request(frame, request); + g_object_unref(request); + + dataSource = webkit_web_frame_get_provisional_data_source(frame); + g_assert(dataSource); + initialRequest = webkit_web_data_source_get_initial_request(dataSource); + g_assert_cmpstr(webkit_network_request_get_uri(initialRequest), ==, "http://www.google.com/"); + + g_object_unref(view); +} + +static void notify_load_status_unreachable_cb(WebKitWebView* view, GParamSpec* pspec, GMainLoop* loop) +{ + WebKitLoadStatus status = webkit_web_view_get_load_status (view); + WebKitWebFrame* frame = webkit_web_view_get_main_frame(view); + + g_assert(status != WEBKIT_LOAD_FINISHED); + + if (status != WEBKIT_LOAD_FAILED) + return; + + WebKitWebDataSource* datasource = webkit_web_frame_get_data_source(frame); + + g_assert_cmpstr("http://this.host.does.not.exist/doireallyexist.html", ==, + webkit_web_data_source_get_unreachable_uri(datasource)); + + g_main_loop_quit(loop); +} + +static void notify_load_status_cb(WebKitWebView* view, GParamSpec* pspec, GMainLoop* loop) +{ + WebKitLoadStatus status = webkit_web_view_get_load_status (view); + WebKitWebFrame* frame = webkit_web_view_get_main_frame(view); + WebKitWebDataSource* dataSource = webkit_web_frame_get_data_source(frame); + + if (status == WEBKIT_LOAD_COMMITTED) { + g_assert(webkit_web_data_source_is_loading(dataSource)); + return; + } + else if (status != WEBKIT_LOAD_FINISHED) + return; + + /* Test get_request */ + g_test_message("Testing webkit_web_data_source_get_request"); + WebKitNetworkRequest* request = webkit_web_data_source_get_request(dataSource); + g_assert_cmpstr(webkit_network_request_get_uri(request), ==, "http://webkit.org/"); + + /* Test get_main_resource */ + g_test_message("Testing webkit_web_data_source_get_main_resource"); + WebKitWebResource* resource = webkit_web_data_source_get_main_resource(dataSource); + g_assert_cmpstr("text/html", ==, webkit_web_resource_get_mime_type(resource)); + g_assert_cmpstr("http://webkit.org/", ==, webkit_web_resource_get_uri(resource)); + + /* Test get_data. We just test if data has certain size for the mean time */ + g_test_message("Testing webkit_web_data_source_get_data has certain size"); + GString* data = webkit_web_data_source_get_data(dataSource); + g_assert(data->len > 100); + + /* FIXME: Add test for get_encoding */ + + g_main_loop_quit(loop); +} + +static gboolean wait_timer_fired(GMainLoop* loop) +{ + waitTimer = 0; + g_main_loop_quit(loop); + + return FALSE; +} + +static void test_webkit_web_data_source() +{ + WebKitWebView* view; + GMainLoop* loop; + + view = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(view); + loop = g_main_loop_new(NULL, TRUE); + g_signal_connect(view, "notify::load-status", G_CALLBACK(notify_load_status_cb), loop); + webkit_web_view_load_uri(view, "http://webkit.org"); + + waitTimer = g_timeout_add_seconds(defaultTimeout, (GSourceFunc)wait_timer_fired, loop); + + g_main_loop_run(loop); + + if (waitTimer) + g_source_remove(waitTimer); + + waitTimer = 0; + + g_main_loop_unref(loop); + g_object_unref(view); +} + +static void notify_load_status_lifetime_cb(WebKitWebView* view, GParamSpec* pspec, GMainLoop* loop) +{ + WebKitLoadStatus status = webkit_web_view_get_load_status (view); + WebKitWebFrame* frame = webkit_web_view_get_main_frame(view); + WebKitWebDataSource* dataSource = webkit_web_frame_get_data_source(frame); + + if (status == WEBKIT_LOAD_COMMITTED) { + g_assert(webkit_web_data_source_is_loading(dataSource)); + return; + } else if (status != WEBKIT_LOAD_FINISHED) + return; + + g_main_loop_quit(loop); +} + +static void test_webkit_web_data_source_lifetime() +{ + WebKitWebView* view; + GMainLoop* loop; + + view = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(view); + loop = g_main_loop_new(NULL, TRUE); + g_signal_connect(view, "notify::load-status", G_CALLBACK(notify_load_status_lifetime_cb), loop); + webkit_web_view_load_uri(view, "http://webkit.org"); + + waitTimer = g_timeout_add_seconds(defaultTimeout, (GSourceFunc)wait_timer_fired, loop); + + g_main_loop_run(loop); + + WebKitWebDataSource* dataSource = webkit_web_frame_get_data_source(webkit_web_view_get_main_frame(view)); + GList* subResources = webkit_web_data_source_get_subresources(dataSource); + gint numberOfResources = g_list_length(subResources); + g_list_free(subResources); + + g_assert_cmpint(webkit_web_view_get_load_status(view), ==, WEBKIT_LOAD_FINISHED); + + webkit_web_view_load_uri(view, "http://gnome.org"); + + g_assert_cmpint(webkit_web_view_get_load_status(view), ==, WEBKIT_LOAD_PROVISIONAL); + + webkit_web_view_stop_loading(view); + + g_assert_cmpint(webkit_web_view_get_load_status(view), ==, WEBKIT_LOAD_FAILED); + + subResources = webkit_web_data_source_get_subresources(dataSource); + g_assert_cmpint(numberOfResources, ==, g_list_length(subResources)); + g_list_free(subResources); + + if (waitTimer) + g_source_remove(waitTimer); + + waitTimer = 0; + + g_main_loop_unref(loop); + g_object_unref(view); +} + +static void test_webkit_web_data_source_unreachable_uri() +{ + /* FIXME: this test fails currently. */ + return; + + WebKitWebView* view; + GMainLoop* loop; + + view = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(view); + loop = g_main_loop_new(NULL, TRUE); + g_signal_connect(view, "notify::load-status", G_CALLBACK(notify_load_status_unreachable_cb), loop); + webkit_web_view_load_uri(view, "http://this.host.does.not.exist/doireallyexist.html"); + + waitTimer = g_timeout_add_seconds(defaultTimeout, (GSourceFunc)wait_timer_fired, loop); + + g_main_loop_run(loop); + + if (waitTimer) + g_source_remove(waitTimer); + + waitTimer = 0; + + g_main_loop_unref(loop); + g_object_unref(view); +} + +int main(int argc, char** argv) +{ + g_thread_init(NULL); + gtk_test_init(&argc, &argv, NULL); + + g_test_bug_base("https://bugs.webkit.org/"); + g_test_bug("24758"); + g_test_add_func("/webkit/webdatasource/get_initial_request", + test_webkit_web_data_source_get_initial_request); + g_test_add_func("/webkit/webdatasource/api", + test_webkit_web_data_source); + g_test_add_func("/webkit/webdatasource/unreachable_uri", + test_webkit_web_data_source_unreachable_uri); + g_test_add_func("/webkit/webdatasource/lifetime", + test_webkit_web_data_source_lifetime); + + return g_test_run (); +} + +#else +int main(int argc, char** argv) +{ + g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now."); + return 0; +} + +#endif diff --git a/Source/WebKit/gtk/tests/testwebframe.c b/Source/WebKit/gtk/tests/testwebframe.c new file mode 100644 index 0000000..d1ff7ea --- /dev/null +++ b/Source/WebKit/gtk/tests/testwebframe.c @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2008 Holger Hans Peter Freyther + * Copyright (C) 2009 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <errno.h> +#include <unistd.h> +#include <glib.h> +#include <glib/gstdio.h> +#include <gtk/gtk.h> +#include <webkit/webkit.h> + +#if GTK_CHECK_VERSION(2, 14, 0) + +static int numberOfFramesCreated = 0; + +static void createFrameSignalTestFrameCreatedCallback(WebKitWebView* webView, WebKitWebFrame* frame, gpointer data) +{ + numberOfFramesCreated++; +} + +static gboolean createFrameSignalTestTimeout(gpointer data) +{ + g_assert_cmpint(numberOfFramesCreated, ==, 2); + g_main_loop_quit((GMainLoop*) data); + return FALSE; +} + +static void test_webkit_web_frame_created_signal(void) +{ + GtkWidget* webView; + GtkWidget* window; + GMainLoop* loop = g_main_loop_new(NULL, TRUE); + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + + webView = webkit_web_view_new(); + g_signal_connect(webView, "frame-created", G_CALLBACK(createFrameSignalTestFrameCreatedCallback), loop); + + // We want to ensure that exactly two create-frame signals are + // fired and no more, so we set a timeout here. There does not appear + // to be a simple way via the API to figure out when all frames have + // loaded. + g_timeout_add(500, createFrameSignalTestTimeout, loop); + + gtk_container_add(GTK_CONTAINER(window), webView); + gtk_widget_show(window); + gtk_widget_show(webView); + + webkit_web_view_load_string(WEBKIT_WEB_VIEW(webView), + "<html><body>Frames!" + "<iframe></iframe>" + "<iframe></iframe>" + "</body></html>", + "text/html", "utf-8", "file://"); + g_main_loop_run(loop); +} + +static void test_webkit_web_frame_create_destroy(void) +{ + GtkWidget *webView; + GtkWidget *window; + + g_test_bug("21837"); + webView = webkit_web_view_new(); + g_object_ref_sink(webView); + g_assert_cmpint(G_OBJECT(webView)->ref_count, ==, 1); + // This crashed with the original version + g_object_unref(webView); + + g_test_bug("25042"); + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + webView = webkit_web_view_new(); + gtk_container_add(GTK_CONTAINER(window), webView); + gtk_widget_show(window); + gtk_widget_show(webView); + gtk_widget_destroy(webView); +} + +static void test_webkit_web_frame_lifetime(void) +{ + WebKitWebView* webView; + WebKitWebFrame* webFrame; + g_test_bug("21837"); + + webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(webView); + g_assert_cmpint(G_OBJECT(webView)->ref_count, ==, 1); + webFrame = webkit_web_view_get_main_frame(webView); + g_assert_cmpint(G_OBJECT(webFrame)->ref_count, ==, 1); + + // Add dummy reference on the WebKitWebFrame to keep it alive + g_object_ref(webFrame); + g_assert_cmpint(G_OBJECT(webFrame)->ref_count, ==, 2); + + // This crashed with the original version + g_object_unref(webView); + + // Make sure that the frame got deleted as well. We did this + // by adding an extra ref on the WebKitWebFrame and we should + // be the one holding the last reference. + g_assert_cmpint(G_OBJECT(webFrame)->ref_count, ==, 1); + g_object_unref(webFrame); +} + +static gboolean print_requested_cb(WebKitWebView* webView, WebKitWebFrame* webFrame, GMainLoop* loop) +{ + g_object_set_data(G_OBJECT(webView), "signal-handled", GINT_TO_POINTER(TRUE)); + g_main_loop_quit(loop); + return TRUE; +} + +static void print_timeout(GMainLoop* loop) +{ + if (g_main_loop_is_running(loop)) + g_main_loop_quit(loop); +} + +static void test_webkit_web_frame_printing(void) +{ + WebKitWebView* webView; + + webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(webView); + g_assert_cmpint(G_OBJECT(webView)->ref_count, ==, 1); + + webkit_web_view_load_string(webView, + "<html><body><h1>WebKitGTK+!</h1></body></html>", + "text/html", + "utf-8", + "file://"); + + GMainLoop* loop = g_main_loop_new(NULL, TRUE); + + // Does javascript print() work correctly? + g_signal_connect(webView, "print-requested", + G_CALLBACK(print_requested_cb), + loop); + + g_object_set_data(G_OBJECT(webView), "signal-handled", GINT_TO_POINTER(FALSE)); + webkit_web_view_execute_script (webView, "print();"); + + // Give javascriptcore some time to process the print request, but + // prepare a timeout to avoid it running forever in case the signal is + // never emitted. + g_timeout_add(1000, (GSourceFunc)print_timeout, loop); + g_main_loop_run(loop); + + g_assert_cmpint(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(webView), "signal-handled")), ==, TRUE); + + // Does printing directly to a file? + GError *error = NULL; + gchar* temporaryFilename = NULL; + gint fd = g_file_open_tmp ("webkit-testwebframe-XXXXXX", &temporaryFilename, &error); + close(fd); + + if (error) { + g_critical("Failed to open a temporary file for writing: %s.", error->message); + g_error_free(error); + goto cleanup; + } + + // We delete the file, so that we can easily figure out that the + // file got printed; + if (g_unlink(temporaryFilename) == -1) { + g_warning("Failed to delete the temporary file: %s.\nThis may cause the test to be bogus.", g_strerror(errno)); + } + + WebKitWebFrame* webFrame = webkit_web_view_get_main_frame(webView); + GtkPrintOperation* operation = gtk_print_operation_new(); + GtkPrintOperationAction action = GTK_PRINT_OPERATION_ACTION_EXPORT; + GtkPrintOperationResult result; + + gtk_print_operation_set_export_filename(operation, temporaryFilename); + result = webkit_web_frame_print_full (webFrame, operation, action, NULL); + + g_assert_cmpint(result, ==, GTK_PRINT_OPERATION_RESULT_APPLY); + g_assert_cmpint(g_file_test(temporaryFilename, G_FILE_TEST_IS_REGULAR), ==, TRUE); + + g_unlink(temporaryFilename); + g_object_unref(operation); +cleanup: + g_object_unref(webView); + g_free(temporaryFilename); +} + +static void test_webkit_web_frame_response() +{ + WebKitWebFrame* frame = g_object_new(WEBKIT_TYPE_WEB_FRAME, NULL); + WebKitNetworkResponse* response = webkit_web_frame_get_network_response(frame); + g_assert(!response); + g_object_unref(frame); +} + +int main(int argc, char** argv) +{ + g_thread_init(NULL); + gtk_test_init(&argc, &argv, NULL); + + g_test_bug_base("https://bugs.webkit.org/"); + g_test_add_func("/webkit/webview/create_destroy", test_webkit_web_frame_create_destroy); + g_test_add_func("/webkit/webview/frame-created_signal", test_webkit_web_frame_created_signal); + g_test_add_func("/webkit/webframe/lifetime", test_webkit_web_frame_lifetime); + g_test_add_func("/webkit/webview/printing", test_webkit_web_frame_printing); + g_test_add_func("/webkit/webview/response", test_webkit_web_frame_response); + return g_test_run (); +} + +#else +int main(int argc, char** argv) +{ + g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now."); + return 0; +} + +#endif diff --git a/Source/WebKit/gtk/tests/testwebhistoryitem.c b/Source/WebKit/gtk/tests/testwebhistoryitem.c new file mode 100644 index 0000000..362dc98 --- /dev/null +++ b/Source/WebKit/gtk/tests/testwebhistoryitem.c @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2009 Jan Michael Alonzo + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <glib.h> +#include <gtk/gtk.h> +#include <webkit/webkit.h> + +#if GTK_CHECK_VERSION(2, 14, 0) + +typedef struct { + WebKitWebHistoryItem* item; +} WebHistoryItemFixture; + +static void web_history_item_fixture_setup(WebHistoryItemFixture* fixture, + gconstpointer data) +{ + fixture->item = webkit_web_history_item_new_with_data("http://example.com/", "Example1"); + g_assert_cmpint(G_OBJECT(fixture->item)->ref_count, == , 1); + g_assert(fixture->item != NULL); +} + +static void web_history_item_fixture_teardown(WebHistoryItemFixture* fixture, + gconstpointer data) +{ + g_assert(fixture->item != NULL); + g_assert_cmpint(G_OBJECT(fixture->item)->ref_count, ==, 1); +} + +static void test_webkit_web_history_item_get_data(WebHistoryItemFixture* fixture, + gconstpointer data) +{ + g_assert_cmpstr(webkit_web_history_item_get_title(fixture->item), ==, "Example1"); + g_assert_cmpstr(webkit_web_history_item_get_uri(fixture->item), ==, "http://example.com/"); +} + +static void test_webkit_web_history_item_alternate_title(WebHistoryItemFixture* fixture, + gconstpointer data) +{ + webkit_web_history_item_set_alternate_title(fixture->item, "Alternate title"); + g_assert_cmpstr(webkit_web_history_item_get_alternate_title(fixture->item), ==, "Alternate title"); +} + +int main(int argc, char** argv) +{ + g_thread_init(NULL); + gtk_test_init(&argc, &argv, NULL); + + g_test_bug_base("https://bugs.webkit.org/"); + g_test_add("/webkit/webhistoryitem/get_data", + WebHistoryItemFixture, 0, web_history_item_fixture_setup, + test_webkit_web_history_item_get_data, web_history_item_fixture_teardown); + g_test_add("/webkit/webhistoryitem/alternate_title", + WebHistoryItemFixture, 0, web_history_item_fixture_setup, + test_webkit_web_history_item_alternate_title, web_history_item_fixture_teardown); + return g_test_run (); +} + +#else +int main(int argc, char** argv) +{ + g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now."); + return 0; +} + +#endif diff --git a/Source/WebKit/gtk/tests/testwebplugindatabase.c b/Source/WebKit/gtk/tests/testwebplugindatabase.c new file mode 100644 index 0000000..1366f84 --- /dev/null +++ b/Source/WebKit/gtk/tests/testwebplugindatabase.c @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2010 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <errno.h> +#include <glib.h> +#include <glib/gstdio.h> +#include <gtk/gtk.h> +#include <webkit/webkit.h> + +#if GTK_CHECK_VERSION(2, 14, 0) + +/* This function is not public, so we need an extern declaration */ +extern void webkit_web_settings_add_extra_plugin_directory(WebKitWebView* view, const gchar* directory); + +static void test_webkit_web_plugin_database_get_plugins() +{ + WebKitWebView* view = WEBKIT_WEB_VIEW(webkit_web_view_new()); + WebKitWebPluginDatabase* database; + GSList* pluginList, *p; + gboolean found = FALSE; + gboolean enabled = FALSE; + + webkit_web_settings_add_extra_plugin_directory(view, TEST_PLUGIN_DIR); + g_object_ref_sink(G_OBJECT(view)); + + database = webkit_get_web_plugin_database(); + pluginList = webkit_web_plugin_database_get_plugins(database); + for (p = pluginList; p; p = p->next) { + WebKitWebPlugin* plugin = (WebKitWebPlugin*)p->data; + if (!g_strcmp0(webkit_web_plugin_get_name(plugin), "WebKit Test PlugIn") && + !g_strcmp0(webkit_web_plugin_get_description(plugin), "Simple Netscape plug-in that handles test content for WebKit")) { + found = TRUE; + enabled = webkit_web_plugin_get_enabled(plugin); + webkit_web_plugin_set_enabled(plugin, FALSE); + } + } + webkit_web_plugin_database_plugins_list_free(pluginList); + g_assert(found); + g_assert(enabled); + + webkit_web_plugin_database_refresh(database); + pluginList = webkit_web_plugin_database_get_plugins(database); + + for (p = pluginList; p; p = p->next) { + WebKitWebPlugin* plugin = (WebKitWebPlugin*)p->data; + if (!g_strcmp0(webkit_web_plugin_get_name(plugin), "WebKit Test PlugIn") && + !g_strcmp0(webkit_web_plugin_get_description(plugin), "Simple Netscape plug-in that handles test content for WebKit")) + enabled = webkit_web_plugin_get_enabled(plugin); + } + webkit_web_plugin_database_plugins_list_free(pluginList); + g_assert(!enabled); + + g_object_unref(view); +} + +int main(int argc, char** argv) +{ + g_thread_init(NULL); + gtk_test_init(&argc, &argv, NULL); + + g_test_bug_base("https://bugs.webkit.org/"); + g_test_add_func("/webkit/webplugindatabase/getplugins", test_webkit_web_plugin_database_get_plugins); + return g_test_run (); +} + +#else +int main(int argc, char** argv) +{ + g_critical("You will need at least gtk-2.14.0 to run the unit tests. Doing nothing now."); + return 0; +} + +#endif diff --git a/Source/WebKit/gtk/tests/testwebresource.c b/Source/WebKit/gtk/tests/testwebresource.c new file mode 100644 index 0000000..1b893a9 --- /dev/null +++ b/Source/WebKit/gtk/tests/testwebresource.c @@ -0,0 +1,342 @@ +/* + * Copyright (C) 2009 Jan Michael Alonzo + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <glib.h> +#include <gtk/gtk.h> +#include <libsoup/soup.h> +#include <string.h> +#include <webkit/webkit.h> + +#if GTK_CHECK_VERSION(2, 14, 0) + +#define INDEX_HTML "<html></html>" +#define MAIN_HTML "<html><head><script language=\"javascript\" src=\"/javascript.js\"></script></head><body><h1>hah</h1></html>" +#define JAVASCRIPT "function blah () { var a = 1; }" + +GMainLoop* loop; +SoupSession *session; +char *base_uri; +WebKitWebResource* main_resource; +WebKitWebResource* sub_resource; + +typedef struct { + WebKitWebResource* webResource; + WebKitWebView* webView; +} WebResourceFixture; + +/* For real request testing */ +static void +server_callback (SoupServer *server, SoupMessage *msg, + const char *path, GHashTable *query, + SoupClientContext *context, gpointer data) +{ + if (msg->method != SOUP_METHOD_GET) { + soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED); + return; + } + + soup_message_set_status (msg, SOUP_STATUS_OK); + + /* Redirect */ + if (g_str_equal (path, "/")) { + soup_message_set_status (msg, SOUP_STATUS_MOVED_PERMANENTLY); + + soup_message_headers_append (msg->response_headers, + "Location", "/index.html"); + } else if (g_str_equal (path, "/index.html")) { + soup_message_body_append (msg->response_body, + SOUP_MEMORY_COPY, + INDEX_HTML, + strlen (INDEX_HTML)); + } else if (g_str_equal (path, "/main.html")) { + soup_message_body_append (msg->response_body, + SOUP_MEMORY_COPY, + MAIN_HTML, + strlen (MAIN_HTML)); + } else if (g_str_equal (path, "/javascript.js")) { + soup_message_body_append (msg->response_body, + SOUP_MEMORY_COPY, + JAVASCRIPT, + strlen (JAVASCRIPT)); + } + + + soup_message_body_complete (msg->response_body); +} + +static void web_resource_fixture_setup(WebResourceFixture* fixture, gconstpointer data) +{ + fixture->webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(fixture->webView); + const gchar* webData = "<html></html>"; + fixture->webResource = webkit_web_resource_new(webData, strlen(webData), "http://example.com/", "text/html", "utf8", "Example.com"); + g_assert(fixture->webResource); +} + +static void web_resource_fixture_teardown(WebResourceFixture* fixture, gconstpointer data) +{ + g_assert(fixture->webResource); + g_object_unref(fixture->webResource); + g_object_unref(fixture->webView); +} + +static void test_webkit_web_resource_get_url(WebResourceFixture* fixture, gconstpointer data) +{ + gchar* url; + g_object_get(G_OBJECT(fixture->webResource), "uri", &url, NULL); + g_assert_cmpstr(url, ==, "http://example.com/"); + g_assert_cmpstr(webkit_web_resource_get_uri(fixture->webResource) ,==,"http://example.com/"); + g_free(url); +} + +static void test_webkit_web_resource_get_data(WebResourceFixture* fixture, gconstpointer data) +{ + GString* charData = webkit_web_resource_get_data(fixture->webResource); + g_assert_cmpstr(charData->str, ==, "<html></html>"); +} + +static void test_webkit_web_resource_get_mime_type(WebResourceFixture* fixture, gconstpointer data) +{ + gchar* mime_type; + g_object_get(G_OBJECT(fixture->webResource), "mime-type", &mime_type, NULL); + g_assert_cmpstr(mime_type, ==, "text/html"); + g_assert_cmpstr(webkit_web_resource_get_mime_type(fixture->webResource),==,"text/html"); + g_free(mime_type); +} + +static void test_webkit_web_resource_get_encoding(WebResourceFixture* fixture, gconstpointer data) +{ + gchar* text_encoding; + g_object_get(G_OBJECT(fixture->webResource), "encoding", &text_encoding, NULL); + g_assert_cmpstr(text_encoding, ==, "utf8"); + g_assert_cmpstr(webkit_web_resource_get_encoding(fixture->webResource),==,"utf8"); + g_free(text_encoding); +} + +static void test_webkit_web_resource_get_frame_name(WebResourceFixture* fixture, gconstpointer data) +{ + gchar* frame_name; + g_object_get(G_OBJECT(fixture->webResource), "frame-name", &frame_name, NULL); + g_assert_cmpstr(frame_name, ==, "Example.com"); + g_assert_cmpstr(webkit_web_resource_get_frame_name(fixture->webResource),==,"Example.com"); + g_free(frame_name); +} + +static void resource_request_starting_cb(WebKitWebView* web_view, WebKitWebFrame* web_frame, WebKitWebResource* web_resource, WebKitNetworkRequest* request, WebKitNetworkResponse* response, gpointer data) +{ + gint* been_there = data; + *been_there = *been_there + 1; + + if (*been_there == 1) { + g_assert(!main_resource); + main_resource = g_object_ref(web_resource); + + g_assert_cmpstr(webkit_web_resource_get_uri(web_resource), ==, base_uri); + + /* This should be a redirect, so the response must be NULL */ + g_assert(!response); + } else if (*been_there == 2) { + char* uri = g_strdup_printf("%sindex.html", base_uri); + + g_assert_cmpstr(webkit_web_resource_get_uri(web_resource), ==, uri); + + /* Cancel the request. */ + webkit_network_request_set_uri(request, "about:blank"); + + g_free(uri); + } +} + +static void notify_load_status_cb(WebKitWebView* web_view, GParamSpec* pspec, gpointer data) +{ + if (webkit_web_view_get_load_status(web_view) == WEBKIT_LOAD_FINISHED) { + gboolean* been_there = data; + *been_there = TRUE; + + g_assert_cmpstr(webkit_web_view_get_uri(web_view), ==, "about:blank"); + + g_main_loop_quit(loop); + } +} + +static void test_web_resource_loading() +{ + WebKitWebView* web_view = WEBKIT_WEB_VIEW(webkit_web_view_new()); + gint been_to_resource_request_starting = 0; + gboolean been_to_load_finished = FALSE; + WebKitWebFrame* web_frame; + WebKitWebDataSource* data_source; + + loop = g_main_loop_new(NULL, TRUE); + + g_object_ref_sink(web_view); + + g_signal_connect(web_view, "resource-request-starting", + G_CALLBACK(resource_request_starting_cb), + &been_to_resource_request_starting); + + g_signal_connect(web_view, "notify::load-status", + G_CALLBACK(notify_load_status_cb), + &been_to_load_finished); + + webkit_web_view_load_uri(web_view, base_uri); + + /* We won't get finished immediately, because of the redirect */ + g_main_loop_run(loop); + + web_frame = webkit_web_view_get_main_frame(web_view); + data_source = webkit_web_frame_get_data_source(web_frame); + + g_assert(main_resource); + g_assert(webkit_web_data_source_get_main_resource(data_source) == main_resource); + g_object_unref(main_resource); + + g_assert_cmpint(been_to_resource_request_starting, ==, 2); + g_assert_cmpint(been_to_load_finished, ==, TRUE); + + g_object_unref(web_view); + g_main_loop_unref(loop); +} + +static void resource_request_starting_sub_cb(WebKitWebView* web_view, WebKitWebFrame* web_frame, WebKitWebResource* web_resource, WebKitNetworkRequest* request, WebKitNetworkResponse* response, gpointer data) +{ + if (!main_resource) + main_resource = g_object_ref(web_resource); + else if (!sub_resource) + sub_resource = g_object_ref(web_resource); +} + +static void notify_load_status_sub_cb(WebKitWebView* web_view, GParamSpec* pspec, gpointer data) +{ + if (webkit_web_view_get_load_status(web_view) == WEBKIT_LOAD_FINISHED) + g_main_loop_quit(loop); +} + +static gboolean idle_quit_loop_cb(gpointer data) +{ + g_main_loop_quit(loop); + return FALSE; +} + +static void test_web_resource_sub_resource_loading() +{ + WebKitWebView* web_view = WEBKIT_WEB_VIEW(webkit_web_view_new()); + WebKitWebFrame* web_frame; + WebKitWebDataSource* data_source; + GList* sub_resources; + char* uri = g_strdup_printf("%smain.html", base_uri); + + main_resource = NULL; + + loop = g_main_loop_new(NULL, TRUE); + + g_object_ref_sink(web_view); + + g_signal_connect(web_view, "resource-request-starting", + G_CALLBACK(resource_request_starting_sub_cb), + NULL); + + g_signal_connect(web_view, "notify::load-status", + G_CALLBACK(notify_load_status_sub_cb), + NULL); + + webkit_web_view_load_uri(web_view, uri); + + g_main_loop_run(loop); + + /* The main resource should be loaded; now let's wait for the sub-resource to load */ + g_idle_add(idle_quit_loop_cb, NULL); + g_main_loop_run(loop); + + g_assert(main_resource && sub_resource); + g_assert(main_resource != sub_resource); + + web_frame = webkit_web_view_get_main_frame(web_view); + data_source = webkit_web_frame_get_data_source(web_frame); + + g_assert(webkit_web_data_source_get_main_resource(data_source) == main_resource); + g_object_unref(main_resource); + + sub_resources = webkit_web_data_source_get_subresources(data_source); + // Expected resources: javascripts.js, favicon.ico + g_assert(sub_resources); + g_assert(sub_resources->next); + g_assert(!sub_resources->next->next); + + // Test that the object we got from the data source is the same + // that went through resource-request-starting. Note that the order is + // not important (and not guaranteed since the resources are stored in a + // hashtable). + g_assert(WEBKIT_WEB_RESOURCE(sub_resources->data) == sub_resource + || WEBKIT_WEB_RESOURCE(sub_resources->next->data) == sub_resource); + + g_object_unref(web_view); + g_main_loop_unref(loop); +} + +int main(int argc, char** argv) +{ + SoupServer* server; + SoupURI* soup_uri; + + g_thread_init(NULL); + gtk_test_init(&argc, &argv, NULL); + + server = soup_server_new(SOUP_SERVER_PORT, 0, NULL); + soup_server_run_async(server); + + soup_server_add_handler(server, NULL, server_callback, NULL, NULL); + + soup_uri = soup_uri_new("http://127.0.0.1/"); + soup_uri_set_port(soup_uri, soup_server_get_port(server)); + + base_uri = soup_uri_to_string(soup_uri, FALSE); + soup_uri_free(soup_uri); + + g_test_bug_base("https://bugs.webkit.org/"); + g_test_add("/webkit/webresource/get_url", + WebResourceFixture, 0, web_resource_fixture_setup, + test_webkit_web_resource_get_url, web_resource_fixture_teardown); + g_test_add("/webkit/webresource/get_mime_type", + WebResourceFixture, 0, web_resource_fixture_setup, + test_webkit_web_resource_get_mime_type, web_resource_fixture_teardown); + g_test_add("/webkit/webresource/get_text_encoding_name", + WebResourceFixture, 0, web_resource_fixture_setup, + test_webkit_web_resource_get_encoding, web_resource_fixture_teardown); + g_test_add("/webkit/webresource/get_frame_name", + WebResourceFixture, 0, web_resource_fixture_setup, + test_webkit_web_resource_get_frame_name, web_resource_fixture_teardown); + g_test_add("/webkit/webresource/get_data", + WebResourceFixture, 0, web_resource_fixture_setup, + test_webkit_web_resource_get_data, web_resource_fixture_teardown); + + g_test_add_func("/webkit/webresource/loading", test_web_resource_loading); + g_test_add_func("/webkit/webresource/sub_resource_loading", test_web_resource_sub_resource_loading); + + return g_test_run (); +} + +#else +int main(int argc, char** argv) +{ + g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now."); + return 0; +} + +#endif diff --git a/Source/WebKit/gtk/tests/testwebsettings.c b/Source/WebKit/gtk/tests/testwebsettings.c new file mode 100644 index 0000000..4db929a --- /dev/null +++ b/Source/WebKit/gtk/tests/testwebsettings.c @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2009 Jan Michael Alonzo + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <glib.h> +#include <gtk/gtk.h> +#include <webkit/webkit.h> + +#if GTK_CHECK_VERSION(2, 14, 0) + +static void test_webkit_web_settings_user_agent(void) +{ + WebKitWebSettings* settings; + GtkWidget* webView; + gchar* defaultUserAgent; + gchar* userAgent; + g_test_bug("17375"); + + webView = webkit_web_view_new(); + g_object_ref_sink(webView); + + settings = webkit_web_view_get_settings(WEBKIT_WEB_VIEW(webView)); + defaultUserAgent = g_strdup(webkit_web_settings_get_user_agent(settings)); + + // test a custom UA string + userAgent = NULL; + g_object_set(G_OBJECT(settings), "user-agent", "testwebsettings/0.1", NULL); + g_object_get(G_OBJECT(settings),"user-agent", &userAgent, NULL); + g_assert_cmpstr(userAgent, ==, "testwebsettings/0.1"); + g_free(userAgent); + + // setting it to NULL or an empty value should give us the default UA string + userAgent = NULL; + g_object_set(G_OBJECT(settings), "user-agent", NULL, NULL); + g_object_get(G_OBJECT(settings),"user-agent", &userAgent, NULL); + g_assert_cmpstr(userAgent, ==, defaultUserAgent); + g_free(userAgent); + + userAgent = NULL; + g_object_set(G_OBJECT(settings), "user-agent", "", NULL); + g_object_get(G_OBJECT(settings),"user-agent", &userAgent, NULL); + g_assert_cmpstr(userAgent, ==, defaultUserAgent); + g_free(userAgent); + + g_free(defaultUserAgent); + g_object_unref(webView); +} + +int main(int argc, char** argv) +{ + g_thread_init(NULL); + gtk_test_init(&argc, &argv, NULL); + + g_test_bug_base("https://bugs.webkit.org/"); + g_test_add_func("/webkit/websettings/user_agent", test_webkit_web_settings_user_agent); + return g_test_run (); +} + +#else +int main(int argc, char** argv) +{ + g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now."); + return 0; +} + +#endif diff --git a/Source/WebKit/gtk/tests/testwebview.c b/Source/WebKit/gtk/tests/testwebview.c new file mode 100644 index 0000000..778235d --- /dev/null +++ b/Source/WebKit/gtk/tests/testwebview.c @@ -0,0 +1,378 @@ +/* + * Copyright (C) 2008 Holger Hans Peter Freyther + * Copyright (C) 2009, 2010 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "test_utils.h" + +#include <errno.h> +#include <unistd.h> +#include <string.h> + +#include <glib.h> +#include <glib/gstdio.h> +#include <gtk/gtk.h> +#include <webkit/webkit.h> + +#if GTK_CHECK_VERSION(2, 14, 0) + +GMainLoop* loop; +SoupSession *session; +char* base_uri; + +/* For real request testing */ +static void +server_callback(SoupServer* server, SoupMessage* msg, + const char* path, GHashTable* query, + SoupClientContext* context, gpointer data) +{ + if (msg->method != SOUP_METHOD_GET) { + soup_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED); + return; + } + + soup_message_set_status(msg, SOUP_STATUS_OK); + + if (g_str_equal(path, "/favicon.ico")) { + char* contents; + gsize length; + GError* error = NULL; + + g_file_get_contents("blank.ico", &contents, &length, &error); + g_assert(!error); + + soup_message_body_append(msg->response_body, SOUP_MEMORY_TAKE, contents, length); + } else if (g_str_equal(path, "/bigdiv.html")) { + char* contents = g_strdup("<html><body><a id=\"link\" href=\"http://abc.def\">test</a><div style=\"background-color: green; height: 1200px;\"></div></body></html>"); + soup_message_body_append(msg->response_body, SOUP_MEMORY_TAKE, contents, strlen(contents)); + } else if (g_str_equal(path, "/iframe.html")) { + char* contents = g_strdup("<html><body id=\"some-content\"><div style=\"background-color: green; height: 50px;\"></div><iframe src=\"bigdiv.html\"></iframe></body></html>"); + soup_message_body_append(msg->response_body, SOUP_MEMORY_TAKE, contents, strlen(contents)); + } else { + char* contents = g_strdup("<html><body>test</body></html>"); + soup_message_body_append(msg->response_body, SOUP_MEMORY_TAKE, contents, strlen(contents)); + } + + soup_message_body_complete(msg->response_body); +} + +static void idle_quit_loop_cb(WebKitWebView* web_view, GParamSpec* pspec, gpointer data) +{ + if (webkit_web_view_get_load_status(web_view) == WEBKIT_LOAD_FINISHED || + webkit_web_view_get_load_status(web_view) == WEBKIT_LOAD_FAILED) + g_main_loop_quit(loop); +} + +static void icon_uri_changed_cb(WebKitWebView* web_view, GParamSpec* pspec, gpointer data) +{ + gboolean* been_here = (gboolean*)data; + char* expected_uri; + + g_assert_cmpstr(g_param_spec_get_name(pspec), ==, "icon-uri"); + + expected_uri = g_strdup_printf("%sfavicon.ico", base_uri); + g_assert_cmpstr(webkit_web_view_get_icon_uri(web_view), ==, expected_uri); + g_free(expected_uri); + + *been_here = TRUE; +} + +static void icon_loaded_cb(WebKitWebView* web_view, char* icon_uri, gpointer data) +{ + gboolean* been_here = (gboolean*)data; + char* expected_uri = g_strdup_printf("%sfavicon.ico", base_uri); + g_assert_cmpstr(icon_uri, ==, expected_uri); + g_free(expected_uri); + + g_assert_cmpstr(icon_uri, ==, webkit_web_view_get_icon_uri(web_view)); + + *been_here = TRUE; +} + +static void test_webkit_web_view_icon_uri() +{ + gboolean been_to_uri_changed = FALSE; + gboolean been_to_icon_loaded = FALSE; + WebKitWebView* view = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(G_OBJECT(view)); + + loop = g_main_loop_new(NULL, TRUE); + + g_object_connect(G_OBJECT(view), + "signal::notify::progress", idle_quit_loop_cb, NULL, + "signal::notify::icon-uri", icon_uri_changed_cb, &been_to_uri_changed, + "signal::icon-loaded", icon_loaded_cb, &been_to_icon_loaded, + NULL); + + webkit_web_view_load_uri(view, base_uri); + + g_main_loop_run(loop); + + g_assert(been_to_uri_changed); + g_assert(been_to_icon_loaded); + + g_object_unref(view); +} + +static gboolean map_event_cb(GtkWidget *widget, GdkEvent* event, gpointer data) +{ + GMainLoop* loop = (GMainLoop*)data; + g_main_loop_quit(loop); + + return FALSE; +} + +static void test_webkit_web_view_grab_focus() +{ + char* uri = g_strconcat(base_uri, "iframe.html", NULL); + GtkWidget* window = gtk_window_new(GTK_WINDOW_POPUP); + GtkWidget* scrolled_window = gtk_scrolled_window_new(NULL, NULL); + WebKitWebView* view = WEBKIT_WEB_VIEW(webkit_web_view_new()); + GtkAdjustment* adjustment; + + gtk_window_set_default_size(GTK_WINDOW(window), 400, 200); + + gtk_container_add(GTK_CONTAINER(window), scrolled_window); + gtk_container_add(GTK_CONTAINER(scrolled_window), GTK_WIDGET(view)); + + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + + loop = g_main_loop_new(NULL, TRUE); + + g_signal_connect(view, "notify::progress", G_CALLBACK (idle_quit_loop_cb), NULL); + + /* Wait for window to show up */ + gtk_widget_show_all(window); + g_signal_connect(window, "map-event", + G_CALLBACK(map_event_cb), loop); + g_main_loop_run(loop); + + /* Load a page with a big div that will cause scrollbars to appear */ + webkit_web_view_load_uri(view, uri); + g_main_loop_run(loop); + + adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(scrolled_window)); + g_assert_cmpfloat(gtk_adjustment_get_value(adjustment), ==, 0.0); + + /* Since webkit_web_view_execute_script does not return a value, + it is impossible to know if an inner document has focus after + a node of it was focused via .focus() method. + The code below is an workaround: if the node has focus, a scroll + action is performed and afterward it is checked if the adjustment + has to be different from 0. + */ + char script[] = "var innerDoc = document.defaultView.frames[0].document; \ + innerDoc.getElementById(\"link\").focus(); \ + if (innerDoc.hasFocus()) \ + window.scrollBy(0, 100);"; + + /* Focus an element using JavaScript */ + webkit_web_view_execute_script(view, script); + + /* Make sure the ScrolledWindow noticed the scroll */ + g_assert_cmpfloat(gtk_adjustment_get_value(adjustment), !=, 0.0); + + g_free(uri); + gtk_widget_destroy(window); +} + +static void do_test_webkit_web_view_adjustments(gboolean with_page_cache) +{ + char* effective_uri = g_strconcat(base_uri, "bigdiv.html", NULL); + char* second_uri = g_strconcat(base_uri, "iframe.html", NULL); + GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + GtkWidget* scrolled_window = gtk_scrolled_window_new(NULL, NULL); + WebKitWebView* view = WEBKIT_WEB_VIEW(webkit_web_view_new()); + GtkAdjustment* adjustment; + double lower; + double upper; + + if (with_page_cache) { + WebKitWebSettings* settings = webkit_web_view_get_settings(view); + g_object_set(settings, "enable-page-cache", TRUE, NULL); + } + + gtk_window_set_default_size(GTK_WINDOW(window), 400, 200); + + gtk_container_add(GTK_CONTAINER(window), scrolled_window); + gtk_container_add(GTK_CONTAINER(scrolled_window), GTK_WIDGET(view)); + + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + + loop = g_main_loop_new(NULL, TRUE); + + g_object_connect(G_OBJECT(view), + "signal::notify::progress", idle_quit_loop_cb, NULL, + NULL); + + /* Wait for window to show up */ + gtk_widget_show_all(window); + g_signal_connect(window, "map-event", + G_CALLBACK(map_event_cb), loop); + g_main_loop_run(loop); + + /* Load a page with a big div that will cause scrollbars to appear */ + webkit_web_view_load_uri(view, effective_uri); + g_main_loop_run(loop); + + adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(scrolled_window)); + g_assert_cmpfloat(gtk_adjustment_get_value(adjustment), ==, 0.0); + + lower = gtk_adjustment_get_lower(adjustment); + upper = gtk_adjustment_get_upper(adjustment); + + /* Scroll the view using JavaScript */ + webkit_web_view_execute_script(view, "window.scrollBy(0, 100)"); + + /* Make sure the ScrolledWindow noticed the scroll */ + g_assert_cmpfloat(gtk_adjustment_get_value(adjustment), ==, 100.0); + + /* Load a second URI */ + webkit_web_view_load_uri(view, second_uri); + g_main_loop_run(loop); + + /* Make sure the scrollbar has been reset */ + g_assert_cmpfloat(gtk_adjustment_get_value(adjustment), ==, 0.0); + + /* Go back */ + webkit_web_view_go_back(view); + + /* When using page cache, go_back will return syncronously */ + if (!with_page_cache) + g_main_loop_run(loop); + + /* Make sure GTK+ has time to process the changes in size, for the adjusments */ + while (gtk_events_pending()) + gtk_main_iteration(); + + /* Make sure upper and lower bounds have been restored correctly */ + g_assert_cmpfloat(lower, ==, gtk_adjustment_get_lower(adjustment)); + g_assert_cmpfloat(upper, ==, gtk_adjustment_get_upper(adjustment)); + + g_assert_cmpfloat(gtk_adjustment_get_value(adjustment), ==, 100.0); + + g_free(effective_uri); + g_free(second_uri); + + gtk_widget_destroy(window); +} + +static void test_webkit_web_view_adjustments() +{ + /* Test this with page cache disabled, and enabled. */ + do_test_webkit_web_view_adjustments(FALSE); + do_test_webkit_web_view_adjustments(TRUE); +} + +gboolean delayed_destroy(gpointer data) +{ + gtk_widget_destroy(GTK_WIDGET(data)); + g_main_loop_quit(loop); + return FALSE; +} + +static void test_webkit_web_view_destroy() +{ + GtkWidget* window; + GtkWidget* web_view; + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + web_view = webkit_web_view_new(); + + gtk_container_add(GTK_CONTAINER(window), web_view); + + gtk_widget_show_all(window); + + loop = g_main_loop_new(NULL, TRUE); + + g_signal_connect(window, "map-event", + G_CALLBACK(map_event_cb), loop); + g_main_loop_run(loop); + + g_idle_add(delayed_destroy, web_view); + g_main_loop_run(loop); + + gtk_widget_destroy(window); +} + +static void test_webkit_web_view_window_features() +{ + GtkWidget* window; + GtkWidget* web_view; + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + web_view = webkit_web_view_new(); + + gtk_container_add(GTK_CONTAINER(window), web_view); + + gtk_widget_show_all(window); + + loop = g_main_loop_new(NULL, TRUE); + + g_signal_connect(window, "map-event", + G_CALLBACK(map_event_cb), loop); + g_main_loop_run(loop); + + /* Bug #36144 */ + g_object_set(G_OBJECT(web_view), "window-features", NULL, NULL); + + gtk_widget_destroy(window); +} + +int main(int argc, char** argv) +{ + SoupServer* server; + SoupURI* soup_uri; + + g_thread_init(NULL); + gtk_test_init(&argc, &argv, NULL); + + /* Hopefully make test independent of the path it's called from. */ + testutils_relative_chdir("Source/WebKit/gtk/tests/resources/test.html", argv[0]); + + server = soup_server_new(SOUP_SERVER_PORT, 0, NULL); + soup_server_run_async(server); + + soup_server_add_handler(server, NULL, server_callback, NULL, NULL); + + soup_uri = soup_uri_new("http://127.0.0.1/"); + soup_uri_set_port(soup_uri, soup_server_get_port(server)); + + base_uri = soup_uri_to_string(soup_uri, FALSE); + soup_uri_free(soup_uri); + + g_test_bug_base("https://bugs.webkit.org/"); + g_test_add_func("/webkit/webview/icon-uri", test_webkit_web_view_icon_uri); + g_test_add_func("/webkit/webview/adjustments", test_webkit_web_view_adjustments); + g_test_add_func("/webkit/webview/destroy", test_webkit_web_view_destroy); + g_test_add_func("/webkit/webview/grab_focus", test_webkit_web_view_grab_focus); + g_test_add_func("/webkit/webview/window-features", test_webkit_web_view_window_features); + + return g_test_run (); +} + +#else +int main(int argc, char** argv) +{ + g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now."); + return 0; +} + +#endif diff --git a/Source/WebKit/gtk/tests/testwindow.c b/Source/WebKit/gtk/tests/testwindow.c new file mode 100644 index 0000000..ecd6609 --- /dev/null +++ b/Source/WebKit/gtk/tests/testwindow.c @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2009 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <gtk/gtk.h> +#include <webkit/webkit.h> + +#if GTK_CHECK_VERSION(2, 14, 0) + +static void notify_load_status_cb(WebKitWebView* web_view, GParamSpec* pspec, gpointer data) +{ + if (webkit_web_view_get_load_status(web_view) == WEBKIT_LOAD_FINISHED) { + GMainLoop* loop = (GMainLoop*)data; + + g_main_loop_quit(loop); + } +} + +static void test_webkit_window_scrollbar_policy(void) +{ + GMainLoop* loop; + GtkWidget* scrolledWindow; + GtkWidget* webView; + WebKitWebFrame* mainFrame; + GtkPolicyType horizontalPolicy; + GtkPolicyType verticalPolicy; + + loop = g_main_loop_new(NULL, TRUE); + + scrolledWindow = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledWindow), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + + webView = webkit_web_view_new(); + g_object_ref_sink(webView); + + g_signal_connect(webView, "notify::load-status", + G_CALLBACK(notify_load_status_cb), loop); + + gtk_container_add(GTK_CONTAINER(scrolledWindow), webView); + + mainFrame = webkit_web_view_get_main_frame(WEBKIT_WEB_VIEW(webView)); + + /* Test we correctly apply policy for not having scrollbars; This + * case is special, because we turn the policy from NEVER to + * AUTOMATIC, since we cannot easily represent the same thing + * using GtkScrolledWindow */ + webkit_web_view_load_html_string(WEBKIT_WEB_VIEW(webView), + "<html><body>WebKit!</body><script>document.getElementsByTagName('body')[0].style.overflow = 'hidden';</script></html>", + "file://"); + + g_main_loop_run(loop); + + gtk_scrolled_window_get_policy(GTK_SCROLLED_WINDOW(scrolledWindow), + &horizontalPolicy, &verticalPolicy); + + g_assert(horizontalPolicy == GTK_POLICY_AUTOMATIC); + g_assert(verticalPolicy == GTK_POLICY_AUTOMATIC); + + g_assert(GTK_POLICY_NEVER == webkit_web_frame_get_horizontal_scrollbar_policy(mainFrame)); + g_assert(GTK_POLICY_NEVER == webkit_web_frame_get_vertical_scrollbar_policy(mainFrame)); + + /* Test we correctly apply policy for always having scrollbars */ + webkit_web_view_load_html_string(WEBKIT_WEB_VIEW(webView), + "<html><body>WebKit!</body><script>document.getElementsByTagName('body')[0].style.overflow = 'scroll';</script></html>", + "file://"); + + g_main_loop_run(loop); + + gtk_scrolled_window_get_policy(GTK_SCROLLED_WINDOW(scrolledWindow), + &horizontalPolicy, &verticalPolicy); + + g_assert(horizontalPolicy == GTK_POLICY_ALWAYS); + g_assert(verticalPolicy == GTK_POLICY_ALWAYS); + + g_assert(horizontalPolicy == webkit_web_frame_get_horizontal_scrollbar_policy(mainFrame)); + g_assert(verticalPolicy == webkit_web_frame_get_vertical_scrollbar_policy(mainFrame)); + + /* Test we correctly apply policy for having scrollbars when needed */ + webkit_web_view_load_html_string(WEBKIT_WEB_VIEW(webView), + "<html><body>WebKit!</body><script>document.getElementsByTagName('body')[0].style.overflow = 'auto';</script></html>", + "file://"); + + g_main_loop_run(loop); + + gtk_scrolled_window_get_policy(GTK_SCROLLED_WINDOW(scrolledWindow), + &horizontalPolicy, &verticalPolicy); + + g_assert(horizontalPolicy == GTK_POLICY_AUTOMATIC); + g_assert(verticalPolicy == GTK_POLICY_AUTOMATIC); + + g_assert(horizontalPolicy == webkit_web_frame_get_horizontal_scrollbar_policy(mainFrame)); + g_assert(verticalPolicy == webkit_web_frame_get_vertical_scrollbar_policy(mainFrame)); + + g_object_unref(webView); +} + +int main(int argc, char** argv) +{ + g_thread_init(NULL); + gtk_test_init(&argc, &argv, NULL); + + g_test_bug_base("https://bugs.webkit.org/"); + g_test_add_func("/webkit/window/scrollbar_policy", test_webkit_window_scrollbar_policy); + return g_test_run (); +} + +#else +int main(int argc, char** argv) +{ + g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now."); + return 0; +} + +#endif |