Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(109)

Side by Side Diff: ui/base/ime/input_method_base_unittest.cc

Issue 851853002: It is time. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Trying to reup because the last upload failed. Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/base/ime/input_method_base.cc ('k') | ui/base/ime/input_method_chromeos.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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.
4
5 #include "ui/base/ime/input_method_base.h"
6
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/base/ime/text_input_focus_manager.h"
16 #include "ui/base/ui_base_switches_util.h"
17 #include "ui/events/event.h"
18
19 namespace ui {
20 namespace {
21
22 class ClientChangeVerifier {
23 public:
24 ClientChangeVerifier()
25 : previous_client_(NULL),
26 next_client_(NULL),
27 call_expected_(false),
28 on_will_change_focused_client_called_(false),
29 on_did_change_focused_client_called_(false),
30 on_text_input_state_changed_(false) {
31 }
32
33 // Expects that focused text input client will not be changed.
34 void ExpectClientDoesNotChange() {
35 previous_client_ = NULL;
36 next_client_ = NULL;
37 call_expected_ = false;
38 on_will_change_focused_client_called_ = false;
39 on_did_change_focused_client_called_ = false;
40 on_text_input_state_changed_ = false;
41 }
42
43 // Expects that focused text input client will be changed from
44 // |previous_client| to |next_client|.
45 void ExpectClientChange(TextInputClient* previous_client,
46 TextInputClient* next_client) {
47 previous_client_ = previous_client;
48 next_client_ = next_client;
49 call_expected_ = true;
50 on_will_change_focused_client_called_ = false;
51 on_did_change_focused_client_called_ = false;
52 on_text_input_state_changed_ = false;
53 }
54
55 // Verifies the result satisfies the expectation or not.
56 void Verify() {
57 if (switches::IsTextInputFocusManagerEnabled()) {
58 EXPECT_FALSE(on_will_change_focused_client_called_);
59 EXPECT_FALSE(on_did_change_focused_client_called_);
60 EXPECT_FALSE(on_text_input_state_changed_);
61 } else {
62 EXPECT_EQ(call_expected_, on_will_change_focused_client_called_);
63 EXPECT_EQ(call_expected_, on_did_change_focused_client_called_);
64 EXPECT_EQ(call_expected_, on_text_input_state_changed_);
65 }
66 }
67
68 void OnWillChangeFocusedClient(TextInputClient* focused_before,
69 TextInputClient* focused) {
70 EXPECT_TRUE(call_expected_);
71
72 // Check arguments
73 EXPECT_EQ(previous_client_, focused_before);
74 EXPECT_EQ(next_client_, focused);
75
76 // Check call order
77 EXPECT_FALSE(on_will_change_focused_client_called_);
78 EXPECT_FALSE(on_did_change_focused_client_called_);
79 EXPECT_FALSE(on_text_input_state_changed_);
80
81 on_will_change_focused_client_called_ = true;
82 }
83
84 void OnDidChangeFocusedClient(TextInputClient* focused_before,
85 TextInputClient* focused) {
86 EXPECT_TRUE(call_expected_);
87
88 // Check arguments
89 EXPECT_EQ(previous_client_, focused_before);
90 EXPECT_EQ(next_client_, focused);
91
92 // Check call order
93 EXPECT_TRUE(on_will_change_focused_client_called_);
94 EXPECT_FALSE(on_did_change_focused_client_called_);
95 EXPECT_FALSE(on_text_input_state_changed_);
96
97 on_did_change_focused_client_called_ = true;
98 }
99
100 void OnTextInputStateChanged(const TextInputClient* client) {
101 EXPECT_TRUE(call_expected_);
102
103 // Check arguments
104 EXPECT_EQ(next_client_, client);
105
106 // Check call order
107 EXPECT_TRUE(on_will_change_focused_client_called_);
108 EXPECT_TRUE(on_did_change_focused_client_called_);
109 EXPECT_FALSE(on_text_input_state_changed_);
110
111 on_text_input_state_changed_ = true;
112 }
113
114 private:
115 TextInputClient* previous_client_;
116 TextInputClient* next_client_;
117 bool call_expected_;
118 bool on_will_change_focused_client_called_;
119 bool on_did_change_focused_client_called_;
120 bool on_text_input_state_changed_;
121
122 DISALLOW_COPY_AND_ASSIGN(ClientChangeVerifier);
123 };
124
125 class InputMethodBaseTest : public testing::Test {
126 protected:
127 InputMethodBaseTest() {
128 }
129 virtual ~InputMethodBaseTest() {
130 }
131
132 virtual void SetUp() {
133 message_loop_.reset(new base::MessageLoopForUI);
134 }
135
136 virtual void TearDown() {
137 message_loop_.reset();
138 }
139
140 private:
141 scoped_ptr<base::MessageLoop> message_loop_;
142 DISALLOW_COPY_AND_ASSIGN(InputMethodBaseTest);
143 };
144
145 class MockInputMethodBase : public InputMethodBase {
146 public:
147 // Note: this class does not take the ownership of |verifier|.
148 MockInputMethodBase(ClientChangeVerifier* verifier) : verifier_(verifier) {
149 }
150 ~MockInputMethodBase() override {}
151
152 private:
153 // Overriden from InputMethod.
154 bool OnUntranslatedIMEMessage(
155 const base::NativeEvent& event,
156 InputMethod::NativeEventResult* result) override {
157 return false;
158 }
159 bool DispatchKeyEvent(const ui::KeyEvent&) override { return false; }
160 void OnCaretBoundsChanged(const TextInputClient* client) override {}
161 void CancelComposition(const TextInputClient* client) override {}
162 void OnInputLocaleChanged() override {}
163 std::string GetInputLocale() override { return ""; }
164 bool IsActive() override { return false; }
165 bool IsCandidatePopupOpen() const override { return false; }
166 // Overriden from InputMethodBase.
167 void OnWillChangeFocusedClient(TextInputClient* focused_before,
168 TextInputClient* focused) override {
169 verifier_->OnWillChangeFocusedClient(focused_before, focused);
170 }
171
172 void OnDidChangeFocusedClient(TextInputClient* focused_before,
173 TextInputClient* focused) override {
174 verifier_->OnDidChangeFocusedClient(focused_before, focused);
175 }
176
177 ClientChangeVerifier* verifier_;
178
179 FRIEND_TEST_ALL_PREFIXES(InputMethodBaseTest, CandidateWindowEvents);
180 DISALLOW_COPY_AND_ASSIGN(MockInputMethodBase);
181 };
182
183 class MockInputMethodObserver : public InputMethodObserver {
184 public:
185 // Note: this class does not take the ownership of |verifier|.
186 explicit MockInputMethodObserver(ClientChangeVerifier* verifier)
187 : verifier_(verifier) {
188 }
189 ~MockInputMethodObserver() override {}
190
191 private:
192 void OnTextInputTypeChanged(const TextInputClient* client) override {}
193 void OnFocus() override {}
194 void OnBlur() override {}
195 void OnCaretBoundsChanged(const TextInputClient* client) override {}
196 void OnTextInputStateChanged(const TextInputClient* client) override {
197 verifier_->OnTextInputStateChanged(client);
198 }
199 void OnShowImeIfNeeded() override {}
200 void OnInputMethodDestroyed(const InputMethod* client) override {}
201
202 ClientChangeVerifier* verifier_;
203 DISALLOW_COPY_AND_ASSIGN(MockInputMethodObserver);
204 };
205
206 class MockTextInputClient : public DummyTextInputClient {
207 public:
208 MockTextInputClient()
209 : shown_event_count_(0), updated_event_count_(0), hidden_event_count_(0) {
210 }
211 ~MockTextInputClient() override {}
212
213 void OnCandidateWindowShown() override { ++shown_event_count_; }
214 void OnCandidateWindowUpdated() override { ++updated_event_count_; }
215 void OnCandidateWindowHidden() override { ++hidden_event_count_; }
216
217 int shown_event_count() const { return shown_event_count_; }
218 int updated_event_count() const { return updated_event_count_; }
219 int hidden_event_count() const { return hidden_event_count_; }
220
221 private:
222 int shown_event_count_;
223 int updated_event_count_;
224 int hidden_event_count_;
225 };
226
227 typedef ScopedObserver<InputMethod, InputMethodObserver>
228 InputMethodScopedObserver;
229
230 void SetFocusedTextInputClient(InputMethod* input_method,
231 TextInputClient* text_input_client) {
232 if (switches::IsTextInputFocusManagerEnabled()) {
233 TextInputFocusManager::GetInstance()->FocusTextInputClient(
234 text_input_client);
235 } else {
236 input_method->SetFocusedTextInputClient(text_input_client);
237 }
238 }
239
240 TEST_F(InputMethodBaseTest, SetFocusedTextInputClient) {
241 DummyTextInputClient text_input_client_1st;
242 DummyTextInputClient text_input_client_2nd;
243
244 ClientChangeVerifier verifier;
245 MockInputMethodBase input_method(&verifier);
246 MockInputMethodObserver input_method_observer(&verifier);
247 InputMethodScopedObserver scoped_observer(&input_method_observer);
248 scoped_observer.Add(&input_method);
249
250 // Assume that the top-level-widget gains focus.
251 input_method.OnFocus();
252
253 {
254 SCOPED_TRACE("Focus from NULL to 1st TextInputClient");
255
256 ASSERT_EQ(NULL, input_method.GetTextInputClient());
257 verifier.ExpectClientChange(NULL, &text_input_client_1st);
258 SetFocusedTextInputClient(&input_method, &text_input_client_1st);
259 EXPECT_EQ(&text_input_client_1st, input_method.GetTextInputClient());
260 verifier.Verify();
261 }
262
263 {
264 SCOPED_TRACE("Redundant focus events must be ignored");
265 verifier.ExpectClientDoesNotChange();
266 SetFocusedTextInputClient(&input_method, &text_input_client_1st);
267 verifier.Verify();
268 }
269
270 {
271 SCOPED_TRACE("Focus from 1st to 2nd TextInputClient");
272
273 ASSERT_EQ(&text_input_client_1st, input_method.GetTextInputClient());
274 verifier.ExpectClientChange(&text_input_client_1st,
275 &text_input_client_2nd);
276 SetFocusedTextInputClient(&input_method, &text_input_client_2nd);
277 EXPECT_EQ(&text_input_client_2nd, input_method.GetTextInputClient());
278 verifier.Verify();
279 }
280
281 {
282 SCOPED_TRACE("Focus from 2nd TextInputClient to NULL");
283
284 ASSERT_EQ(&text_input_client_2nd, input_method.GetTextInputClient());
285 verifier.ExpectClientChange(&text_input_client_2nd, NULL);
286 SetFocusedTextInputClient(&input_method, NULL);
287 EXPECT_EQ(NULL, input_method.GetTextInputClient());
288 verifier.Verify();
289 }
290
291 {
292 SCOPED_TRACE("Redundant focus events must be ignored");
293 verifier.ExpectClientDoesNotChange();
294 SetFocusedTextInputClient(&input_method, NULL);
295 verifier.Verify();
296 }
297 }
298
299 TEST_F(InputMethodBaseTest, DetachTextInputClient) {
300 // DetachTextInputClient is not supported when IsTextInputFocusManagerEnabled.
301 if (switches::IsTextInputFocusManagerEnabled())
302 return;
303
304 DummyTextInputClient text_input_client;
305 DummyTextInputClient text_input_client_the_other;
306
307 ClientChangeVerifier verifier;
308 MockInputMethodBase input_method(&verifier);
309 MockInputMethodObserver input_method_observer(&verifier);
310 InputMethodScopedObserver scoped_observer(&input_method_observer);
311 scoped_observer.Add(&input_method);
312
313 // Assume that the top-level-widget gains focus.
314 input_method.OnFocus();
315
316 // Initialize for the next test.
317 {
318 verifier.ExpectClientChange(NULL, &text_input_client);
319 input_method.SetFocusedTextInputClient(&text_input_client);
320 verifier.Verify();
321 }
322
323 {
324 SCOPED_TRACE("DetachTextInputClient must be ignored for other clients");
325 ASSERT_EQ(&text_input_client, input_method.GetTextInputClient());
326 verifier.ExpectClientDoesNotChange();
327 input_method.DetachTextInputClient(&text_input_client_the_other);
328 EXPECT_EQ(&text_input_client, input_method.GetTextInputClient());
329 verifier.Verify();
330 }
331
332 {
333 SCOPED_TRACE("DetachTextInputClient must succeed even after the "
334 "top-level loses the focus");
335
336 ASSERT_EQ(&text_input_client, input_method.GetTextInputClient());
337 input_method.OnBlur();
338 input_method.OnFocus();
339 verifier.ExpectClientChange(&text_input_client, NULL);
340 input_method.DetachTextInputClient(&text_input_client);
341 EXPECT_EQ(NULL, input_method.GetTextInputClient());
342 verifier.Verify();
343 }
344 }
345
346 TEST_F(InputMethodBaseTest, CandidateWindowEvents) {
347 MockTextInputClient text_input_client;
348
349 {
350 ClientChangeVerifier verifier;
351 MockInputMethodBase input_method_base(&verifier);
352 input_method_base.OnFocus();
353
354 verifier.ExpectClientChange(NULL, &text_input_client);
355 SetFocusedTextInputClient(&input_method_base, &text_input_client);
356
357 EXPECT_EQ(0, text_input_client.shown_event_count());
358 EXPECT_EQ(0, text_input_client.updated_event_count());
359 EXPECT_EQ(0, text_input_client.hidden_event_count());
360
361 input_method_base.OnCandidateWindowShown();
362 base::RunLoop().RunUntilIdle();
363
364 EXPECT_EQ(1, text_input_client.shown_event_count());
365 EXPECT_EQ(0, text_input_client.updated_event_count());
366 EXPECT_EQ(0, text_input_client.hidden_event_count());
367
368 input_method_base.OnCandidateWindowUpdated();
369 base::RunLoop().RunUntilIdle();
370
371 EXPECT_EQ(1, text_input_client.shown_event_count());
372 EXPECT_EQ(1, text_input_client.updated_event_count());
373 EXPECT_EQ(0, text_input_client.hidden_event_count());
374
375 input_method_base.OnCandidateWindowHidden();
376 base::RunLoop().RunUntilIdle();
377
378 EXPECT_EQ(1, text_input_client.shown_event_count());
379 EXPECT_EQ(1, text_input_client.updated_event_count());
380 EXPECT_EQ(1, text_input_client.hidden_event_count());
381
382 input_method_base.OnCandidateWindowShown();
383 }
384
385 // If InputMethod is deleted immediately after an event happens, but before
386 // its callback is invoked, the callback will be cancelled.
387 base::RunLoop().RunUntilIdle();
388 EXPECT_EQ(1, text_input_client.shown_event_count());
389 EXPECT_EQ(1, text_input_client.updated_event_count());
390 EXPECT_EQ(1, text_input_client.hidden_event_count());
391 }
392
393 } // namespace
394 } // namespace ui
OLDNEW
« no previous file with comments | « ui/base/ime/input_method_base.cc ('k') | ui/base/ime/input_method_chromeos.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698