Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / ui / base / ime / input_method_base_unittest.cc
blobf8c45bc2dc31b03b7d7f90c0ae9895c7aca20070
1 // Copyright 2013 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.
5 #include "ui/base/ime/input_method_base.h"
7 #include "base/gtest_prod_util.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/run_loop.h"
11 #include "base/scoped_observer.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "ui/base/ime/dummy_text_input_client.h"
14 #include "ui/base/ime/input_method_observer.h"
15 #include "ui/events/event.h"
17 namespace ui {
18 namespace {
20 class ClientChangeVerifier {
21 public:
22 ClientChangeVerifier()
23 : previous_client_(NULL),
24 next_client_(NULL),
25 call_expected_(false),
26 on_will_change_focused_client_called_(false),
27 on_did_change_focused_client_called_(false),
28 on_text_input_state_changed_(false) {
31 // Expects that focused text input client will not be changed.
32 void ExpectClientDoesNotChange() {
33 previous_client_ = NULL;
34 next_client_ = NULL;
35 call_expected_ = false;
36 on_will_change_focused_client_called_ = false;
37 on_did_change_focused_client_called_ = false;
38 on_text_input_state_changed_ = false;
41 // Expects that focused text input client will be changed from
42 // |previous_client| to |next_client|.
43 void ExpectClientChange(TextInputClient* previous_client,
44 TextInputClient* next_client) {
45 previous_client_ = previous_client;
46 next_client_ = next_client;
47 call_expected_ = true;
48 on_will_change_focused_client_called_ = false;
49 on_did_change_focused_client_called_ = false;
50 on_text_input_state_changed_ = false;
53 // Verifies the result satisfies the expectation or not.
54 void Verify() {
55 EXPECT_EQ(call_expected_, on_will_change_focused_client_called_);
56 EXPECT_EQ(call_expected_, on_did_change_focused_client_called_);
57 EXPECT_EQ(call_expected_, on_text_input_state_changed_);
60 void OnWillChangeFocusedClient(TextInputClient* focused_before,
61 TextInputClient* focused) {
62 EXPECT_TRUE(call_expected_);
64 // Check arguments
65 EXPECT_EQ(previous_client_, focused_before);
66 EXPECT_EQ(next_client_, focused);
68 // Check call order
69 EXPECT_FALSE(on_will_change_focused_client_called_);
70 EXPECT_FALSE(on_did_change_focused_client_called_);
71 EXPECT_FALSE(on_text_input_state_changed_);
73 on_will_change_focused_client_called_ = true;
76 void OnDidChangeFocusedClient(TextInputClient* focused_before,
77 TextInputClient* focused) {
78 EXPECT_TRUE(call_expected_);
80 // Check arguments
81 EXPECT_EQ(previous_client_, focused_before);
82 EXPECT_EQ(next_client_, focused);
84 // Check call order
85 EXPECT_TRUE(on_will_change_focused_client_called_);
86 EXPECT_FALSE(on_did_change_focused_client_called_);
87 EXPECT_FALSE(on_text_input_state_changed_);
89 on_did_change_focused_client_called_ = true;
92 void OnTextInputStateChanged(const TextInputClient* client) {
93 EXPECT_TRUE(call_expected_);
95 // Check arguments
96 EXPECT_EQ(next_client_, client);
98 // Check call order
99 EXPECT_TRUE(on_will_change_focused_client_called_);
100 EXPECT_TRUE(on_did_change_focused_client_called_);
101 EXPECT_FALSE(on_text_input_state_changed_);
103 on_text_input_state_changed_ = true;
106 private:
107 TextInputClient* previous_client_;
108 TextInputClient* next_client_;
109 bool call_expected_;
110 bool on_will_change_focused_client_called_;
111 bool on_did_change_focused_client_called_;
112 bool on_text_input_state_changed_;
114 DISALLOW_COPY_AND_ASSIGN(ClientChangeVerifier);
117 class InputMethodBaseTest : public testing::Test {
118 protected:
119 InputMethodBaseTest() {
121 ~InputMethodBaseTest() override {}
123 void SetUp() override { message_loop_.reset(new base::MessageLoopForUI); }
125 void TearDown() override { message_loop_.reset(); }
127 private:
128 scoped_ptr<base::MessageLoop> message_loop_;
129 DISALLOW_COPY_AND_ASSIGN(InputMethodBaseTest);
132 class MockInputMethodBase : public InputMethodBase {
133 public:
134 // Note: this class does not take the ownership of |verifier|.
135 MockInputMethodBase(ClientChangeVerifier* verifier) : verifier_(verifier) {
137 ~MockInputMethodBase() override {}
139 private:
140 // Overriden from InputMethod.
141 bool OnUntranslatedIMEMessage(
142 const base::NativeEvent& event,
143 InputMethod::NativeEventResult* result) override {
144 return false;
146 bool DispatchKeyEvent(const ui::KeyEvent&) override { return false; }
147 void OnCaretBoundsChanged(const TextInputClient* client) override {}
148 void CancelComposition(const TextInputClient* client) override {}
149 void OnInputLocaleChanged() override {}
150 std::string GetInputLocale() override { return ""; }
151 bool IsCandidatePopupOpen() const override { return false; }
152 // Overriden from InputMethodBase.
153 void OnWillChangeFocusedClient(TextInputClient* focused_before,
154 TextInputClient* focused) override {
155 verifier_->OnWillChangeFocusedClient(focused_before, focused);
158 void OnDidChangeFocusedClient(TextInputClient* focused_before,
159 TextInputClient* focused) override {
160 verifier_->OnDidChangeFocusedClient(focused_before, focused);
163 ClientChangeVerifier* verifier_;
165 FRIEND_TEST_ALL_PREFIXES(InputMethodBaseTest, CandidateWindowEvents);
166 DISALLOW_COPY_AND_ASSIGN(MockInputMethodBase);
169 class MockInputMethodObserver : public InputMethodObserver {
170 public:
171 // Note: this class does not take the ownership of |verifier|.
172 explicit MockInputMethodObserver(ClientChangeVerifier* verifier)
173 : verifier_(verifier) {
175 ~MockInputMethodObserver() override {}
177 private:
178 void OnTextInputTypeChanged(const TextInputClient* client) override {}
179 void OnFocus() override {}
180 void OnBlur() override {}
181 void OnCaretBoundsChanged(const TextInputClient* client) override {}
182 void OnTextInputStateChanged(const TextInputClient* client) override {
183 verifier_->OnTextInputStateChanged(client);
185 void OnShowImeIfNeeded() override {}
186 void OnInputMethodDestroyed(const InputMethod* client) override {}
188 ClientChangeVerifier* verifier_;
189 DISALLOW_COPY_AND_ASSIGN(MockInputMethodObserver);
192 typedef ScopedObserver<InputMethod, InputMethodObserver>
193 InputMethodScopedObserver;
195 void SetFocusedTextInputClient(InputMethod* input_method,
196 TextInputClient* text_input_client) {
197 input_method->SetFocusedTextInputClient(text_input_client);
200 TEST_F(InputMethodBaseTest, SetFocusedTextInputClient) {
201 DummyTextInputClient text_input_client_1st;
202 DummyTextInputClient text_input_client_2nd;
204 ClientChangeVerifier verifier;
205 MockInputMethodBase input_method(&verifier);
206 MockInputMethodObserver input_method_observer(&verifier);
207 InputMethodScopedObserver scoped_observer(&input_method_observer);
208 scoped_observer.Add(&input_method);
210 // Assume that the top-level-widget gains focus.
211 input_method.OnFocus();
214 SCOPED_TRACE("Focus from NULL to 1st TextInputClient");
216 ASSERT_EQ(NULL, input_method.GetTextInputClient());
217 verifier.ExpectClientChange(NULL, &text_input_client_1st);
218 SetFocusedTextInputClient(&input_method, &text_input_client_1st);
219 EXPECT_EQ(&text_input_client_1st, input_method.GetTextInputClient());
220 verifier.Verify();
224 SCOPED_TRACE("Redundant focus events must be ignored");
225 verifier.ExpectClientDoesNotChange();
226 SetFocusedTextInputClient(&input_method, &text_input_client_1st);
227 verifier.Verify();
231 SCOPED_TRACE("Focus from 1st to 2nd TextInputClient");
233 ASSERT_EQ(&text_input_client_1st, input_method.GetTextInputClient());
234 verifier.ExpectClientChange(&text_input_client_1st,
235 &text_input_client_2nd);
236 SetFocusedTextInputClient(&input_method, &text_input_client_2nd);
237 EXPECT_EQ(&text_input_client_2nd, input_method.GetTextInputClient());
238 verifier.Verify();
242 SCOPED_TRACE("Focus from 2nd TextInputClient to NULL");
244 ASSERT_EQ(&text_input_client_2nd, input_method.GetTextInputClient());
245 verifier.ExpectClientChange(&text_input_client_2nd, NULL);
246 SetFocusedTextInputClient(&input_method, NULL);
247 EXPECT_EQ(NULL, input_method.GetTextInputClient());
248 verifier.Verify();
252 SCOPED_TRACE("Redundant focus events must be ignored");
253 verifier.ExpectClientDoesNotChange();
254 SetFocusedTextInputClient(&input_method, NULL);
255 verifier.Verify();
259 TEST_F(InputMethodBaseTest, DetachTextInputClient) {
260 DummyTextInputClient text_input_client;
261 DummyTextInputClient text_input_client_the_other;
263 ClientChangeVerifier verifier;
264 MockInputMethodBase input_method(&verifier);
265 MockInputMethodObserver input_method_observer(&verifier);
266 InputMethodScopedObserver scoped_observer(&input_method_observer);
267 scoped_observer.Add(&input_method);
269 // Assume that the top-level-widget gains focus.
270 input_method.OnFocus();
272 // Initialize for the next test.
274 verifier.ExpectClientChange(NULL, &text_input_client);
275 input_method.SetFocusedTextInputClient(&text_input_client);
276 verifier.Verify();
280 SCOPED_TRACE("DetachTextInputClient must be ignored for other clients");
281 ASSERT_EQ(&text_input_client, input_method.GetTextInputClient());
282 verifier.ExpectClientDoesNotChange();
283 input_method.DetachTextInputClient(&text_input_client_the_other);
284 EXPECT_EQ(&text_input_client, input_method.GetTextInputClient());
285 verifier.Verify();
289 SCOPED_TRACE("DetachTextInputClient must succeed even after the "
290 "top-level loses the focus");
292 ASSERT_EQ(&text_input_client, input_method.GetTextInputClient());
293 input_method.OnBlur();
294 input_method.OnFocus();
295 verifier.ExpectClientChange(&text_input_client, NULL);
296 input_method.DetachTextInputClient(&text_input_client);
297 EXPECT_EQ(NULL, input_method.GetTextInputClient());
298 verifier.Verify();
302 } // namespace
303 } // namespace ui