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 "WebInputEvent.h" 36 #include "WebInputEventConversion.h" 37 #include "core/editing/Editor.h" 38 #include "core/events/EventTarget.h" 39 #include "core/events/KeyboardEvent.h" 40 #include "platform/KeyboardCodes.h" 41 42 using namespace WebCore; 43 using namespace blink; 44 45 namespace { 46 47 class KeyboardTest : public testing::Test { 48 public: 49 50 // Pass a WebKeyboardEvent into the EditorClient and get back the string 51 // name of which editing event that key causes. 52 // E.g., sending in the enter key gives back "InsertNewline". 53 const char* interpretKeyEvent( 54 const WebKeyboardEvent& webKeyboardEvent, 55 PlatformEvent::Type keyType) 56 { 57 PlatformKeyboardEventBuilder evt(webKeyboardEvent); 58 evt.setKeyType(keyType); 59 RefPtr<KeyboardEvent> keyboardEvent = KeyboardEvent::create(evt, 0); 60 return Editor::interpretKeyEvent(keyboardEvent.get()); 61 } 62 63 // Set up a WebKeyboardEvent KEY_DOWN event with key code and modifiers. 64 void setupKeyDownEvent(WebKeyboardEvent* keyboardEvent, 65 char keyCode, 66 int modifiers) 67 { 68 keyboardEvent->windowsKeyCode = keyCode; 69 keyboardEvent->modifiers = modifiers; 70 keyboardEvent->type = WebInputEvent::KeyDown; 71 keyboardEvent->text[0] = keyCode; 72 keyboardEvent->setKeyIdentifierFromWindowsKeyCode(); 73 } 74 75 // Like interpretKeyEvent, but with pressing down OSModifier+|keyCode|. 76 // OSModifier is the platform's standard modifier key: control on most 77 // platforms, but meta (command) on Mac. 78 const char* interpretOSModifierKeyPress(char keyCode) 79 { 80 WebKeyboardEvent keyboardEvent; 81 #if OS(MACOSX) 82 WebInputEvent::Modifiers osModifier = WebInputEvent::MetaKey; 83 #else 84 WebInputEvent::Modifiers osModifier = WebInputEvent::ControlKey; 85 #endif 86 setupKeyDownEvent(&keyboardEvent, keyCode, osModifier); 87 return interpretKeyEvent(keyboardEvent, PlatformEvent::RawKeyDown); 88 } 89 90 // Like interpretKeyEvent, but with pressing down ctrl+|keyCode|. 91 const char* interpretCtrlKeyPress(char keyCode) 92 { 93 WebKeyboardEvent keyboardEvent; 94 setupKeyDownEvent(&keyboardEvent, keyCode, WebInputEvent::ControlKey); 95 return interpretKeyEvent(keyboardEvent, PlatformEvent::RawKeyDown); 96 } 97 98 // Like interpretKeyEvent, but with typing a tab. 99 const char* interpretTab(int modifiers) 100 { 101 WebKeyboardEvent keyboardEvent; 102 setupKeyDownEvent(&keyboardEvent, '\t', modifiers); 103 return interpretKeyEvent(keyboardEvent, PlatformEvent::Char); 104 } 105 106 // Like interpretKeyEvent, but with typing a newline. 107 const char* interpretNewLine(int modifiers) 108 { 109 WebKeyboardEvent keyboardEvent; 110 setupKeyDownEvent(&keyboardEvent, '\r', modifiers); 111 return interpretKeyEvent(keyboardEvent, PlatformEvent::Char); 112 } 113 114 // A name for "no modifiers set". 115 static const int noModifiers = 0; 116 }; 117 118 TEST_F(KeyboardTest, TestCtrlReturn) 119 { 120 EXPECT_STREQ("InsertNewline", interpretCtrlKeyPress(0xD)); 121 } 122 123 TEST_F(KeyboardTest, TestOSModifierZ) 124 { 125 #if !OS(MACOSX) 126 EXPECT_STREQ("Undo", interpretOSModifierKeyPress('Z')); 127 #endif 128 } 129 130 TEST_F(KeyboardTest, TestOSModifierY) 131 { 132 #if !OS(MACOSX) 133 EXPECT_STREQ("Redo", interpretOSModifierKeyPress('Y')); 134 #endif 135 } 136 137 TEST_F(KeyboardTest, TestOSModifierA) 138 { 139 #if !OS(MACOSX) 140 EXPECT_STREQ("SelectAll", interpretOSModifierKeyPress('A')); 141 #endif 142 } 143 144 TEST_F(KeyboardTest, TestOSModifierX) 145 { 146 #if !OS(MACOSX) 147 EXPECT_STREQ("Cut", interpretOSModifierKeyPress('X')); 148 #endif 149 } 150 151 TEST_F(KeyboardTest, TestOSModifierC) 152 { 153 #if !OS(MACOSX) 154 EXPECT_STREQ("Copy", interpretOSModifierKeyPress('C')); 155 #endif 156 } 157 158 TEST_F(KeyboardTest, TestOSModifierV) 159 { 160 #if !OS(MACOSX) 161 EXPECT_STREQ("Paste", interpretOSModifierKeyPress('V')); 162 #endif 163 } 164 165 TEST_F(KeyboardTest, TestEscape) 166 { 167 WebKeyboardEvent keyboardEvent; 168 setupKeyDownEvent(&keyboardEvent, WebCore::VKEY_ESCAPE, noModifiers); 169 170 const char* result = interpretKeyEvent(keyboardEvent, 171 PlatformEvent::RawKeyDown); 172 EXPECT_STREQ("Cancel", result); 173 } 174 175 TEST_F(KeyboardTest, TestInsertTab) 176 { 177 EXPECT_STREQ("InsertTab", interpretTab(noModifiers)); 178 } 179 180 TEST_F(KeyboardTest, TestInsertBackTab) 181 { 182 EXPECT_STREQ("InsertBacktab", interpretTab(WebInputEvent::ShiftKey)); 183 } 184 185 TEST_F(KeyboardTest, TestInsertNewline) 186 { 187 EXPECT_STREQ("InsertNewline", interpretNewLine(noModifiers)); 188 } 189 190 TEST_F(KeyboardTest, TestInsertNewline2) 191 { 192 EXPECT_STREQ("InsertNewline", interpretNewLine(WebInputEvent::ControlKey)); 193 } 194 195 TEST_F(KeyboardTest, TestInsertLineBreak) 196 { 197 EXPECT_STREQ("InsertLineBreak", interpretNewLine(WebInputEvent::ShiftKey)); 198 } 199 200 TEST_F(KeyboardTest, TestInsertNewline3) 201 { 202 EXPECT_STREQ("InsertNewline", interpretNewLine(WebInputEvent::AltKey)); 203 } 204 205 TEST_F(KeyboardTest, TestInsertNewline4) 206 { 207 int modifiers = WebInputEvent::AltKey | WebInputEvent::ShiftKey; 208 const char* result = interpretNewLine(modifiers); 209 EXPECT_STREQ("InsertNewline", result); 210 } 211 212 } // empty namespace 213