Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / ui / cocoa / accelerators_cocoa_browsertest.mm
blobce3f2772f7a133d54f7487509c0c9e83213444d5
1 // Copyright 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.
5 #import <Cocoa/Cocoa.h>
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"
14 typedef InProcessBrowserTest AcceleratorsCocoaBrowserTest;
16 namespace {
18 // Adds all NSMenuItems with an accelerator to the array.
19 void AddAcceleratorItemsToArray(NSMenu* menu, NSMutableArray* array) {
20   for (NSMenuItem* item in [menu itemArray]) {
21     NSMenu* submenu = item.submenu;
22     if (submenu)
23       AddAcceleratorItemsToArray(submenu, array);
25     if (item.keyEquivalent.length > 0)
26       [array addObject:item];
27   }
30 // Returns the NSMenuItem that has the given keyEquivalent and modifiers, or
31 // nil.
32 NSMenuItem* MenuContainsAccelerator(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           MenuContainsAccelerator(submenu, key_equivalent, modifiers);
40       if (result)
41         return result;
42     }
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;
55 }  // namespace
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   AddAcceleratorItemsToArray(menu, array);
65   for (NSMenuItem* item in array) {
66     NSInteger command_id = item.tag;
67     AcceleratorsCocoa* keymap = AcceleratorsCocoa::GetInstance();
68     const ui::Accelerator* accelerator;
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);
76       EXPECT_TRUE(accelerator);
77       return;
78     }
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;
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();
92     // Check that the menu item's keyEquivalent matches the one from the
93     // Cocoa accelerator map.
94     EXPECT_NSEQ(key_equivalent, item.keyEquivalent);
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   }
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());
122     // Check that there exists a corresponding NSMenuItem.
123     NSMenuItem* item =
124         MenuContainsAccelerator([NSApp mainMenu],
125                                 platform_accelerator->characters(),
126                                 platform_accelerator->modifier_mask());
127     EXPECT_TRUE(item);
129     // If the menu uses a commandDispatch:, the tag must match the command id!
130     if (item.action == @selector(commandDispatch:))
131       EXPECT_EQ(item.tag, it->first);
132   }