summaryrefslogtreecommitdiff
path: root/chromium/ui/base/ime/input_method_base_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/ui/base/ime/input_method_base_unittest.cc')
-rw-r--r--chromium/ui/base/ime/input_method_base_unittest.cc383
1 files changed, 383 insertions, 0 deletions
diff --git a/chromium/ui/base/ime/input_method_base_unittest.cc b/chromium/ui/base/ime/input_method_base_unittest.cc
new file mode 100644
index 00000000000..cc7304cefcc
--- /dev/null
+++ b/chromium/ui/base/ime/input_method_base_unittest.cc
@@ -0,0 +1,383 @@
+// Copyright 2013 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/ime/input_method_base.h"
+
+#include "base/scoped_observer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/ime/dummy_text_input_client.h"
+#include "ui/base/ime/input_method_observer.h"
+#include "ui/events/event.h"
+
+namespace ui {
+namespace {
+
+class ClientChangeVerifier {
+ public:
+ ClientChangeVerifier()
+ : previous_client_(NULL),
+ next_client_(NULL),
+ call_expected_(false),
+ on_will_change_focused_client_called_(false),
+ on_did_change_focused_client_called_(false),
+ on_text_input_state_changed_(false) {
+ }
+
+ // Expects that focused text input client will not be changed.
+ void ExpectClientDoesNotChange() {
+ previous_client_ = NULL;
+ next_client_ = NULL;
+ call_expected_ = false;
+ on_will_change_focused_client_called_ = false;
+ on_did_change_focused_client_called_ = false;
+ on_text_input_state_changed_ = false;
+ }
+
+ // Expects that focused text input client will be changed from
+ // |previous_client| to |next_client|.
+ void ExpectClientChange(TextInputClient* previous_client,
+ TextInputClient* next_client) {
+ previous_client_ = previous_client;
+ next_client_ = next_client;
+ call_expected_ = true;
+ on_will_change_focused_client_called_ = false;
+ on_did_change_focused_client_called_ = false;
+ on_text_input_state_changed_ = false;
+ }
+
+ // Verifies the result satisfies the expectation or not.
+ void Verify() {
+ EXPECT_EQ(call_expected_, on_will_change_focused_client_called_);
+ EXPECT_EQ(call_expected_, on_did_change_focused_client_called_);
+ EXPECT_EQ(call_expected_, on_text_input_state_changed_);
+ }
+
+ void OnWillChangeFocusedClient(TextInputClient* focused_before,
+ TextInputClient* focused) {
+ EXPECT_TRUE(call_expected_);
+
+ // Check arguments
+ EXPECT_EQ(previous_client_, focused_before);
+ EXPECT_EQ(next_client_, focused);
+
+ // Check call order
+ EXPECT_FALSE(on_will_change_focused_client_called_);
+ EXPECT_FALSE(on_did_change_focused_client_called_);
+ EXPECT_FALSE(on_text_input_state_changed_);
+
+ on_will_change_focused_client_called_ = true;
+ }
+
+ void OnDidChangeFocusedClient(TextInputClient* focused_before,
+ TextInputClient* focused) {
+ EXPECT_TRUE(call_expected_);
+
+ // Check arguments
+ EXPECT_EQ(previous_client_, focused_before);
+ EXPECT_EQ(next_client_, focused);
+
+ // Check call order
+ EXPECT_TRUE(on_will_change_focused_client_called_);
+ EXPECT_FALSE(on_did_change_focused_client_called_);
+ EXPECT_FALSE(on_text_input_state_changed_);
+
+ on_did_change_focused_client_called_ = true;
+ }
+
+ void OnTextInputStateChanged(const TextInputClient* client) {
+ EXPECT_TRUE(call_expected_);
+
+ // Check arguments
+ EXPECT_EQ(next_client_, client);
+
+ // Check call order
+ EXPECT_TRUE(on_will_change_focused_client_called_);
+ EXPECT_TRUE(on_did_change_focused_client_called_);
+ EXPECT_FALSE(on_text_input_state_changed_);
+
+ on_text_input_state_changed_ = true;
+ }
+
+ private:
+ TextInputClient* previous_client_;
+ TextInputClient* next_client_;
+ bool call_expected_;
+ bool on_will_change_focused_client_called_;
+ bool on_did_change_focused_client_called_;
+ bool on_text_input_state_changed_;
+
+ DISALLOW_COPY_AND_ASSIGN(ClientChangeVerifier);
+};
+
+class MockInputMethodBase : public InputMethodBase {
+ public:
+ // Note: this class does not take the ownership of |verifier|.
+ explicit MockInputMethodBase(ClientChangeVerifier* verifier)
+ : verifier_(verifier) {
+ }
+ virtual ~MockInputMethodBase() {
+ }
+
+ private:
+ // Overriden from InputMethod.
+ virtual bool OnUntranslatedIMEMessage(
+ const base::NativeEvent& event,
+ InputMethod::NativeEventResult* result) OVERRIDE {
+ return false;
+ }
+ virtual bool DispatchKeyEvent(const base::NativeEvent&) OVERRIDE {
+ return false;
+ }
+ virtual bool DispatchFabricatedKeyEvent(const ui::KeyEvent&) OVERRIDE {
+ return false;
+ }
+ virtual void OnCaretBoundsChanged(const TextInputClient* clien) OVERRIDE {
+ }
+ virtual void CancelComposition(const TextInputClient* clien) OVERRIDE {
+ }
+ virtual void OnInputLocaleChanged() OVERRIDE {
+ }
+ virtual std::string GetInputLocale() OVERRIDE {
+ return "";
+ }
+ virtual base::i18n::TextDirection GetInputTextDirection() OVERRIDE {
+ return base::i18n::UNKNOWN_DIRECTION;
+ }
+ virtual bool IsActive() OVERRIDE {
+ return false;
+ }
+ virtual bool IsCandidatePopupOpen() const OVERRIDE {
+ return false;
+ }
+
+ // Overriden from InputMethodBase.
+ virtual void OnWillChangeFocusedClient(TextInputClient* focused_before,
+ TextInputClient* focused) OVERRIDE {
+ verifier_->OnWillChangeFocusedClient(focused_before, focused);
+ }
+
+ virtual void OnDidChangeFocusedClient(TextInputClient* focused_before,
+ TextInputClient* focused) OVERRIDE {
+ verifier_->OnDidChangeFocusedClient(focused_before, focused);
+ }
+
+ ClientChangeVerifier* verifier_;
+ DISALLOW_COPY_AND_ASSIGN(MockInputMethodBase);
+};
+
+class MockInputMethodObserver : public InputMethodObserver {
+ public:
+ // Note: this class does not take the ownership of |verifier|.
+ explicit MockInputMethodObserver(ClientChangeVerifier* verifier)
+ : verifier_(verifier) {
+ }
+ virtual ~MockInputMethodObserver() {
+ }
+
+ private:
+ virtual void OnTextInputStateChanged(const TextInputClient* client) OVERRIDE {
+ verifier_->OnTextInputStateChanged(client);
+ }
+ virtual void OnInputMethodDestroyed(const InputMethod* client) OVERRIDE {
+ }
+
+ ClientChangeVerifier* verifier_;
+ DISALLOW_COPY_AND_ASSIGN(MockInputMethodObserver);
+};
+
+typedef ScopedObserver<InputMethod, InputMethodObserver>
+ InputMethodScopedObserver;
+
+TEST(InputMethodBaseTest, SetFocusedTextInputClient) {
+ DummyTextInputClient text_input_client_1st;
+ DummyTextInputClient text_input_client_2nd;
+
+ ClientChangeVerifier verifier;
+ MockInputMethodBase input_method(&verifier);
+ MockInputMethodObserver input_method_observer(&verifier);
+ InputMethodScopedObserver scoped_observer(&input_method_observer);
+ scoped_observer.Add(&input_method);
+
+ // Assume that the top-level-widget gains focus.
+ input_method.OnFocus();
+
+ {
+ SCOPED_TRACE("Focus from NULL to 1st TextInputClient");
+
+ ASSERT_EQ(NULL, input_method.GetTextInputClient());
+ verifier.ExpectClientChange(NULL, &text_input_client_1st);
+ input_method.SetFocusedTextInputClient(&text_input_client_1st);
+ EXPECT_EQ(&text_input_client_1st, input_method.GetTextInputClient());
+ verifier.Verify();
+ }
+
+ {
+ SCOPED_TRACE("Redundant focus events must be ignored");
+ verifier.ExpectClientDoesNotChange();
+ input_method.SetFocusedTextInputClient(&text_input_client_1st);
+ verifier.Verify();
+ }
+
+ {
+ SCOPED_TRACE("Focus from 1st to 2nd TextInputClient");
+
+ ASSERT_EQ(&text_input_client_1st, input_method.GetTextInputClient());
+ verifier.ExpectClientChange(&text_input_client_1st,
+ &text_input_client_2nd);
+ input_method.SetFocusedTextInputClient(&text_input_client_2nd);
+ EXPECT_EQ(&text_input_client_2nd, input_method.GetTextInputClient());
+ verifier.Verify();
+ }
+
+ {
+ SCOPED_TRACE("Focus from 2nd TextInputClient to NULL");
+
+ ASSERT_EQ(&text_input_client_2nd, input_method.GetTextInputClient());
+ verifier.ExpectClientChange(&text_input_client_2nd, NULL);
+ input_method.SetFocusedTextInputClient(NULL);
+ EXPECT_EQ(NULL, input_method.GetTextInputClient());
+ verifier.Verify();
+ }
+
+ {
+ SCOPED_TRACE("Redundant focus events must be ignored");
+ verifier.ExpectClientDoesNotChange();
+ input_method.SetFocusedTextInputClient(NULL);
+ verifier.Verify();
+ }
+}
+
+TEST(InputMethodBaseTest, DetachTextInputClient) {
+ DummyTextInputClient text_input_client;
+ DummyTextInputClient text_input_client_the_other;
+
+ ClientChangeVerifier verifier;
+ MockInputMethodBase input_method(&verifier);
+ MockInputMethodObserver input_method_observer(&verifier);
+ InputMethodScopedObserver scoped_observer(&input_method_observer);
+ scoped_observer.Add(&input_method);
+
+ // Assume that the top-level-widget gains focus.
+ input_method.OnFocus();
+
+ // Initialize for the next test.
+ {
+ verifier.ExpectClientChange(NULL, &text_input_client);
+ input_method.SetFocusedTextInputClient(&text_input_client);
+ verifier.Verify();
+ }
+
+ {
+ SCOPED_TRACE("DetachTextInputClient must be ignored for other clients");
+ ASSERT_EQ(&text_input_client, input_method.GetTextInputClient());
+ verifier.ExpectClientDoesNotChange();
+ input_method.DetachTextInputClient(&text_input_client_the_other);
+ EXPECT_EQ(&text_input_client, input_method.GetTextInputClient());
+ verifier.Verify();
+ }
+
+ {
+ SCOPED_TRACE("DetachTextInputClient must succeed even after the "
+ "top-level loses the focus");
+
+ ASSERT_EQ(&text_input_client, input_method.GetTextInputClient());
+ input_method.OnBlur();
+ input_method.OnFocus();
+ verifier.ExpectClientChange(&text_input_client, NULL);
+ input_method.DetachTextInputClient(&text_input_client);
+ EXPECT_EQ(NULL, input_method.GetTextInputClient());
+ verifier.Verify();
+ }
+}
+
+TEST(InputMethodBaseTest, SetStickyFocusedTextInputClient) {
+ DummyTextInputClient sticky_client;
+ DummyTextInputClient non_sticky_client;
+
+ ClientChangeVerifier verifier;
+ MockInputMethodBase input_method(&verifier);
+ MockInputMethodObserver input_method_observer(&verifier);
+ InputMethodScopedObserver scoped_observer(&input_method_observer);
+ scoped_observer.Add(&input_method);
+
+ // Assume that the top-level-widget gains focus.
+ input_method.OnFocus();
+
+ {
+ SCOPED_TRACE("Focus from NULL to non-sticky client");
+
+ ASSERT_EQ(NULL, input_method.GetTextInputClient());
+ verifier.ExpectClientChange(NULL, &non_sticky_client);
+ input_method.SetFocusedTextInputClient(&non_sticky_client);
+ EXPECT_EQ(&non_sticky_client, input_method.GetTextInputClient());
+ verifier.Verify();
+ }
+
+ {
+ SCOPED_TRACE("Focus from non-sticky to sticky client");
+
+ ASSERT_EQ(&non_sticky_client, input_method.GetTextInputClient());
+ verifier.ExpectClientChange(&non_sticky_client, &sticky_client);
+ input_method.SetStickyFocusedTextInputClient(&sticky_client);
+ EXPECT_EQ(&sticky_client, input_method.GetTextInputClient());
+ verifier.Verify();
+ }
+
+ {
+ SCOPED_TRACE("Focus from sticky to non-sticky client -> must fail");
+
+ ASSERT_EQ(&sticky_client, input_method.GetTextInputClient());
+ verifier.ExpectClientDoesNotChange();
+ input_method.SetFocusedTextInputClient(&non_sticky_client);
+ EXPECT_EQ(&sticky_client, input_method.GetTextInputClient());
+ verifier.Verify();
+ }
+
+ {
+ SCOPED_TRACE("Focus from sticky to NULL -> must fail");
+
+ verifier.ExpectClientDoesNotChange();
+ input_method.SetFocusedTextInputClient(NULL);
+ EXPECT_EQ(&sticky_client, input_method.GetTextInputClient());
+ verifier.Verify();
+ }
+
+ {
+ SCOPED_TRACE("SetStickyFocusedTextInputClient(NULL) must be supported");
+
+ ASSERT_EQ(&sticky_client, input_method.GetTextInputClient());
+ verifier.ExpectClientChange(&sticky_client, NULL);
+ input_method.SetStickyFocusedTextInputClient(NULL);
+ EXPECT_EQ(NULL, input_method.GetTextInputClient());
+ verifier.Verify();
+
+ // |SetStickyFocusedTextInputClient(NULL)| must be equivalent to
+ // |SetFocusedTextInputClient(NULL)|. We should be able to use
+ // |SetFocusedTextInputClient(&non_sticky_client)| here.
+ verifier.ExpectClientChange(NULL, &non_sticky_client);
+ input_method.SetFocusedTextInputClient(&non_sticky_client);
+ EXPECT_EQ(&non_sticky_client, input_method.GetTextInputClient());
+ verifier.Verify();
+ }
+
+ {
+ SCOPED_TRACE("Set stick client again for the next test");
+ verifier.ExpectClientChange(&non_sticky_client, &sticky_client);
+ input_method.SetStickyFocusedTextInputClient(&sticky_client);
+ verifier.Verify();
+ }
+
+ {
+ SCOPED_TRACE("DetachTextInputClient must be supported for sticky client");
+
+ ASSERT_EQ(&sticky_client, input_method.GetTextInputClient());
+ verifier.ExpectClientChange(&sticky_client, NULL);
+ input_method.DetachTextInputClient(&sticky_client);
+ EXPECT_EQ(NULL, input_method.GetTextInputClient());
+ verifier.Verify();
+ }
+}
+
+} // namespace
+} // namespace ui