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

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

Issue 1586843002: Remove remote tree host and some related input and metro_driver code (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@metro-mode-3
Patch Set: remove ash_unittests from being run Created 4 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/remote_input_method_win.cc ('k') | ui/base/ime/ui_base_ime.gyp » ('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/remote_input_method_win.h"
6
7 #include <InputScope.h>
8 #include <stddef.h>
9 #include <stdint.h>
10
11 #include <vector>
12
13 #include "base/macros.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/scoped_observer.h"
16 #include "base/strings/string16.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "ui/base/ime/composition_text.h"
19 #include "ui/base/ime/dummy_text_input_client.h"
20 #include "ui/base/ime/input_method.h"
21 #include "ui/base/ime/input_method_delegate.h"
22 #include "ui/base/ime/input_method_observer.h"
23 #include "ui/base/ime/remote_input_method_delegate_win.h"
24 #include "ui/events/event.h"
25
26 namespace ui {
27 namespace {
28
29 class MockTextInputClient : public DummyTextInputClient {
30 public:
31 MockTextInputClient()
32 : text_input_type_(TEXT_INPUT_TYPE_NONE),
33 text_input_mode_(TEXT_INPUT_MODE_DEFAULT),
34 call_count_set_composition_text_(0),
35 call_count_insert_char_(0),
36 call_count_insert_text_(0),
37 emulate_pepper_flash_(false) {
38 }
39
40 size_t call_count_set_composition_text() const {
41 return call_count_set_composition_text_;
42 }
43 const base::string16& inserted_text() const {
44 return inserted_text_;
45 }
46 size_t call_count_insert_char() const {
47 return call_count_insert_char_;
48 }
49 size_t call_count_insert_text() const {
50 return call_count_insert_text_;
51 }
52 void Reset() {
53 text_input_type_ = TEXT_INPUT_TYPE_NONE;
54 text_input_mode_ = TEXT_INPUT_MODE_DEFAULT;
55 call_count_set_composition_text_ = 0;
56 inserted_text_.clear();
57 call_count_insert_char_ = 0;
58 call_count_insert_text_ = 0;
59 caret_bounds_ = gfx::Rect();
60 composition_character_bounds_.clear();
61 emulate_pepper_flash_ = false;
62 }
63 void set_text_input_type(ui::TextInputType type) {
64 text_input_type_ = type;
65 }
66 void set_text_input_mode(ui::TextInputMode mode) {
67 text_input_mode_ = mode;
68 }
69 void set_caret_bounds(const gfx::Rect& caret_bounds) {
70 caret_bounds_ = caret_bounds;
71 }
72 void set_composition_character_bounds(
73 const std::vector<gfx::Rect>& composition_character_bounds) {
74 composition_character_bounds_ = composition_character_bounds;
75 }
76 void set_emulate_pepper_flash(bool enabled) {
77 emulate_pepper_flash_ = enabled;
78 }
79
80 private:
81 // Overriden from DummyTextInputClient.
82 void SetCompositionText(const ui::CompositionText& composition) override {
83 ++call_count_set_composition_text_;
84 }
85 void InsertChar(const ui::KeyEvent& event) override {
86 inserted_text_.append(1, event.GetCharacter());
87 ++call_count_insert_char_;
88 }
89 void InsertText(const base::string16& text) override {
90 inserted_text_.append(text);
91 ++call_count_insert_text_;
92 }
93 ui::TextInputType GetTextInputType() const override {
94 return text_input_type_;
95 }
96 ui::TextInputMode GetTextInputMode() const override {
97 return text_input_mode_;
98 }
99 gfx::Rect GetCaretBounds() const override { return caret_bounds_; }
100 bool GetCompositionCharacterBounds(uint32_t index,
101 gfx::Rect* rect) const override {
102 // Emulate the situation of crbug.com/328237.
103 if (emulate_pepper_flash_)
104 return false;
105 if (!rect || composition_character_bounds_.size() <= index)
106 return false;
107 *rect = composition_character_bounds_[index];
108 return true;
109 }
110 bool HasCompositionText() const override {
111 return !composition_character_bounds_.empty();
112 }
113 bool GetCompositionTextRange(gfx::Range* range) const override {
114 if (composition_character_bounds_.empty())
115 return false;
116 *range = gfx::Range(0, composition_character_bounds_.size());
117 return true;
118 }
119
120 ui::TextInputType text_input_type_;
121 ui::TextInputMode text_input_mode_;
122 gfx::Rect caret_bounds_;
123 std::vector<gfx::Rect> composition_character_bounds_;
124 base::string16 inserted_text_;
125 size_t call_count_set_composition_text_;
126 size_t call_count_insert_char_;
127 size_t call_count_insert_text_;
128 bool emulate_pepper_flash_;
129 DISALLOW_COPY_AND_ASSIGN(MockTextInputClient);
130 };
131
132 class MockInputMethodDelegate : public internal::InputMethodDelegate {
133 public:
134 MockInputMethodDelegate() {}
135
136 const std::vector<ui::KeyboardCode>& fabricated_key_events() const {
137 return fabricated_key_events_;
138 }
139 void Reset() {
140 fabricated_key_events_.clear();
141 }
142
143 private:
144 ui::EventDispatchDetails DispatchKeyEventPostIME(
145 ui::KeyEvent* event) override {
146 EXPECT_FALSE(event->HasNativeEvent());
147 fabricated_key_events_.push_back(event->key_code());
148 event->SetHandled();
149 return ui::EventDispatchDetails();
150 }
151
152 std::vector<ui::KeyboardCode> fabricated_key_events_;
153 DISALLOW_COPY_AND_ASSIGN(MockInputMethodDelegate);
154 };
155
156 class MockRemoteInputMethodDelegateWin
157 : public internal::RemoteInputMethodDelegateWin {
158 public:
159 MockRemoteInputMethodDelegateWin()
160 : cancel_composition_called_(false),
161 text_input_client_updated_called_(false) {
162 }
163
164 bool cancel_composition_called() const {
165 return cancel_composition_called_;
166 }
167 bool text_input_client_updated_called() const {
168 return text_input_client_updated_called_;
169 }
170 const std::vector<int32_t>& input_scopes() const { return input_scopes_; }
171 const std::vector<gfx::Rect>& composition_character_bounds() const {
172 return composition_character_bounds_;
173 }
174 void Reset() {
175 cancel_composition_called_ = false;
176 text_input_client_updated_called_ = false;
177 input_scopes_.clear();
178 composition_character_bounds_.clear();
179 }
180
181 private:
182 void CancelComposition() override { cancel_composition_called_ = true; }
183
184 void OnTextInputClientUpdated(
185 const std::vector<int32_t>& input_scopes,
186 const std::vector<gfx::Rect>& composition_character_bounds) override {
187 text_input_client_updated_called_ = true;
188 input_scopes_ = input_scopes;
189 composition_character_bounds_ = composition_character_bounds;
190 }
191
192 bool cancel_composition_called_;
193 bool text_input_client_updated_called_;
194 std::vector<int32_t> input_scopes_;
195 std::vector<gfx::Rect> composition_character_bounds_;
196 DISALLOW_COPY_AND_ASSIGN(MockRemoteInputMethodDelegateWin);
197 };
198
199 class MockInputMethodObserver : public InputMethodObserver {
200 public:
201 MockInputMethodObserver()
202 : on_text_input_state_changed_(0),
203 on_input_method_destroyed_changed_(0) {
204 }
205 ~MockInputMethodObserver() override {}
206 void Reset() {
207 on_text_input_state_changed_ = 0;
208 on_input_method_destroyed_changed_ = 0;
209 }
210 size_t on_text_input_state_changed() const {
211 return on_text_input_state_changed_;
212 }
213 size_t on_input_method_destroyed_changed() const {
214 return on_input_method_destroyed_changed_;
215 }
216
217 private:
218 // Overriden from InputMethodObserver.
219 void OnTextInputTypeChanged(const TextInputClient* client) override {}
220 void OnFocus() override {}
221 void OnBlur() override {}
222 void OnCaretBoundsChanged(const TextInputClient* client) override {}
223 void OnTextInputStateChanged(const TextInputClient* client) override {
224 ++on_text_input_state_changed_;
225 }
226 void OnInputMethodDestroyed(const InputMethod* client) override {
227 ++on_input_method_destroyed_changed_;
228 }
229 void OnShowImeIfNeeded() override {}
230
231 size_t on_text_input_state_changed_;
232 size_t on_input_method_destroyed_changed_;
233 DISALLOW_COPY_AND_ASSIGN(MockInputMethodObserver);
234 };
235
236 typedef ScopedObserver<InputMethod, InputMethodObserver>
237 InputMethodScopedObserver;
238
239 TEST(RemoteInputMethodWinTest, RemoteInputMethodPrivateWin) {
240 InputMethod* other_ptr = static_cast<InputMethod*>(NULL) + 1;
241
242 // Use typed NULL to make EXPECT_NE happy until nullptr becomes available.
243 RemoteInputMethodPrivateWin* kNull =
244 static_cast<RemoteInputMethodPrivateWin*>(NULL);
245 EXPECT_EQ(kNull, RemoteInputMethodPrivateWin::Get(other_ptr));
246
247 MockInputMethodDelegate delegate_;
248 scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));
249 EXPECT_NE(kNull, RemoteInputMethodPrivateWin::Get(input_method.get()));
250
251 InputMethod* dangling_ptr = input_method.get();
252 input_method.reset(NULL);
253 EXPECT_EQ(kNull, RemoteInputMethodPrivateWin::Get(dangling_ptr));
254 }
255
256 TEST(RemoteInputMethodWinTest, OnInputSourceChanged) {
257 MockInputMethodDelegate delegate_;
258 scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));
259 RemoteInputMethodPrivateWin* private_ptr =
260 RemoteInputMethodPrivateWin::Get(input_method.get());
261 ASSERT_TRUE(private_ptr != NULL);
262
263 private_ptr->OnInputSourceChanged(
264 MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN), true);
265 EXPECT_EQ("ja-JP", input_method->GetInputLocale());
266
267 private_ptr->OnInputSourceChanged(
268 MAKELANGID(LANG_ARABIC, SUBLANG_ARABIC_QATAR), true);
269 EXPECT_EQ("ar-QA", input_method->GetInputLocale());
270 }
271
272 TEST(RemoteInputMethodWinTest, OnCandidatePopupChanged) {
273 MockInputMethodDelegate delegate_;
274 scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));
275 RemoteInputMethodPrivateWin* private_ptr =
276 RemoteInputMethodPrivateWin::Get(input_method.get());
277 ASSERT_TRUE(private_ptr != NULL);
278
279 // Initial value
280 EXPECT_FALSE(input_method->IsCandidatePopupOpen());
281
282 // RemoteInputMethodWin::OnCandidatePopupChanged can be called even when the
283 // focused text input client is NULL.
284 ASSERT_TRUE(input_method->GetTextInputClient() == NULL);
285 private_ptr->OnCandidatePopupChanged(false);
286 private_ptr->OnCandidatePopupChanged(true);
287
288 MockTextInputClient mock_text_input_client;
289 input_method->SetFocusedTextInputClient(&mock_text_input_client);
290
291 mock_text_input_client.Reset();
292
293 private_ptr->OnCandidatePopupChanged(true);
294 EXPECT_TRUE(input_method->IsCandidatePopupOpen());
295
296 private_ptr->OnCandidatePopupChanged(false);
297 EXPECT_FALSE(input_method->IsCandidatePopupOpen());
298 }
299
300 TEST(RemoteInputMethodWinTest, CancelComposition) {
301 MockInputMethodDelegate delegate_;
302 MockTextInputClient mock_text_input_client;
303 scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));
304
305 // This must not cause a crash.
306 input_method->CancelComposition(&mock_text_input_client);
307
308 RemoteInputMethodPrivateWin* private_ptr =
309 RemoteInputMethodPrivateWin::Get(input_method.get());
310 ASSERT_TRUE(private_ptr != NULL);
311 MockRemoteInputMethodDelegateWin mock_remote_delegate;
312 private_ptr->SetRemoteDelegate(&mock_remote_delegate);
313
314 input_method->CancelComposition(&mock_text_input_client);
315 EXPECT_FALSE(mock_remote_delegate.cancel_composition_called());
316
317 input_method->SetFocusedTextInputClient(&mock_text_input_client);
318 input_method->CancelComposition(&mock_text_input_client);
319 EXPECT_TRUE(mock_remote_delegate.cancel_composition_called());
320 }
321
322 TEST(RemoteInputMethodWinTest, SetFocusedTextInputClient) {
323 MockInputMethodDelegate delegate_;
324 MockTextInputClient mock_text_input_client;
325 scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));
326
327 mock_text_input_client.set_caret_bounds(gfx::Rect(10, 0, 10, 20));
328 mock_text_input_client.set_text_input_type(ui::TEXT_INPUT_TYPE_URL);
329 input_method->SetFocusedTextInputClient(&mock_text_input_client);
330
331 RemoteInputMethodPrivateWin* private_ptr =
332 RemoteInputMethodPrivateWin::Get(input_method.get());
333 ASSERT_TRUE(private_ptr != NULL);
334 MockRemoteInputMethodDelegateWin mock_remote_delegate;
335 private_ptr->SetRemoteDelegate(&mock_remote_delegate);
336
337 // Initial state must be synced.
338 EXPECT_TRUE(mock_remote_delegate.text_input_client_updated_called());
339 ASSERT_EQ(1u, mock_remote_delegate.composition_character_bounds().size());
340 EXPECT_EQ(gfx::Rect(10, 0, 10, 20),
341 mock_remote_delegate.composition_character_bounds()[0]);
342 ASSERT_EQ(1u, mock_remote_delegate.input_scopes().size());
343 EXPECT_EQ(IS_URL, mock_remote_delegate.input_scopes()[0]);
344
345 // State must be cleared by SetFocusedTextInputClient(NULL).
346 mock_remote_delegate.Reset();
347 input_method->SetFocusedTextInputClient(NULL);
348 EXPECT_TRUE(mock_remote_delegate.text_input_client_updated_called());
349 EXPECT_TRUE(mock_remote_delegate.composition_character_bounds().empty());
350 EXPECT_TRUE(mock_remote_delegate.input_scopes().empty());
351 }
352
353 TEST(RemoteInputMethodWinTest, DetachTextInputClient) {
354 MockInputMethodDelegate delegate_;
355 MockTextInputClient mock_text_input_client;
356 scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));
357
358 mock_text_input_client.set_caret_bounds(gfx::Rect(10, 0, 10, 20));
359 mock_text_input_client.set_text_input_type(ui::TEXT_INPUT_TYPE_URL);
360 input_method->SetFocusedTextInputClient(&mock_text_input_client);
361
362 RemoteInputMethodPrivateWin* private_ptr =
363 RemoteInputMethodPrivateWin::Get(input_method.get());
364 ASSERT_TRUE(private_ptr != NULL);
365 MockRemoteInputMethodDelegateWin mock_remote_delegate;
366 private_ptr->SetRemoteDelegate(&mock_remote_delegate);
367
368 // Initial state must be synced.
369 EXPECT_TRUE(mock_remote_delegate.text_input_client_updated_called());
370 ASSERT_EQ(1u, mock_remote_delegate.composition_character_bounds().size());
371 EXPECT_EQ(gfx::Rect(10, 0, 10, 20),
372 mock_remote_delegate.composition_character_bounds()[0]);
373 ASSERT_EQ(1u, mock_remote_delegate.input_scopes().size());
374 EXPECT_EQ(IS_URL, mock_remote_delegate.input_scopes()[0]);
375
376 // State must be cleared by DetachTextInputClient
377 mock_remote_delegate.Reset();
378 input_method->DetachTextInputClient(&mock_text_input_client);
379 EXPECT_TRUE(mock_remote_delegate.text_input_client_updated_called());
380 EXPECT_TRUE(mock_remote_delegate.composition_character_bounds().empty());
381 EXPECT_TRUE(mock_remote_delegate.input_scopes().empty());
382 }
383
384 TEST(RemoteInputMethodWinTest, OnCaretBoundsChanged) {
385 MockInputMethodDelegate delegate_;
386 MockTextInputClient mock_text_input_client;
387 scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));
388
389 // This must not cause a crash.
390 input_method->OnCaretBoundsChanged(&mock_text_input_client);
391
392 mock_text_input_client.set_caret_bounds(gfx::Rect(10, 0, 10, 20));
393 input_method->SetFocusedTextInputClient(&mock_text_input_client);
394
395 RemoteInputMethodPrivateWin* private_ptr =
396 RemoteInputMethodPrivateWin::Get(input_method.get());
397 ASSERT_TRUE(private_ptr != NULL);
398 MockRemoteInputMethodDelegateWin mock_remote_delegate;
399 private_ptr->SetRemoteDelegate(&mock_remote_delegate);
400
401 // Initial state must be synced.
402 EXPECT_TRUE(mock_remote_delegate.text_input_client_updated_called());
403 ASSERT_EQ(1u, mock_remote_delegate.composition_character_bounds().size());
404 EXPECT_EQ(gfx::Rect(10, 0, 10, 20),
405 mock_remote_delegate.composition_character_bounds()[0]);
406
407 // Redundant OnCaretBoundsChanged must be ignored.
408 mock_remote_delegate.Reset();
409 input_method->OnCaretBoundsChanged(&mock_text_input_client);
410 EXPECT_FALSE(mock_remote_delegate.text_input_client_updated_called());
411
412 // Check OnCaretBoundsChanged is handled. (w/o composition)
413 mock_remote_delegate.Reset();
414 mock_text_input_client.Reset();
415 mock_text_input_client.set_caret_bounds(gfx::Rect(10, 20, 30, 40));
416 input_method->OnCaretBoundsChanged(&mock_text_input_client);
417 EXPECT_TRUE(mock_remote_delegate.text_input_client_updated_called());
418 ASSERT_EQ(1u, mock_remote_delegate.composition_character_bounds().size());
419 EXPECT_EQ(gfx::Rect(10, 20, 30, 40),
420 mock_remote_delegate.composition_character_bounds()[0]);
421
422 // Check OnCaretBoundsChanged is handled. (w/ composition)
423 {
424 mock_remote_delegate.Reset();
425 mock_text_input_client.Reset();
426
427 std::vector<gfx::Rect> bounds;
428 bounds.push_back(gfx::Rect(10, 20, 30, 40));
429 bounds.push_back(gfx::Rect(40, 30, 20, 10));
430 mock_text_input_client.set_composition_character_bounds(bounds);
431 input_method->OnCaretBoundsChanged(&mock_text_input_client);
432 EXPECT_TRUE(mock_remote_delegate.text_input_client_updated_called());
433 EXPECT_EQ(bounds, mock_remote_delegate.composition_character_bounds());
434 }
435 }
436
437 // Test case against crbug.com/328237.
438 TEST(RemoteInputMethodWinTest, OnCaretBoundsChangedForPepperFlash) {
439 MockInputMethodDelegate delegate_;
440 MockTextInputClient mock_text_input_client;
441 scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));
442 input_method->SetFocusedTextInputClient(&mock_text_input_client);
443
444 RemoteInputMethodPrivateWin* private_ptr =
445 RemoteInputMethodPrivateWin::Get(input_method.get());
446 ASSERT_TRUE(private_ptr != NULL);
447 MockRemoteInputMethodDelegateWin mock_remote_delegate;
448 private_ptr->SetRemoteDelegate(&mock_remote_delegate);
449
450 mock_remote_delegate.Reset();
451 mock_text_input_client.Reset();
452 mock_text_input_client.set_emulate_pepper_flash(true);
453
454 std::vector<gfx::Rect> caret_bounds;
455 caret_bounds.push_back(gfx::Rect(5, 15, 25, 35));
456 mock_text_input_client.set_caret_bounds(caret_bounds[0]);
457
458 std::vector<gfx::Rect> composition_bounds;
459 composition_bounds.push_back(gfx::Rect(10, 20, 30, 40));
460 composition_bounds.push_back(gfx::Rect(40, 30, 20, 10));
461 mock_text_input_client.set_composition_character_bounds(composition_bounds);
462 input_method->OnCaretBoundsChanged(&mock_text_input_client);
463 EXPECT_TRUE(mock_remote_delegate.text_input_client_updated_called());
464 // The caret bounds must be used when
465 // TextInputClient::GetCompositionCharacterBounds failed.
466 EXPECT_EQ(caret_bounds, mock_remote_delegate.composition_character_bounds());
467 }
468
469 TEST(RemoteInputMethodWinTest, OnTextInputTypeChanged) {
470 MockInputMethodDelegate delegate_;
471 MockTextInputClient mock_text_input_client;
472 scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));
473
474 // This must not cause a crash.
475 input_method->OnCaretBoundsChanged(&mock_text_input_client);
476
477 mock_text_input_client.set_text_input_type(ui::TEXT_INPUT_TYPE_URL);
478 input_method->SetFocusedTextInputClient(&mock_text_input_client);
479
480 RemoteInputMethodPrivateWin* private_ptr =
481 RemoteInputMethodPrivateWin::Get(input_method.get());
482 ASSERT_TRUE(private_ptr != NULL);
483 MockRemoteInputMethodDelegateWin mock_remote_delegate;
484 private_ptr->SetRemoteDelegate(&mock_remote_delegate);
485
486 // Initial state must be synced.
487 EXPECT_TRUE(mock_remote_delegate.text_input_client_updated_called());
488 ASSERT_EQ(1u, mock_remote_delegate.input_scopes().size());
489 EXPECT_EQ(IS_URL, mock_remote_delegate.input_scopes()[0]);
490
491 // Check TEXT_INPUT_TYPE_NONE is handled.
492 mock_remote_delegate.Reset();
493 mock_text_input_client.Reset();
494 mock_text_input_client.set_text_input_type(ui::TEXT_INPUT_TYPE_NONE);
495 mock_text_input_client.set_text_input_mode(ui::TEXT_INPUT_MODE_KATAKANA);
496 input_method->OnTextInputTypeChanged(&mock_text_input_client);
497 EXPECT_TRUE(mock_remote_delegate.text_input_client_updated_called());
498 EXPECT_TRUE(mock_remote_delegate.input_scopes().empty());
499
500 // Redundant OnTextInputTypeChanged must be ignored.
501 mock_remote_delegate.Reset();
502 input_method->OnTextInputTypeChanged(&mock_text_input_client);
503 EXPECT_FALSE(mock_remote_delegate.text_input_client_updated_called());
504
505 mock_remote_delegate.Reset();
506 mock_text_input_client.Reset();
507 mock_text_input_client.set_caret_bounds(gfx::Rect(10, 20, 30, 40));
508 input_method->OnCaretBoundsChanged(&mock_text_input_client);
509 }
510
511 TEST(RemoteInputMethodWinTest, DispatchKeyEvent_NativeKeyEvent) {
512 // Basically RemoteInputMethodWin does not handle native keydown event.
513
514 MockInputMethodDelegate delegate_;
515 MockTextInputClient mock_text_input_client;
516 scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));
517
518 const MSG wm_keydown = { NULL, WM_KEYDOWN, ui::VKEY_A };
519 ui::KeyEvent new_keydown(wm_keydown);
520 ui::KeyEvent native_keydown(new_keydown);
521
522 // This must not cause a crash.
523 input_method->DispatchKeyEvent(&native_keydown);
524 EXPECT_FALSE(native_keydown.handled());
525 EXPECT_TRUE(mock_text_input_client.inserted_text().empty());
526 EXPECT_TRUE(delegate_.fabricated_key_events().empty());
527 delegate_.Reset();
528 mock_text_input_client.Reset();
529
530 RemoteInputMethodPrivateWin* private_ptr =
531 RemoteInputMethodPrivateWin::Get(input_method.get());
532 ASSERT_TRUE(private_ptr != NULL);
533 MockRemoteInputMethodDelegateWin mock_remote_delegate;
534 private_ptr->SetRemoteDelegate(&mock_remote_delegate);
535
536 // TextInputClient is not focused yet here.
537 native_keydown = new_keydown;
538 input_method->DispatchKeyEvent(&native_keydown);
539 EXPECT_FALSE(native_keydown.handled());
540 EXPECT_TRUE(mock_text_input_client.inserted_text().empty());
541 EXPECT_TRUE(delegate_.fabricated_key_events().empty());
542 delegate_.Reset();
543 mock_text_input_client.Reset();
544
545 input_method->SetFocusedTextInputClient(&mock_text_input_client);
546
547 // TextInputClient is now focused here.
548 native_keydown = new_keydown;
549 input_method->DispatchKeyEvent(&native_keydown);
550 EXPECT_FALSE(native_keydown.handled());
551 EXPECT_TRUE(mock_text_input_client.inserted_text().empty());
552 EXPECT_TRUE(delegate_.fabricated_key_events().empty());
553 delegate_.Reset();
554 mock_text_input_client.Reset();
555 }
556
557 TEST(RemoteInputMethodWinTest, DispatchKeyEvent_NativeCharEvent) {
558 // RemoteInputMethodWin handles native char event if possible.
559
560 MockInputMethodDelegate delegate_;
561 MockTextInputClient mock_text_input_client;
562 scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));
563
564 const MSG wm_char = { NULL, WM_CHAR, 'A', 0 };
565 ui::KeyEvent new_char(wm_char);
566 ui::KeyEvent native_char(new_char);
567
568 // This must not cause a crash.
569 input_method->DispatchKeyEvent(&native_char);
570 EXPECT_FALSE(native_char.handled());
571 EXPECT_TRUE(mock_text_input_client.inserted_text().empty());
572 EXPECT_TRUE(delegate_.fabricated_key_events().empty());
573 delegate_.Reset();
574 mock_text_input_client.Reset();
575
576 RemoteInputMethodPrivateWin* private_ptr =
577 RemoteInputMethodPrivateWin::Get(input_method.get());
578 ASSERT_TRUE(private_ptr != NULL);
579 MockRemoteInputMethodDelegateWin mock_remote_delegate;
580 private_ptr->SetRemoteDelegate(&mock_remote_delegate);
581
582 // TextInputClient is not focused yet here.
583 native_char = new_char;
584 input_method->DispatchKeyEvent(&native_char);
585 EXPECT_FALSE(native_char.handled());
586 EXPECT_TRUE(mock_text_input_client.inserted_text().empty());
587 EXPECT_TRUE(delegate_.fabricated_key_events().empty());
588 delegate_.Reset();
589 mock_text_input_client.Reset();
590
591 input_method->SetFocusedTextInputClient(&mock_text_input_client);
592
593 // TextInputClient is now focused here.
594 native_char = new_char;
595 input_method->DispatchKeyEvent(&native_char);
596 EXPECT_TRUE(native_char.handled());
597 EXPECT_EQ(L"A", mock_text_input_client.inserted_text());
598 EXPECT_TRUE(delegate_.fabricated_key_events().empty());
599 delegate_.Reset();
600 mock_text_input_client.Reset();
601 }
602
603 TEST(RemoteInputMethodWinTest, DispatchKeyEvent_FabricatedKeyDown) {
604 // Fabricated non-char event will be delegated to
605 // InputMethodDelegate::DispatchFabricatedKeyEventPostIME as long as the
606 // delegate is installed.
607
608 MockInputMethodDelegate delegate_;
609 MockTextInputClient mock_text_input_client;
610 scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));
611
612 ui::KeyEvent new_keydown(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::EF_NONE);
613 new_keydown.set_character(L'A');
614 ui::KeyEvent fabricated_keydown(new_keydown);
615
616 // This must not cause a crash.
617 input_method->DispatchKeyEvent(&fabricated_keydown);
618 EXPECT_TRUE(fabricated_keydown.handled());
619 EXPECT_TRUE(mock_text_input_client.inserted_text().empty());
620 ASSERT_EQ(1u, delegate_.fabricated_key_events().size());
621 EXPECT_EQ(L'A', delegate_.fabricated_key_events()[0]);
622 delegate_.Reset();
623 mock_text_input_client.Reset();
624
625 RemoteInputMethodPrivateWin* private_ptr =
626 RemoteInputMethodPrivateWin::Get(input_method.get());
627 ASSERT_TRUE(private_ptr != NULL);
628 MockRemoteInputMethodDelegateWin mock_remote_delegate;
629 private_ptr->SetRemoteDelegate(&mock_remote_delegate);
630
631 // TextInputClient is not focused yet here.
632 fabricated_keydown = new_keydown;
633 input_method->DispatchKeyEvent(&fabricated_keydown);
634 EXPECT_TRUE(fabricated_keydown.handled());
635 EXPECT_TRUE(mock_text_input_client.inserted_text().empty());
636 ASSERT_EQ(1u, delegate_.fabricated_key_events().size());
637 EXPECT_EQ(L'A', delegate_.fabricated_key_events()[0]);
638 delegate_.Reset();
639 mock_text_input_client.Reset();
640
641 input_method->SetFocusedTextInputClient(&mock_text_input_client);
642 // TextInputClient is now focused here.
643 fabricated_keydown = new_keydown;
644 input_method->DispatchKeyEvent(&fabricated_keydown);
645 EXPECT_TRUE(fabricated_keydown.handled());
646 EXPECT_TRUE(mock_text_input_client.inserted_text().empty());
647 ASSERT_EQ(1u, delegate_.fabricated_key_events().size());
648 EXPECT_EQ(L'A', delegate_.fabricated_key_events()[0]);
649 delegate_.Reset();
650 mock_text_input_client.Reset();
651
652 input_method->SetDelegate(NULL);
653 // RemoteInputMethodDelegateWin is no longer set here.
654 fabricated_keydown = new_keydown;
655 input_method->DispatchKeyEvent(&fabricated_keydown);
656 EXPECT_FALSE(fabricated_keydown.handled());
657 EXPECT_TRUE(mock_text_input_client.inserted_text().empty());
658 }
659
660 TEST(RemoteInputMethodWinTest, DispatchKeyEvent_FabricatedChar) {
661 // Note: RemoteInputMethodWin::DispatchKeyEvent should always return true
662 // for fabricated character events.
663
664 MockInputMethodDelegate delegate_;
665 MockTextInputClient mock_text_input_client;
666 scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));
667
668 ui::KeyEvent new_char(L'A', ui::VKEY_A, ui::EF_NONE);
669 ui::KeyEvent fabricated_char(new_char);
670
671 // This must not cause a crash.
672 input_method->DispatchKeyEvent(&fabricated_char);
673 EXPECT_TRUE(fabricated_char.handled());
674 EXPECT_TRUE(mock_text_input_client.inserted_text().empty());
675 EXPECT_TRUE(delegate_.fabricated_key_events().empty());
676 delegate_.Reset();
677 mock_text_input_client.Reset();
678
679 RemoteInputMethodPrivateWin* private_ptr =
680 RemoteInputMethodPrivateWin::Get(input_method.get());
681 ASSERT_TRUE(private_ptr != NULL);
682 MockRemoteInputMethodDelegateWin mock_remote_delegate;
683 private_ptr->SetRemoteDelegate(&mock_remote_delegate);
684
685 // TextInputClient is not focused yet here.
686 fabricated_char = new_char;
687 input_method->DispatchKeyEvent(&fabricated_char);
688 EXPECT_TRUE(fabricated_char.handled());
689 EXPECT_TRUE(mock_text_input_client.inserted_text().empty());
690 EXPECT_TRUE(delegate_.fabricated_key_events().empty());
691 delegate_.Reset();
692 mock_text_input_client.Reset();
693
694 input_method->SetFocusedTextInputClient(&mock_text_input_client);
695
696 // TextInputClient is now focused here.
697 fabricated_char = new_char;
698 input_method->DispatchKeyEvent(&fabricated_char);
699 EXPECT_TRUE(fabricated_char.handled());
700 EXPECT_EQ(L"A", mock_text_input_client.inserted_text());
701 EXPECT_TRUE(delegate_.fabricated_key_events().empty());
702 delegate_.Reset();
703 mock_text_input_client.Reset();
704 }
705
706 TEST(RemoteInputMethodWinTest, OnCompositionChanged) {
707 MockInputMethodDelegate delegate_;
708 MockTextInputClient mock_text_input_client;
709 scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));
710
711 RemoteInputMethodPrivateWin* private_ptr =
712 RemoteInputMethodPrivateWin::Get(input_method.get());
713 ASSERT_TRUE(private_ptr != NULL);
714 MockRemoteInputMethodDelegateWin mock_remote_delegate;
715 private_ptr->SetRemoteDelegate(&mock_remote_delegate);
716
717 CompositionText composition_text;
718
719 // TextInputClient is not focused yet here.
720
721 private_ptr->OnCompositionChanged(composition_text);
722 EXPECT_EQ(0u, mock_text_input_client.call_count_set_composition_text());
723 delegate_.Reset();
724 mock_text_input_client.Reset();
725
726 input_method->SetFocusedTextInputClient(&mock_text_input_client);
727
728 // TextInputClient is now focused here.
729
730 private_ptr->OnCompositionChanged(composition_text);
731 EXPECT_EQ(1u, mock_text_input_client.call_count_set_composition_text());
732 delegate_.Reset();
733 mock_text_input_client.Reset();
734 }
735
736 TEST(RemoteInputMethodWinTest, OnTextCommitted) {
737 MockInputMethodDelegate delegate_;
738 MockTextInputClient mock_text_input_client;
739 scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));
740
741 RemoteInputMethodPrivateWin* private_ptr =
742 RemoteInputMethodPrivateWin::Get(input_method.get());
743 ASSERT_TRUE(private_ptr != NULL);
744 MockRemoteInputMethodDelegateWin mock_remote_delegate;
745 private_ptr->SetRemoteDelegate(&mock_remote_delegate);
746
747 base::string16 committed_text = L"Hello";
748
749 // TextInputClient is not focused yet here.
750
751 mock_text_input_client.set_text_input_type(TEXT_INPUT_TYPE_TEXT);
752 private_ptr->OnTextCommitted(committed_text);
753 EXPECT_EQ(0u, mock_text_input_client.call_count_insert_char());
754 EXPECT_EQ(0u, mock_text_input_client.call_count_insert_text());
755 EXPECT_EQ(L"", mock_text_input_client.inserted_text());
756 delegate_.Reset();
757 mock_text_input_client.Reset();
758
759 input_method->SetFocusedTextInputClient(&mock_text_input_client);
760
761 // TextInputClient is now focused here.
762
763 mock_text_input_client.set_text_input_type(TEXT_INPUT_TYPE_TEXT);
764 private_ptr->OnTextCommitted(committed_text);
765 EXPECT_EQ(0u, mock_text_input_client.call_count_insert_char());
766 EXPECT_EQ(1u, mock_text_input_client.call_count_insert_text());
767 EXPECT_EQ(committed_text, mock_text_input_client.inserted_text());
768 delegate_.Reset();
769 mock_text_input_client.Reset();
770
771 // When TextInputType is TEXT_INPUT_TYPE_NONE, TextInputClient::InsertText
772 // should not be used.
773 mock_text_input_client.set_text_input_type(TEXT_INPUT_TYPE_NONE);
774 private_ptr->OnTextCommitted(committed_text);
775 EXPECT_EQ(committed_text.size(),
776 mock_text_input_client.call_count_insert_char());
777 EXPECT_EQ(0u, mock_text_input_client.call_count_insert_text());
778 EXPECT_EQ(committed_text, mock_text_input_client.inserted_text());
779 delegate_.Reset();
780 mock_text_input_client.Reset();
781 }
782
783 TEST(RemoteInputMethodWinTest, OnTextInputStateChanged_Observer) {
784 DummyTextInputClient text_input_client;
785 DummyTextInputClient text_input_client_the_other;
786
787 MockInputMethodObserver input_method_observer;
788 MockInputMethodDelegate delegate_;
789 scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));
790 InputMethodScopedObserver scoped_observer(&input_method_observer);
791 scoped_observer.Add(input_method.get());
792
793 input_method->SetFocusedTextInputClient(&text_input_client);
794 ASSERT_EQ(&text_input_client, input_method->GetTextInputClient());
795 EXPECT_EQ(1u, input_method_observer.on_text_input_state_changed());
796 input_method_observer.Reset();
797
798 input_method->SetFocusedTextInputClient(&text_input_client);
799 ASSERT_EQ(&text_input_client, input_method->GetTextInputClient());
800 EXPECT_EQ(0u, input_method_observer.on_text_input_state_changed());
801 input_method_observer.Reset();
802
803 input_method->SetFocusedTextInputClient(&text_input_client_the_other);
804 ASSERT_EQ(&text_input_client_the_other, input_method->GetTextInputClient());
805 EXPECT_EQ(1u, input_method_observer.on_text_input_state_changed());
806 input_method_observer.Reset();
807
808 input_method->DetachTextInputClient(&text_input_client_the_other);
809 ASSERT_TRUE(input_method->GetTextInputClient() == NULL);
810 EXPECT_EQ(1u, input_method_observer.on_text_input_state_changed());
811 input_method_observer.Reset();
812 }
813
814 TEST(RemoteInputMethodWinTest, OnInputMethodDestroyed_Observer) {
815 DummyTextInputClient text_input_client;
816 DummyTextInputClient text_input_client_the_other;
817
818 MockInputMethodObserver input_method_observer;
819 InputMethodScopedObserver scoped_observer(&input_method_observer);
820
821 MockInputMethodDelegate delegate_;
822 scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));
823 input_method->AddObserver(&input_method_observer);
824
825 EXPECT_EQ(0u, input_method_observer.on_input_method_destroyed_changed());
826 input_method.reset();
827 EXPECT_EQ(1u, input_method_observer.on_input_method_destroyed_changed());
828 }
829
830 } // namespace
831 } // namespace ui
OLDNEW
« no previous file with comments | « ui/base/ime/remote_input_method_win.cc ('k') | ui/base/ime/ui_base_ime.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698