1/*
2 * Copyright (C) 2012 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#import <Cocoa/Cocoa.h>
34#include <gtest/gtest.h>
35
36#include "core/events/KeyboardEvent.h"
37#include "platform/WindowsKeyboardCodes.h"
38#include "public/web/WebInputEvent.h"
39#include "public/web/mac/WebInputEventFactory.h"
40
41using blink::WebInputEventFactory;
42using blink::WebKeyboardEvent;
43
44namespace {
45
46struct KeyMappingEntry {
47    int macKeyCode;
48    unichar character;
49    int windowsKeyCode;
50};
51
52NSEvent* BuildFakeKeyEvent(NSUInteger keyCode, unichar character, NSUInteger modifierFlags)
53{
54    NSString* string = [NSString stringWithCharacters:&character length:1];
55    return [NSEvent keyEventWithType:NSKeyDown
56                            location:NSZeroPoint
57                       modifierFlags:modifierFlags
58                           timestamp:0.0
59                        windowNumber:0
60                             context:nil
61                          characters:string
62         charactersIgnoringModifiers:string
63                           isARepeat:NO
64                             keyCode:keyCode];
65}
66
67} // namespace
68
69// Test that arrow keys don't have numpad modifier set.
70TEST(WebInputEventFactoryTestMac, ArrowKeyNumPad)
71{
72    // Left
73    NSEvent* macEvent = BuildFakeKeyEvent(0x7B, NSLeftArrowFunctionKey, NSNumericPadKeyMask);
74    WebKeyboardEvent webEvent = WebInputEventFactory::keyboardEvent(macEvent);
75    EXPECT_EQ(0, webEvent.modifiers);
76
77    // Right
78    macEvent = BuildFakeKeyEvent(0x7C, NSRightArrowFunctionKey, NSNumericPadKeyMask);
79    webEvent = WebInputEventFactory::keyboardEvent(macEvent);
80    EXPECT_EQ(0, webEvent.modifiers);
81
82    // Down
83    macEvent = BuildFakeKeyEvent(0x7D, NSDownArrowFunctionKey, NSNumericPadKeyMask);
84    webEvent = WebInputEventFactory::keyboardEvent(macEvent);
85    EXPECT_EQ(0, webEvent.modifiers);
86
87    // Up
88    macEvent = BuildFakeKeyEvent(0x7E, NSUpArrowFunctionKey, NSNumericPadKeyMask);
89    webEvent = WebInputEventFactory::keyboardEvent(macEvent);
90    EXPECT_EQ(0, webEvent.modifiers);
91}
92
93// Test that numpad keys get mapped correctly.
94TEST(WebInputEventFactoryTestMac, NumPadMapping)
95{
96    KeyMappingEntry table[] =
97    {
98        {65, '.', VK_DECIMAL},
99        {67, '*', VK_MULTIPLY},
100        {69, '+', VK_ADD},
101        {71, NSClearLineFunctionKey, VK_CLEAR},
102        {75, '/', VK_DIVIDE},
103        {76, 3,   VK_RETURN},
104        {78, '-', VK_SUBTRACT},
105        {81, '=', VK_OEM_PLUS},
106        {82, '0', VK_NUMPAD0},
107        {83, '1', VK_NUMPAD1},
108        {84, '2', VK_NUMPAD2},
109        {85, '3', VK_NUMPAD3},
110        {86, '4', VK_NUMPAD4},
111        {87, '5', VK_NUMPAD5},
112        {88, '6', VK_NUMPAD6},
113        {89, '7', VK_NUMPAD7},
114        {91, '8', VK_NUMPAD8},
115        {92, '9', VK_NUMPAD9},
116    };
117
118    for (size_t i = 0; i < arraysize(table); ++i) {
119        NSEvent* macEvent = BuildFakeKeyEvent(table[i].macKeyCode, table[i].character, 0);
120        WebKeyboardEvent webEvent = WebInputEventFactory::keyboardEvent(macEvent);
121        EXPECT_EQ(table[i].windowsKeyCode, webEvent.windowsKeyCode);
122    }
123}
124