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