1 // Copyright (c) 2012 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 #include "ui/base/accelerators/accelerator_manager.h" 6 7 #include "base/compiler_specific.h" 8 #include "testing/gtest/include/gtest/gtest.h" 9 #include "ui/events/event_constants.h" 10 #include "ui/events/keycodes/keyboard_codes.h" 11 12 namespace ui { 13 namespace test { 14 15 namespace { 16 17 class TestTarget : public AcceleratorTarget { 18 public: 19 TestTarget() : accelerator_pressed_count_(0) {} 20 virtual ~TestTarget() {} 21 22 int accelerator_pressed_count() const { 23 return accelerator_pressed_count_; 24 } 25 26 void set_accelerator_pressed_count(int accelerator_pressed_count) { 27 accelerator_pressed_count_ = accelerator_pressed_count; 28 } 29 30 // Overridden from AcceleratorTarget: 31 virtual bool AcceleratorPressed(const Accelerator& accelerator) OVERRIDE; 32 virtual bool CanHandleAccelerators() const OVERRIDE; 33 34 private: 35 int accelerator_pressed_count_; 36 37 DISALLOW_COPY_AND_ASSIGN(TestTarget); 38 }; 39 40 bool TestTarget::AcceleratorPressed(const Accelerator& accelerator) { 41 ++accelerator_pressed_count_; 42 return true; 43 } 44 45 bool TestTarget::CanHandleAccelerators() const { 46 return true; 47 } 48 49 Accelerator GetAccelerator(KeyboardCode code, int mask) { 50 return Accelerator(code, mask); 51 } 52 53 } // namespace 54 55 class AcceleratorManagerTest : public testing::Test { 56 public: 57 AcceleratorManagerTest() {} 58 virtual ~AcceleratorManagerTest() {} 59 60 AcceleratorManager manager_; 61 }; 62 63 TEST_F(AcceleratorManagerTest, Register) { 64 const Accelerator accelerator_a(VKEY_A, EF_NONE); 65 TestTarget target; 66 manager_.Register(accelerator_a, AcceleratorManager::kNormalPriority, 67 &target); 68 69 // The registered accelerator is processed. 70 EXPECT_TRUE(manager_.Process(accelerator_a)); 71 EXPECT_EQ(1, target.accelerator_pressed_count()); 72 } 73 74 TEST_F(AcceleratorManagerTest, RegisterMultipleTarget) { 75 const Accelerator accelerator_a(VKEY_A, EF_NONE); 76 TestTarget target1; 77 manager_.Register(accelerator_a, AcceleratorManager::kNormalPriority, 78 &target1); 79 TestTarget target2; 80 manager_.Register(accelerator_a, AcceleratorManager::kNormalPriority, 81 &target2); 82 83 // If multiple targets are registered with the same accelerator, the target 84 // registered later processes the accelerator. 85 EXPECT_TRUE(manager_.Process(accelerator_a)); 86 EXPECT_EQ(0, target1.accelerator_pressed_count()); 87 EXPECT_EQ(1, target2.accelerator_pressed_count()); 88 } 89 90 TEST_F(AcceleratorManagerTest, Unregister) { 91 const Accelerator accelerator_a(VKEY_A, EF_NONE); 92 TestTarget target; 93 manager_.Register(accelerator_a, AcceleratorManager::kNormalPriority, 94 &target); 95 const Accelerator accelerator_b(VKEY_B, EF_NONE); 96 manager_.Register(accelerator_b, AcceleratorManager::kNormalPriority, 97 &target); 98 99 // Unregistering a different accelerator does not affect the other 100 // accelerator. 101 manager_.Unregister(accelerator_b, &target); 102 EXPECT_TRUE(manager_.Process(accelerator_a)); 103 EXPECT_EQ(1, target.accelerator_pressed_count()); 104 105 // The unregistered accelerator is no longer processed. 106 target.set_accelerator_pressed_count(0); 107 manager_.Unregister(accelerator_a, &target); 108 EXPECT_FALSE(manager_.Process(accelerator_a)); 109 EXPECT_EQ(0, target.accelerator_pressed_count()); 110 } 111 112 TEST_F(AcceleratorManagerTest, UnregisterAll) { 113 const Accelerator accelerator_a(VKEY_A, EF_NONE); 114 TestTarget target1; 115 manager_.Register(accelerator_a, AcceleratorManager::kNormalPriority, 116 &target1); 117 const Accelerator accelerator_b(VKEY_B, EF_NONE); 118 manager_.Register(accelerator_b, AcceleratorManager::kNormalPriority, 119 &target1); 120 const Accelerator accelerator_c(VKEY_C, EF_NONE); 121 TestTarget target2; 122 manager_.Register(accelerator_c, AcceleratorManager::kNormalPriority, 123 &target2); 124 manager_.UnregisterAll(&target1); 125 126 // All the accelerators registered for |target1| are no longer processed. 127 EXPECT_FALSE(manager_.Process(accelerator_a)); 128 EXPECT_FALSE(manager_.Process(accelerator_b)); 129 EXPECT_EQ(0, target1.accelerator_pressed_count()); 130 131 // UnregisterAll with a different target does not affect the other target. 132 EXPECT_TRUE(manager_.Process(accelerator_c)); 133 EXPECT_EQ(1, target2.accelerator_pressed_count()); 134 } 135 136 TEST_F(AcceleratorManagerTest, Process) { 137 TestTarget target; 138 139 // Test all 2*2*2 cases (shift/control/alt = on/off). 140 for (int mask = 0; mask < 2 * 2 * 2; ++mask) { 141 Accelerator accelerator(GetAccelerator(VKEY_A, mask)); 142 const base::string16 text = accelerator.GetShortcutText(); 143 manager_.Register(accelerator, AcceleratorManager::kNormalPriority, 144 &target); 145 146 // The registered accelerator is processed. 147 const int last_count = target.accelerator_pressed_count(); 148 EXPECT_TRUE(manager_.Process(accelerator)) << text; 149 EXPECT_EQ(last_count + 1, target.accelerator_pressed_count()) << text; 150 151 // The non-registered accelerators are not processed. 152 accelerator.set_type(ET_UNKNOWN); 153 EXPECT_FALSE(manager_.Process(accelerator)) << text; // different type 154 accelerator.set_type(ET_TRANSLATED_KEY_PRESS); 155 EXPECT_FALSE(manager_.Process(accelerator)) << text; // different type 156 accelerator.set_type(ET_KEY_RELEASED); 157 EXPECT_FALSE(manager_.Process(accelerator)) << text; // different type 158 accelerator.set_type(ET_TRANSLATED_KEY_RELEASE); 159 EXPECT_FALSE(manager_.Process(accelerator)) << text; // different type 160 161 EXPECT_FALSE(manager_.Process(GetAccelerator(VKEY_UNKNOWN, mask))) 162 << text; // different vkey 163 EXPECT_FALSE(manager_.Process(GetAccelerator(VKEY_B, mask))) 164 << text; // different vkey 165 EXPECT_FALSE(manager_.Process(GetAccelerator(VKEY_SHIFT, mask))) 166 << text; // different vkey 167 168 for (int test_mask = 0; test_mask < 2 * 2 * 2; ++test_mask) { 169 if (test_mask == mask) 170 continue; 171 const Accelerator test_accelerator(GetAccelerator(VKEY_A, test_mask)); 172 const base::string16 test_text = test_accelerator.GetShortcutText(); 173 EXPECT_FALSE(manager_.Process(test_accelerator)) 174 << text << ", " << test_text; // different modifiers 175 } 176 177 EXPECT_EQ(last_count + 1, target.accelerator_pressed_count()) << text; 178 manager_.UnregisterAll(&target); 179 } 180 } 181 182 } // namespace test 183 } // namespace ui 184