OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #import <Cocoa/Cocoa.h> | |
6 | |
7 #include "base/logging.h" | |
8 #import "chrome/browser/ui/cocoa/accelerators_cocoa.h" | |
9 #include "chrome/test/base/in_process_browser_test.h" | |
10 #include "ui/base/accelerators/platform_accelerator_cocoa.h" | |
11 #import "ui/events/keycodes/keyboard_code_conversion_mac.h" | |
12 #include "testing/gtest_mac.h" | |
13 | |
14 typedef InProcessBrowserTest AcceleratorsCocoaBrowserTest; | |
15 | |
16 namespace { | |
17 | |
18 // Adds all NSMenuItems with an accelerator to the array. | |
19 void AddAccelerator(NSMenu* menu, NSMutableArray* array) { | |
20 for (NSMenuItem* item in [menu itemArray]) { | |
21 NSMenu* submenu = item.submenu; | |
22 if (submenu) | |
23 AddAccelerator(submenu, array); | |
24 | |
25 if (item.keyEquivalent.length > 0) | |
26 [array addObject:item]; | |
27 } | |
28 } | |
29 | |
30 // Returns the NSMenuItem that has the given keyEquivalent and modifiers, or | |
31 // nil. | |
32 NSMenuItem* MenuContains(NSMenu* menu, | |
33 NSString* key_equivalent, | |
34 NSUInteger modifiers) { | |
35 for (NSMenuItem* item in [menu itemArray]) { | |
36 NSMenu* submenu = item.submenu; | |
37 if (submenu) { | |
38 NSMenuItem* result = | |
39 MenuContains(submenu, key_equivalent, modifiers); | |
40 if (result) | |
41 return result; | |
42 } | |
43 | |
44 if ([item.keyEquivalent isEqual:key_equivalent]) { | |
45 BOOL maskEqual = | |
46 (modifiers == item.keyEquivalentModifierMask) || | |
47 ((modifiers & (~NSShiftKeyMask)) == item.keyEquivalentModifierMask); | |
48 if (maskEqual) | |
49 return item; | |
50 } | |
51 } | |
52 return nil; | |
53 } | |
54 | |
55 } // namespace | |
56 | |
57 // Checks that each NSMenuItem in the main menu has a corresponding accelerator, | |
58 // and the keyEquivalent/modifiers match. | |
59 IN_PROC_BROWSER_TEST_F(AcceleratorsCocoaBrowserTest, | |
60 MainMenuAcceleratorsInMapping) { | |
61 NSMenu* menu = [NSApp mainMenu]; | |
62 NSMutableArray* array = [NSMutableArray array]; | |
63 AddAccelerator(menu, array); | |
64 | |
65 for (NSMenuItem* item in array) { | |
66 int command_id = item.tag; | |
Robert Sesek
2014/02/11 22:18:16
-tag returns NSInteger
erikchen
2014/02/11 23:16:28
Done.
| |
67 AcceleratorsCocoa* keymap = AcceleratorsCocoa::GetInstance(); | |
68 const ui::Accelerator* accelerator; | |
69 | |
70 // If the tag is zero, then the NSMenuItem must use a custom selector. | |
71 // Check that the accelerator is present as an un-mapped accelerator. | |
72 if (command_id == 0) { | |
73 accelerator = keymap->GetAcceleratorForHotKey( | |
74 item.keyEquivalent, item.keyEquivalentModifierMask); | |
75 | |
76 EXPECT_TRUE(accelerator); | |
77 return; | |
78 } | |
79 | |
80 // If the tag isn't zero, then it must correspond to an IDC_* command. | |
81 accelerator = keymap->GetAcceleratorForCommand(command_id); | |
82 EXPECT_TRUE(accelerator); | |
83 if (!accelerator) | |
84 continue; | |
85 | |
86 // Get the Cocoa key_equivalent associated with the accelerator. | |
87 const ui::PlatformAcceleratorCocoa* platform_accelerator = | |
88 static_cast<const ui::PlatformAcceleratorCocoa*>( | |
89 accelerator->platform_accelerator()); | |
90 NSString* key_equivalent = platform_accelerator->characters(); | |
91 | |
92 // Check that the menu item's keyEquivalent matches the one from the | |
93 // cocoa accelerator map. | |
Robert Sesek
2014/02/11 22:18:16
nit: Cocoa
erikchen
2014/02/11 23:16:28
Done.
| |
94 EXPECT_NSEQ(key_equivalent, item.keyEquivalent); | |
95 | |
96 // Check that the menu item's modifier mask matches the one stored in the | |
97 // accelerator. A mask that include NSShiftKeyMask may not include the | |
98 // relevant bit (the information is reflected in the keyEquivalent of the | |
99 // NSMenuItem). | |
100 NSUInteger mask = platform_accelerator->modifier_mask(); | |
101 BOOL maskEqual = | |
102 (mask == item.keyEquivalentModifierMask) || | |
103 ((mask & (~NSShiftKeyMask)) == item.keyEquivalentModifierMask); | |
104 EXPECT_TRUE(maskEqual); | |
105 } | |
106 } | |
107 | |
108 // Check that each accelerator with a command_id has an associated NSMenuItem | |
109 // in the main menu. If the selector is commandDispatch:, then the tag must | |
110 // match the command_id. | |
111 IN_PROC_BROWSER_TEST_F(AcceleratorsCocoaBrowserTest, | |
112 MappingAcceleratorsInMainMenu) { | |
113 AcceleratorsCocoa* keymap = AcceleratorsCocoa::GetInstance(); | |
114 for (AcceleratorsCocoa::AcceleratorMap::iterator it = | |
115 keymap->accelerators_.begin(); | |
116 it != keymap->accelerators_.end(); | |
117 ++it) { | |
118 const ui::PlatformAcceleratorCocoa* platform_accelerator = | |
119 static_cast<const ui::PlatformAcceleratorCocoa*>( | |
120 it->second.platform_accelerator()); | |
121 | |
122 // Check that there exists a corresponding NSMenuItem. | |
123 NSMenuItem* item = MenuContains([NSApp mainMenu], | |
124 platform_accelerator->characters(), | |
125 platform_accelerator->modifier_mask()); | |
126 EXPECT_TRUE(item); | |
127 | |
128 // If the menu uses a commandDispatch:, the tag must match the command id! | |
129 if (item.action == @selector(commandDispatch:)) | |
130 EXPECT_EQ(item.tag, it->first); | |
131 } | |
132 } | |
OLD | NEW |