| // Copyright 2017 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 "components/autofill/content/browser/key_press_handler_manager.h" |
| |
| #include <string> |
| |
| #include "base/bind.h" |
| #include "base/time/time.h" |
| #include "content/public/browser/native_web_keyboard_event.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace autofill { |
| |
| namespace { |
| |
| const content::NativeWebKeyboardEvent |
| kDummyEvent(blink::WebInputEvent::kUndefined, 0, base::TimeTicks()); |
| |
| // Dummy keyboard event handler: ignores the event, but appends the given |name| |
| // to a logging |target|. |
| bool DummyHandler(const char* name, |
| std::string* target, |
| const content::NativeWebKeyboardEvent& /*event*/) { |
| target->append(name); |
| return false; |
| } |
| |
| // A delegate which logs the handlers instead of adding and removing them. |
| class LoggingDelegate : public KeyPressHandlerManager::Delegate { |
| public: |
| explicit LoggingDelegate(std::string* target) : target_(target) {} |
| |
| // KeyPressHandlerManager::Delegate: |
| void AddHandler(const content::RenderWidgetHost::KeyPressEventCallback& |
| handler) override { |
| target_->append("A"); |
| handler.Run(kDummyEvent); |
| } |
| void RemoveHandler(const content::RenderWidgetHost::KeyPressEventCallback& |
| handler) override { |
| target_->append("R"); |
| handler.Run(kDummyEvent); |
| } |
| |
| private: |
| std::string* const target_; |
| }; |
| |
| } // namespace |
| |
| class KeyPressHandlerManagerTest : public testing::Test { |
| public: |
| KeyPressHandlerManagerTest() : delegate_(&callback_trace_) {} |
| |
| protected: |
| content::RenderWidgetHost::KeyPressEventCallback CallbackForName( |
| const char* name) { |
| return base::Bind(DummyHandler, name, &callback_trace_); |
| } |
| |
| // String encoding the events related to adding and removing callbacks. For |
| // example, "A1R1A2R2" means that callback "1" was added, then removed, and |
| // then callback "2" was added and removed. |
| std::string callback_trace_; |
| |
| LoggingDelegate delegate_; |
| }; |
| |
| // Removing should remove the previously added callback. |
| TEST_F(KeyPressHandlerManagerTest, AddRemove) { |
| KeyPressHandlerManager manager(&delegate_); |
| manager.RegisterKeyPressHandler(CallbackForName("1")); |
| manager.RemoveKeyPressHandler(); |
| EXPECT_EQ("A1R1", callback_trace_); |
| } |
| |
| // Registering a new callback should remove the old one. |
| TEST_F(KeyPressHandlerManagerTest, AddReplace) { |
| KeyPressHandlerManager manager(&delegate_); |
| manager.RegisterKeyPressHandler(CallbackForName("1")); |
| manager.RegisterKeyPressHandler(CallbackForName("2")); |
| manager.RemoveKeyPressHandler(); |
| EXPECT_EQ("A1R1A2R2", callback_trace_); |
| } |
| |
| // Without registering a callback first, none should be removed. |
| TEST_F(KeyPressHandlerManagerTest, NoRemove) { |
| KeyPressHandlerManager manager(&delegate_); |
| manager.RemoveKeyPressHandler(); |
| EXPECT_EQ(std::string(), callback_trace_); |
| } |
| |
| // Adding one callback twice should be a no-op. |
| TEST_F(KeyPressHandlerManagerTest, AddTwice) { |
| KeyPressHandlerManager manager(&delegate_); |
| auto callback = CallbackForName("1"); |
| manager.RegisterKeyPressHandler(callback); |
| manager.RegisterKeyPressHandler(callback); |
| manager.RemoveKeyPressHandler(); |
| EXPECT_EQ("A1R1", callback_trace_); |
| } |
| |
| // Removing one callback twice should be a no-op. |
| TEST_F(KeyPressHandlerManagerTest, RemoveTwice) { |
| KeyPressHandlerManager manager(&delegate_); |
| manager.RegisterKeyPressHandler(CallbackForName("1")); |
| manager.RemoveKeyPressHandler(); |
| manager.RemoveKeyPressHandler(); |
| EXPECT_EQ("A1R1", callback_trace_); |
| } |
| |
| } // namespace autofill |