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