Index: Tools/TestWebKitAPI/Tests/gtk/InputMethodFilter.cpp |
diff --git a/Tools/TestWebKitAPI/Tests/gtk/InputMethodFilter.cpp b/Tools/TestWebKitAPI/Tests/gtk/InputMethodFilter.cpp |
deleted file mode 100644 |
index bfcc17dcc67f6bd40f1ac3e57d05b561cca2fa39..0000000000000000000000000000000000000000 |
--- a/Tools/TestWebKitAPI/Tests/gtk/InputMethodFilter.cpp |
+++ /dev/null |
@@ -1,310 +0,0 @@ |
-/* |
- * Copyright (C) 2012 Igalia S.L. |
- * |
- * Redistribution and use in source and binary forms, with or without |
- * modification, are permitted provided that the following conditions |
- * are met: |
- * 1. Redistributions of source code must retain the above copyright |
- * notice, this list of conditions and the following disclaimer. |
- * 2. Redistributions in binary form must reproduce the above copyright |
- * notice, this list of conditions and the following disclaimer in the |
- * documentation and/or other materials provided with the distribution. |
- * |
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
- * THE POSSIBILITY OF SUCH DAMAGE. |
- */ |
- |
-#include "config.h" |
- |
-#include "GtkInputMethodFilter.h" |
-#include "WTFStringUtilities.h" |
-#include <gdk/gdkkeysyms.h> |
-#include <gtk/gtk.h> |
-#include <wtf/gobject/GOwnPtr.h> |
-#include <wtf/gobject/GRefPtr.h> |
-#include <wtf/text/CString.h> |
- |
-using namespace WebCore; |
- |
-namespace TestWebKitAPI { |
- |
-class TestInputMethodFilter : public GtkInputMethodFilter { |
-public: |
- TestInputMethodFilter() |
- : m_testWindow(gtk_window_new(GTK_WINDOW_POPUP)) |
- { |
- gtk_widget_show(m_testWindow.get()); |
- setWidget(m_testWindow.get()); |
- |
- // Focus in is necessary to activate the default input method in the multicontext. |
- notifyFocusedIn(); |
- } |
- |
- Vector<String>& events() { return m_events; } |
- |
- void sendKeyEventToFilter(unsigned int gdkKeyValue, GdkEventType type, unsigned int modifiers = 0) |
- { |
- GdkEvent* event = gdk_event_new(type); |
- event->key.keyval = gdkKeyValue; |
- event->key.state = modifiers; |
- event->key.window = gtk_widget_get_window(m_testWindow.get()); |
- event->key.time = GDK_CURRENT_TIME; |
- g_object_ref(event->key.window); |
- |
-#ifndef GTK_API_VERSION_2 |
- gdk_event_set_device(event, gdk_device_manager_get_client_pointer(gdk_display_get_device_manager(gdk_display_get_default()))); |
-#endif |
- |
- GOwnPtr<GdkKeymapKey> keys; |
- gint nKeys; |
- if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), gdkKeyValue, &keys.outPtr(), &nKeys)) |
- event->key.hardware_keycode = keys.get()[0].keycode; |
- |
- filterKeyEvent(&event->key); |
- gdk_event_free(event); |
- } |
- |
- void sendPressAndReleaseKeyEventPairToFilter(unsigned int gdkKeyValue, unsigned int modifiers = 0) |
- { |
- sendKeyEventToFilter(gdkKeyValue, GDK_KEY_PRESS, modifiers); |
- sendKeyEventToFilter(gdkKeyValue, GDK_KEY_RELEASE, modifiers); |
- } |
- |
-protected: |
- virtual bool sendSimpleKeyEvent(GdkEventKey* event, WTF::String eventString, EventFakedForComposition faked) |
- { |
- const char* eventType = event->type == GDK_KEY_RELEASE ? "release" : "press"; |
- const char* fakedString = faked == EventFaked ? " (faked)" : ""; |
- if (!eventString.isNull()) |
- m_events.append(String::format("sendSimpleKeyEvent type=%s keycode=%x text='%s'%s", eventType, event->keyval, eventString.utf8().data(), fakedString)); |
- else |
- m_events.append(String::format("sendSimpleKeyEvent type=%s keycode=%x%s", eventType, event->keyval, fakedString)); |
- |
- return true; |
- } |
- |
- virtual bool sendKeyEventWithCompositionResults(GdkEventKey* event, ResultsToSend resultsToSend, EventFakedForComposition faked) |
- { |
- const char* eventType = event->type == GDK_KEY_RELEASE ? "release" : "press"; |
- const char* fakedString = faked == EventFaked ? " (faked)" : ""; |
- m_events.append(String::format("sendKeyEventWithCompositionResults type=%s keycode=%u%s", eventType, event->keyval, fakedString)); |
- |
- if (resultsToSend & Composition && !m_confirmedComposition.isNull()) |
- confirmCompositionText(m_confirmedComposition); |
- if (resultsToSend & Preedit && !m_preedit.isNull()) |
- setPreedit(m_preedit, m_cursorOffset); |
- |
- return true; |
- } |
- |
- virtual bool canEdit() |
- { |
- return true; |
- } |
- |
- virtual void confirmCompositionText(String text) |
- { |
- m_events.append(String::format("confirmComposition '%s'", text.utf8().data())); |
- } |
- |
- virtual void confirmCurrentComposition() |
- { |
- m_events.append(String("confirmCurrentcomposition")); |
- } |
- |
- virtual void cancelCurrentComposition() |
- { |
- m_events.append(String("cancelCurrentComposition")); |
- } |
- |
- virtual void setPreedit(String preedit, int cursorOffset) |
- { |
- m_events.append(String::format("setPreedit text='%s' cursorOffset=%i", preedit.utf8().data(), cursorOffset)); |
- } |
- |
-private: |
- GRefPtr<GtkWidget> m_testWindow; |
- Vector<String> m_events; |
-}; |
- |
-TEST(GTK, GtkInputMethodFilterSimple) |
-{ |
- TestInputMethodFilter inputMethodFilter; |
- inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_g); |
- inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_t); |
- inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_k); |
- |
- const Vector<String>& events = inputMethodFilter.events(); |
- |
- ASSERT_EQ(6, events.size()); |
- ASSERT_EQ(String("sendSimpleKeyEvent type=press keycode=67 text='g'"), events[0]); |
- ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=67"), events[1]); |
- ASSERT_EQ(String("sendSimpleKeyEvent type=press keycode=74 text='t'"), events[2]); |
- ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=74"), events[3]); |
- ASSERT_EQ(String("sendSimpleKeyEvent type=press keycode=6b text='k'"), events[4]); |
- ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=6b"), events[5]); |
-} |
- |
-TEST(GTK, GtkInputMethodFilterUnicodeSequence) |
-{ |
- TestInputMethodFilter inputMethodFilter; |
- |
- // This is simple unicode hex entry of the characters, u, 0, 0, f, 4 pressed with |
- // the shift and controls keys held down. In reality, these values are not typical |
- // of an actual hex entry, because they'd be transformed by the shift modifier according |
- // to the keyboard layout. For instance, on a US keyboard a 0 with the shift key pressed |
- // is a right parenthesis. Using these values prevents having to work out what the |
- // transformed characters are based on the current keyboard layout. |
- inputMethodFilter.sendKeyEventToFilter(GDK_KEY_Control_L, GDK_KEY_PRESS); |
- inputMethodFilter.sendKeyEventToFilter(GDK_KEY_Shift_L, GDK_KEY_PRESS, GDK_CONTROL_MASK); |
- |
- inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_U, GDK_SHIFT_MASK | GDK_CONTROL_MASK); |
- inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_0, GDK_SHIFT_MASK | GDK_CONTROL_MASK); |
- inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_0, GDK_SHIFT_MASK | GDK_CONTROL_MASK); |
- inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_F, GDK_SHIFT_MASK | GDK_CONTROL_MASK); |
- inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_4, GDK_SHIFT_MASK | GDK_CONTROL_MASK); |
- |
- inputMethodFilter.sendKeyEventToFilter(GDK_KEY_Shift_L, GDK_KEY_RELEASE, GDK_CONTROL_MASK | GDK_SHIFT_MASK); |
- inputMethodFilter.sendKeyEventToFilter(GDK_KEY_Control_L, GDK_KEY_RELEASE, GDK_CONTROL_MASK); |
- |
- const Vector<String>& events = inputMethodFilter.events(); |
- ASSERT_EQ(21, events.size()); |
- ASSERT_EQ(String("sendSimpleKeyEvent type=press keycode=ffe3"), events[0]); |
- ASSERT_EQ(String("sendSimpleKeyEvent type=press keycode=ffe1"), events[1]); |
- ASSERT_EQ(String("sendKeyEventWithCompositionResults type=press keycode=85"), events[2]); |
- ASSERT_EQ(String("setPreedit text='u' cursorOffset=1"), events[3]); |
- ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=55"), events[4]); |
- ASSERT_EQ(String("sendKeyEventWithCompositionResults type=press keycode=48"), events[5]); |
- ASSERT_EQ(String("setPreedit text='u0' cursorOffset=2"), events[6]); |
- ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=30"), events[7]); |
- ASSERT_EQ(String("sendKeyEventWithCompositionResults type=press keycode=48"), events[8]); |
- ASSERT_EQ(String("setPreedit text='u00' cursorOffset=3"), events[9]); |
- ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=30"), events[10]); |
- ASSERT_EQ(String("sendKeyEventWithCompositionResults type=press keycode=70"), events[11]); |
- ASSERT_EQ(String("setPreedit text='u00F' cursorOffset=4"), events[12]); |
- ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=46"), events[13]); |
- ASSERT_EQ(String("sendKeyEventWithCompositionResults type=press keycode=52"), events[14]); |
- ASSERT_EQ(String("setPreedit text='u00F4' cursorOffset=5"), events[15]); |
- ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=34"), events[16]); |
- ASSERT_EQ(String("confirmComposition 'ô'"), events[17]); |
- ASSERT_EQ(String("setPreedit text='' cursorOffset=0"), events[18]); |
- ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=ffe1"), events[19]); |
- ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=ffe3"), events[20]); |
-} |
- |
-TEST(GTK, GtkInputMethodFilterComposeKey) |
-{ |
- TestInputMethodFilter inputMethodFilter; |
- |
- inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_Multi_key); |
- inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_apostrophe); |
- inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_o); |
- |
- const Vector<String>& events = inputMethodFilter.events(); |
- ASSERT_EQ(5, events.size()); |
- ASSERT_EQ(String("sendKeyEventWithCompositionResults type=press keycode=39"), events[0]); |
- ASSERT_EQ(String("setPreedit text='' cursorOffset=0"), events[1]); |
- ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=27"), events[2]); |
- ASSERT_EQ(String("sendSimpleKeyEvent type=press keycode=6f text='ó'"), events[3]); |
- ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=6f"), events[4]); |
-} |
- |
-typedef void (*GetPreeditStringCallback) (GtkIMContext*, gchar**, PangoAttrList**, int*); |
-static void temporaryGetPreeditStringOverride(GtkIMContext*, char** string, PangoAttrList** attrs, int* cursorPosition) |
-{ |
- *string = g_strdup("preedit of doom, bringer of cheese"); |
- *cursorPosition = 3; |
-} |
- |
-TEST(GTK, GtkInputMethodFilterContextEventsWithoutKeyEvents) |
-{ |
- TestInputMethodFilter inputMethodFilter; |
- |
- // This is a bit of a hack to avoid mocking out the entire InputMethodContext, by |
- // simply replacing the get_preedit_string virtual method for the length of this test. |
- GtkIMContext* context = inputMethodFilter.context(); |
- GtkIMContextClass* contextClass = GTK_IM_CONTEXT_GET_CLASS(context); |
- GetPreeditStringCallback previousCallback = contextClass->get_preedit_string; |
- contextClass->get_preedit_string = temporaryGetPreeditStringOverride; |
- |
- g_signal_emit_by_name(context, "preedit-changed"); |
- g_signal_emit_by_name(context, "commit", "commit text"); |
- |
- contextClass->get_preedit_string = previousCallback; |
- |
- const Vector<String>& events = inputMethodFilter.events(); |
- ASSERT_EQ(6, events.size()); |
- ASSERT_EQ(String("sendKeyEventWithCompositionResults type=press keycode=16777215 (faked)"), events[0]); |
- ASSERT_EQ(String("setPreedit text='preedit of doom, bringer of cheese' cursorOffset=3"), events[1]); |
- ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=ffffff (faked)"), events[2]); |
- ASSERT_EQ(String("sendKeyEventWithCompositionResults type=press keycode=16777215 (faked)"), events[3]); |
- ASSERT_EQ(String("confirmComposition 'commit text'"), events[4]); |
- ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=ffffff (faked)"), events[5]); |
-} |
- |
-static bool gSawContextReset = false; |
-typedef void (*ResetCallback) (GtkIMContext*); |
-static void temporaryResetOverride(GtkIMContext*) |
-{ |
- gSawContextReset = true; |
-} |
- |
-static void verifyCanceledComposition(const Vector<String>& events) |
-{ |
- ASSERT_EQ(3, events.size()); |
- ASSERT_EQ(String("sendKeyEventWithCompositionResults type=press keycode=39"), events[0]); |
- ASSERT_EQ(String("setPreedit text='' cursorOffset=0"), events[1]); |
- ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=27"), events[2]); |
- ASSERT(gSawContextReset); |
-} |
- |
-TEST(GTK, GtkInputMethodFilterContextFocusOutDuringOngoingComposition) |
-{ |
- TestInputMethodFilter inputMethodFilter; |
- |
- // See comment above about this technique. |
- GtkIMContext* context = inputMethodFilter.context(); |
- GtkIMContextClass* contextClass = GTK_IM_CONTEXT_GET_CLASS(context); |
- ResetCallback previousCallback = contextClass->reset; |
- contextClass->reset = temporaryResetOverride; |
- |
- gSawContextReset = false; |
- inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_Multi_key); |
- inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_apostrophe); |
- inputMethodFilter.notifyFocusedOut(); |
- |
- verifyCanceledComposition(inputMethodFilter.events()); |
- |
- contextClass->reset = previousCallback; |
-} |
- |
-TEST(GTK, GtkInputMethodFilterContextMouseClickDuringOngoingComposition) |
-{ |
- TestInputMethodFilter inputMethodFilter; |
- |
- // See comment above about this technique. |
- GtkIMContext* context = inputMethodFilter.context(); |
- GtkIMContextClass* contextClass = GTK_IM_CONTEXT_GET_CLASS(context); |
- ResetCallback previousCallback = contextClass->reset; |
- contextClass->reset = temporaryResetOverride; |
- |
- gSawContextReset = false; |
- inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_Multi_key); |
- inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_apostrophe); |
- inputMethodFilter.notifyMouseButtonPress(); |
- |
- verifyCanceledComposition(inputMethodFilter.events()); |
- |
- contextClass->reset = previousCallback; |
-} |
- |
-} // namespace TestWebKitAPI |