• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
TestTarget()19   TestTarget() : accelerator_pressed_count_(0) {}
~TestTarget()20   virtual ~TestTarget() {}
21 
accelerator_pressed_count() const22   int accelerator_pressed_count() const {
23     return accelerator_pressed_count_;
24   }
25 
set_accelerator_pressed_count(int accelerator_pressed_count)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 
AcceleratorPressed(const Accelerator & accelerator)40 bool TestTarget::AcceleratorPressed(const Accelerator& accelerator) {
41   ++accelerator_pressed_count_;
42   return true;
43 }
44 
CanHandleAccelerators() const45 bool TestTarget::CanHandleAccelerators() const {
46   return true;
47 }
48 
GetAccelerator(KeyboardCode code,int mask)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:
AcceleratorManagerTest()57   AcceleratorManagerTest() {}
~AcceleratorManagerTest()58   virtual ~AcceleratorManagerTest() {}
59 
60   AcceleratorManager manager_;
61 };
62 
TEST_F(AcceleratorManagerTest,Register)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 
TEST_F(AcceleratorManagerTest,RegisterMultipleTarget)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 
TEST_F(AcceleratorManagerTest,Unregister)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 
TEST_F(AcceleratorManagerTest,UnregisterAll)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 
TEST_F(AcceleratorManagerTest,Process)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