[M120 Migration]Fix for crash during chrome exit
[platform/framework/web/chromium-efl.git] / chrome / browser / global_keyboard_shortcuts_mac_unittest.mm
1 // Copyright 2009 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/global_keyboard_shortcuts_mac.h"
6
7 #include <AppKit/NSEvent.h>
8 #include <Carbon/Carbon.h>
9 #include <stddef.h>
10
11 #include <initializer_list>
12
13 #include "base/check_op.h"
14 #include "chrome/app/chrome_command_ids.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "ui/base/buildflags.h"
17 #include "ui/events/keycodes/keyboard_code_conversion_mac.h"
18
19 namespace {
20
21 enum class CommandKeyState : bool {
22   kUp,
23   kDown,
24 };
25 enum class ShiftKeyState : bool {
26   kUp,
27   kDown,
28 };
29 enum class OptionKeyState : bool {
30   kUp,
31   kDown,
32 };
33 enum class ControlKeyState : bool {
34   kUp,
35   kDown,
36 };
37
38 int CommandForKeys(int vkey_code,
39                    CommandKeyState command,
40                    ShiftKeyState shift = ShiftKeyState::kUp,
41                    OptionKeyState option = OptionKeyState::kUp,
42                    ControlKeyState control = ControlKeyState::kUp) {
43   NSUInteger modifier_flags = 0;
44   if (command == CommandKeyState::kDown)
45     modifier_flags |= NSEventModifierFlagCommand;
46   if (shift == ShiftKeyState::kDown)
47     modifier_flags |= NSEventModifierFlagShift;
48   if (option == OptionKeyState::kDown)
49     modifier_flags |= NSEventModifierFlagOption;
50   if (control == ControlKeyState::kDown)
51     modifier_flags |= NSEventModifierFlagControl;
52
53   switch (vkey_code) {
54     case kVK_UpArrow:
55     case kVK_DownArrow:
56     case kVK_LeftArrow:
57     case kVK_RightArrow:
58       // Docs say that this is set for numpad *and* arrow keys.
59       modifier_flags |= NSEventModifierFlagNumericPad;
60       [[fallthrough]];
61     case kVK_Help:
62     case kVK_ForwardDelete:
63     case kVK_Home:
64     case kVK_End:
65     case kVK_PageUp:
66     case kVK_PageDown:
67       // Docs say that this is set for function keys *and* the cluster of six
68       // navigation keys in the center of the keyboard *and* arrow keys.
69       modifier_flags |= NSEventModifierFlagFunction;
70       break;
71     default:
72       break;
73   }
74
75   unichar shifted_character;
76   unichar character;
77   int result = ui::MacKeyCodeForWindowsKeyCode(
78       ui::KeyboardCodeFromKeyCode(vkey_code), modifier_flags,
79       &shifted_character, &character);
80   DCHECK_NE(result, -1);
81
82   NSEvent* event = [NSEvent
83                  keyEventWithType:NSEventTypeKeyDown
84                          location:NSZeroPoint
85                     modifierFlags:modifier_flags
86                         timestamp:0.0
87                      windowNumber:0
88                           context:nil
89                        characters:[NSString stringWithFormat:@"%C", character]
90       charactersIgnoringModifiers:[NSString
91                                       stringWithFormat:@"%C", shifted_character]
92                         isARepeat:NO
93                           keyCode:vkey_code];
94
95   return CommandForKeyEvent(event).chrome_command;
96 }
97
98 }  // namespace
99
100 TEST(GlobalKeyboardShortcuts, BasicFunctionality) {
101   // Test that an invalid shortcut translates into an invalid command id.
102   const int kInvalidCommandId = -1;
103   const int no_key_code = 0;
104   EXPECT_EQ(
105       kInvalidCommandId,
106       CommandForKeys(no_key_code, CommandKeyState::kUp, ShiftKeyState::kUp,
107                      OptionKeyState::kUp, ControlKeyState::kUp));
108
109   // Check that all known keyboard shortcuts return valid results.
110   for (const auto& shortcut : GetShortcutsNotPresentInMainMenu()) {
111     CommandKeyState command =
112         shortcut.command_key ? CommandKeyState::kDown : CommandKeyState::kUp;
113     ShiftKeyState shift =
114         shortcut.shift_key ? ShiftKeyState::kDown : ShiftKeyState::kUp;
115     OptionKeyState option =
116         shortcut.opt_key ? OptionKeyState::kDown : OptionKeyState::kUp;
117     ControlKeyState control =
118         shortcut.cntrl_key ? ControlKeyState::kDown : ControlKeyState::kUp;
119
120     int cmd_num =
121         CommandForKeys(shortcut.vkey_code, command, shift, option, control);
122     EXPECT_EQ(cmd_num, shortcut.chrome_command);
123   }
124   // Test that switching tabs triggers off keycodes and not characters (visible
125   // with the Italian keyboard layout).
126   EXPECT_EQ(
127       IDC_SELECT_TAB_0,
128       CommandForKeys(kVK_ANSI_1, CommandKeyState::kDown, ShiftKeyState::kUp,
129                      OptionKeyState::kUp, ControlKeyState::kUp));
130 }
131
132 TEST(GlobalKeyboardShortcuts, KeypadNumberKeysMatch) {
133   // Test that the shortcuts that are generated by keypad number keys match the
134   // equivalent keys.
135   static const struct {
136     int keycode;
137     int keypad_keycode;
138   } equivalents[] = {
139     {kVK_ANSI_0, kVK_ANSI_Keypad0},
140     {kVK_ANSI_1, kVK_ANSI_Keypad1},
141     {kVK_ANSI_2, kVK_ANSI_Keypad2},
142     {kVK_ANSI_3, kVK_ANSI_Keypad3},
143     {kVK_ANSI_4, kVK_ANSI_Keypad4},
144     {kVK_ANSI_5, kVK_ANSI_Keypad5},
145     {kVK_ANSI_6, kVK_ANSI_Keypad6},
146     {kVK_ANSI_7, kVK_ANSI_Keypad7},
147     {kVK_ANSI_8, kVK_ANSI_Keypad8},
148     {kVK_ANSI_9, kVK_ANSI_Keypad9},
149   };
150
151   // We only consider unshifted keys. A shifted numpad key gives a different
152   // keyEquivalent than a shifted number key.
153   const ShiftKeyState shift = ShiftKeyState::kUp;
154   for (auto equivalent : equivalents) {
155     for (CommandKeyState command :
156          {CommandKeyState::kUp, CommandKeyState::kDown}) {
157       for (OptionKeyState option :
158            {OptionKeyState::kUp, OptionKeyState::kDown}) {
159         for (ControlKeyState control :
160              {ControlKeyState::kUp, ControlKeyState::kDown}) {
161           EXPECT_EQ(CommandForKeys(equivalent.keycode, command, shift, option,
162                                    control),
163                     CommandForKeys(equivalent.keypad_keycode, command, shift,
164                                    option, control));
165         }
166       }
167     }
168   }
169 }