1 /* 2 * Copyright (C) 2010 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "config.h" 32 33 #include <gtest/gtest.h> 34 35 #include "core/editing/EditingBehavior.h" 36 #include "core/editing/Editor.h" 37 #include "core/events/EventTarget.h" 38 #include "core/events/KeyboardEvent.h" 39 #include "core/frame/Settings.h" 40 #include "platform/KeyboardCodes.h" 41 #include "public/web/WebInputEvent.h" 42 #include "web/WebInputEventConversion.h" 43 44 using namespace WebCore; 45 using namespace blink; 46 47 namespace { 48 49 class KeyboardTest : public testing::Test { 50 public: 51 52 // Pass a WebKeyboardEvent into the EditorClient and get back the string 53 // name of which editing event that key causes. 54 // E.g., sending in the enter key gives back "InsertNewline". 55 const char* interpretKeyEvent( 56 const WebKeyboardEvent& webKeyboardEvent, 57 PlatformEvent::Type keyType) 58 { 59 PlatformKeyboardEventBuilder evt(webKeyboardEvent); 60 evt.setKeyType(keyType); 61 RefPtrWillBeRawPtr<KeyboardEvent> keyboardEvent = KeyboardEvent::create(evt, 0); 62 OwnPtr<Settings> settings = Settings::create(); 63 EditingBehavior behavior(settings->editingBehaviorType()); 64 return behavior.interpretKeyEvent(*keyboardEvent); 65 } 66 67 // Set up a WebKeyboardEvent KEY_DOWN event with key code and modifiers. 68 void setupKeyDownEvent(WebKeyboardEvent* keyboardEvent, 69 char keyCode, 70 int modifiers) 71 { 72 keyboardEvent->windowsKeyCode = keyCode; 73 keyboardEvent->modifiers = modifiers; 74 keyboardEvent->type = WebInputEvent::KeyDown; 75 keyboardEvent->text[0] = keyCode; 76 keyboardEvent->setKeyIdentifierFromWindowsKeyCode(); 77 } 78 79 // Like interpretKeyEvent, but with pressing down OSModifier+|keyCode|. 80 // OSModifier is the platform's standard modifier key: control on most 81 // platforms, but meta (command) on Mac. 82 const char* interpretOSModifierKeyPress(char keyCode) 83 { 84 WebKeyboardEvent keyboardEvent; 85 #if OS(MACOSX) 86 WebInputEvent::Modifiers osModifier = WebInputEvent::MetaKey; 87 #else 88 WebInputEvent::Modifiers osModifier = WebInputEvent::ControlKey; 89 #endif 90 setupKeyDownEvent(&keyboardEvent, keyCode, osModifier); 91 return interpretKeyEvent(keyboardEvent, PlatformEvent::RawKeyDown); 92 } 93 94 // Like interpretKeyEvent, but with pressing down ctrl+|keyCode|. 95 const char* interpretCtrlKeyPress(char keyCode) 96 { 97 WebKeyboardEvent keyboardEvent; 98 setupKeyDownEvent(&keyboardEvent, keyCode, WebInputEvent::ControlKey); 99 return interpretKeyEvent(keyboardEvent, PlatformEvent::RawKeyDown); 100 } 101 102 // Like interpretKeyEvent, but with typing a tab. 103 const char* interpretTab(int modifiers) 104 { 105 WebKeyboardEvent keyboardEvent; 106 setupKeyDownEvent(&keyboardEvent, '\t', modifiers); 107 return interpretKeyEvent(keyboardEvent, PlatformEvent::Char); 108 } 109 110 // Like interpretKeyEvent, but with typing a newline. 111 const char* interpretNewLine(int modifiers) 112 { 113 WebKeyboardEvent keyboardEvent; 114 setupKeyDownEvent(&keyboardEvent, '\r', modifiers); 115 return interpretKeyEvent(keyboardEvent, PlatformEvent::Char); 116 } 117 118 // A name for "no modifiers set". 119 static const int noModifiers = 0; 120 }; 121 122 TEST_F(KeyboardTest, TestCtrlReturn) 123 { 124 EXPECT_STREQ("InsertNewline", interpretCtrlKeyPress(0xD)); 125 } 126 127 TEST_F(KeyboardTest, TestOSModifierZ) 128 { 129 #if !OS(MACOSX) 130 EXPECT_STREQ("Undo", interpretOSModifierKeyPress('Z')); 131 #endif 132 } 133 134 TEST_F(KeyboardTest, TestOSModifierY) 135 { 136 #if !OS(MACOSX) 137 EXPECT_STREQ("Redo", interpretOSModifierKeyPress('Y')); 138 #endif 139 } 140 141 TEST_F(KeyboardTest, TestOSModifierA) 142 { 143 #if !OS(MACOSX) 144 EXPECT_STREQ("SelectAll", interpretOSModifierKeyPress('A')); 145 #endif 146 } 147 148 TEST_F(KeyboardTest, TestOSModifierX) 149 { 150 #if !OS(MACOSX) 151 EXPECT_STREQ("Cut", interpretOSModifierKeyPress('X')); 152 #endif 153 } 154 155 TEST_F(KeyboardTest, TestOSModifierC) 156 { 157 #if !OS(MACOSX) 158 EXPECT_STREQ("Copy", interpretOSModifierKeyPress('C')); 159 #endif 160 } 161 162 TEST_F(KeyboardTest, TestOSModifierV) 163 { 164 #if !OS(MACOSX) 165 EXPECT_STREQ("Paste", interpretOSModifierKeyPress('V')); 166 #endif 167 } 168 169 TEST_F(KeyboardTest, TestEscape) 170 { 171 WebKeyboardEvent keyboardEvent; 172 setupKeyDownEvent(&keyboardEvent, WebCore::VKEY_ESCAPE, noModifiers); 173 174 const char* result = interpretKeyEvent(keyboardEvent, 175 PlatformEvent::RawKeyDown); 176 EXPECT_STREQ("Cancel", result); 177 } 178 179 TEST_F(KeyboardTest, TestInsertTab) 180 { 181 EXPECT_STREQ("InsertTab", interpretTab(noModifiers)); 182 } 183 184 TEST_F(KeyboardTest, TestInsertBackTab) 185 { 186 EXPECT_STREQ("InsertBacktab", interpretTab(WebInputEvent::ShiftKey)); 187 } 188 189 TEST_F(KeyboardTest, TestInsertNewline) 190 { 191 EXPECT_STREQ("InsertNewline", interpretNewLine(noModifiers)); 192 } 193 194 TEST_F(KeyboardTest, TestInsertNewline2) 195 { 196 EXPECT_STREQ("InsertNewline", interpretNewLine(WebInputEvent::ControlKey)); 197 } 198 199 TEST_F(KeyboardTest, TestInsertLineBreak) 200 { 201 EXPECT_STREQ("InsertLineBreak", interpretNewLine(WebInputEvent::ShiftKey)); 202 } 203 204 TEST_F(KeyboardTest, TestInsertNewline3) 205 { 206 EXPECT_STREQ("InsertNewline", interpretNewLine(WebInputEvent::AltKey)); 207 } 208 209 TEST_F(KeyboardTest, TestInsertNewline4) 210 { 211 int modifiers = WebInputEvent::AltKey | WebInputEvent::ShiftKey; 212 const char* result = interpretNewLine(modifiers); 213 EXPECT_STREQ("InsertNewline", result); 214 } 215 216 } // empty namespace 217