blob: b8672ec1462bde98e10c3ff66cb4fe865efd0048 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/base/accelerators/accelerator_manager.h"
#include "base/compiler_specific.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/event_constants.h"
#include "ui/events/keycodes/keyboard_codes.h"
namespace ui {
namespace test {
namespace {
class TestTarget : public AcceleratorTarget {
public:
TestTarget() : accelerator_pressed_count_(0) {}
virtual ~TestTarget() {}
int accelerator_pressed_count() const {
return accelerator_pressed_count_;
}
void set_accelerator_pressed_count(int accelerator_pressed_count) {
accelerator_pressed_count_ = accelerator_pressed_count;
}
// Overridden from AcceleratorTarget:
virtual bool AcceleratorPressed(const Accelerator& accelerator) OVERRIDE;
virtual bool CanHandleAccelerators() const OVERRIDE;
private:
int accelerator_pressed_count_;
DISALLOW_COPY_AND_ASSIGN(TestTarget);
};
bool TestTarget::AcceleratorPressed(const Accelerator& accelerator) {
++accelerator_pressed_count_;
return true;
}
bool TestTarget::CanHandleAccelerators() const {
return true;
}
Accelerator GetAccelerator(KeyboardCode code, int mask) {
return Accelerator(code, mask);
}
} // namespace
class AcceleratorManagerTest : public testing::Test {
public:
AcceleratorManagerTest() {}
virtual ~AcceleratorManagerTest() {}
AcceleratorManager manager_;
};
TEST_F(AcceleratorManagerTest, Register) {
const Accelerator accelerator_a(VKEY_A, EF_NONE);
TestTarget target;
manager_.Register(accelerator_a, AcceleratorManager::kNormalPriority,
&target);
// The registered accelerator is processed.
EXPECT_TRUE(manager_.Process(accelerator_a));
EXPECT_EQ(1, target.accelerator_pressed_count());
}
TEST_F(AcceleratorManagerTest, RegisterMultipleTarget) {
const Accelerator accelerator_a(VKEY_A, EF_NONE);
TestTarget target1;
manager_.Register(accelerator_a, AcceleratorManager::kNormalPriority,
&target1);
TestTarget target2;
manager_.Register(accelerator_a, AcceleratorManager::kNormalPriority,
&target2);
// If multiple targets are registered with the same accelerator, the target
// registered later processes the accelerator.
EXPECT_TRUE(manager_.Process(accelerator_a));
EXPECT_EQ(0, target1.accelerator_pressed_count());
EXPECT_EQ(1, target2.accelerator_pressed_count());
}
TEST_F(AcceleratorManagerTest, Unregister) {
const Accelerator accelerator_a(VKEY_A, EF_NONE);
TestTarget target;
manager_.Register(accelerator_a, AcceleratorManager::kNormalPriority,
&target);
const Accelerator accelerator_b(VKEY_B, EF_NONE);
manager_.Register(accelerator_b, AcceleratorManager::kNormalPriority,
&target);
// Unregistering a different accelerator does not affect the other
// accelerator.
manager_.Unregister(accelerator_b, &target);
EXPECT_TRUE(manager_.Process(accelerator_a));
EXPECT_EQ(1, target.accelerator_pressed_count());
// The unregistered accelerator is no longer processed.
target.set_accelerator_pressed_count(0);
manager_.Unregister(accelerator_a, &target);
EXPECT_FALSE(manager_.Process(accelerator_a));
EXPECT_EQ(0, target.accelerator_pressed_count());
}
TEST_F(AcceleratorManagerTest, UnregisterAll) {
const Accelerator accelerator_a(VKEY_A, EF_NONE);
TestTarget target1;
manager_.Register(accelerator_a, AcceleratorManager::kNormalPriority,
&target1);
const Accelerator accelerator_b(VKEY_B, EF_NONE);
manager_.Register(accelerator_b, AcceleratorManager::kNormalPriority,
&target1);
const Accelerator accelerator_c(VKEY_C, EF_NONE);
TestTarget target2;
manager_.Register(accelerator_c, AcceleratorManager::kNormalPriority,
&target2);
manager_.UnregisterAll(&target1);
// All the accelerators registered for |target1| are no longer processed.
EXPECT_FALSE(manager_.Process(accelerator_a));
EXPECT_FALSE(manager_.Process(accelerator_b));
EXPECT_EQ(0, target1.accelerator_pressed_count());
// UnregisterAll with a different target does not affect the other target.
EXPECT_TRUE(manager_.Process(accelerator_c));
EXPECT_EQ(1, target2.accelerator_pressed_count());
}
TEST_F(AcceleratorManagerTest, Process) {
TestTarget target;
// Test all 2*2*2 cases (shift/control/alt = on/off).
for (int mask = 0; mask < 2 * 2 * 2; ++mask) {
Accelerator accelerator(GetAccelerator(VKEY_A, mask));
const base::string16 text = accelerator.GetShortcutText();
manager_.Register(accelerator, AcceleratorManager::kNormalPriority,
&target);
// The registered accelerator is processed.
const int last_count = target.accelerator_pressed_count();
EXPECT_TRUE(manager_.Process(accelerator)) << text;
EXPECT_EQ(last_count + 1, target.accelerator_pressed_count()) << text;
// The non-registered accelerators are not processed.
accelerator.set_type(ET_UNKNOWN);
EXPECT_FALSE(manager_.Process(accelerator)) << text; // different type
accelerator.set_type(ET_TRANSLATED_KEY_PRESS);
EXPECT_FALSE(manager_.Process(accelerator)) << text; // different type
accelerator.set_type(ET_KEY_RELEASED);
EXPECT_FALSE(manager_.Process(accelerator)) << text; // different type
accelerator.set_type(ET_TRANSLATED_KEY_RELEASE);
EXPECT_FALSE(manager_.Process(accelerator)) << text; // different type
EXPECT_FALSE(manager_.Process(GetAccelerator(VKEY_UNKNOWN, mask)))
<< text; // different vkey
EXPECT_FALSE(manager_.Process(GetAccelerator(VKEY_B, mask)))
<< text; // different vkey
EXPECT_FALSE(manager_.Process(GetAccelerator(VKEY_SHIFT, mask)))
<< text; // different vkey
for (int test_mask = 0; test_mask < 2 * 2 * 2; ++test_mask) {
if (test_mask == mask)
continue;
const Accelerator test_accelerator(GetAccelerator(VKEY_A, test_mask));
const base::string16 test_text = test_accelerator.GetShortcutText();
EXPECT_FALSE(manager_.Process(test_accelerator))
<< text << ", " << test_text; // different modifiers
}
EXPECT_EQ(last_count + 1, target.accelerator_pressed_count()) << text;
manager_.UnregisterAll(&target);
}
}
} // namespace test
} // namespace ui