OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/views/controls/textfield/textfield.h" | 5 #include "ui/views/controls/textfield/textfield.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 #include <string> | 8 #include <string> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
12 #include "base/pickle.h" | 12 #include "base/pickle.h" |
13 #include "base/strings/string16.h" | 13 #include "base/strings/string16.h" |
14 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
15 #include "ui/base/clipboard/clipboard.h" | 15 #include "ui/base/clipboard/clipboard.h" |
16 #include "ui/base/clipboard/scoped_clipboard_writer.h" | 16 #include "ui/base/clipboard/scoped_clipboard_writer.h" |
17 #include "ui/base/dragdrop/drag_drop_types.h" | 17 #include "ui/base/dragdrop/drag_drop_types.h" |
18 #include "ui/base/ime/text_input_client.h" | 18 #include "ui/base/ime/text_input_client.h" |
19 #include "ui/base/l10n/l10n_util.h" | 19 #include "ui/base/l10n/l10n_util.h" |
20 #include "ui/base/ui_base_switches.h" | 20 #include "ui/base/ui_base_switches.h" |
21 #include "ui/base/ui_base_switches_util.h" | 21 #include "ui/base/ui_base_switches_util.h" |
22 #include "ui/events/event.h" | 22 #include "ui/events/event.h" |
23 #include "ui/events/keycodes/keyboard_codes.h" | 23 #include "ui/events/keycodes/keyboard_codes.h" |
| 24 #include "ui/events/test/event_generator.h" |
24 #include "ui/gfx/render_text.h" | 25 #include "ui/gfx/render_text.h" |
25 #include "ui/strings/grit/ui_strings.h" | 26 #include "ui/strings/grit/ui_strings.h" |
26 #include "ui/views/controls/textfield/textfield_controller.h" | 27 #include "ui/views/controls/textfield/textfield_controller.h" |
27 #include "ui/views/controls/textfield/textfield_model.h" | 28 #include "ui/views/controls/textfield/textfield_model.h" |
28 #include "ui/views/controls/textfield/textfield_test_api.h" | 29 #include "ui/views/controls/textfield/textfield_test_api.h" |
29 #include "ui/views/focus/focus_manager.h" | 30 #include "ui/views/focus/focus_manager.h" |
30 #include "ui/views/ime/mock_input_method.h" | 31 #include "ui/views/ime/mock_input_method.h" |
31 #include "ui/views/test/test_views_delegate.h" | 32 #include "ui/views/test/test_views_delegate.h" |
32 #include "ui/views/test/views_test_base.h" | 33 #include "ui/views/test/views_test_base.h" |
33 #include "ui/views/test/widget_test.h" | 34 #include "ui/views/test/widget_test.h" |
(...skipping 15 matching lines...) Expand all Loading... |
49 using base::ASCIIToUTF16; | 50 using base::ASCIIToUTF16; |
50 using base::UTF8ToUTF16; | 51 using base::UTF8ToUTF16; |
51 using base::WideToUTF16; | 52 using base::WideToUTF16; |
52 | 53 |
53 #define EXPECT_STR_EQ(ascii, utf16) EXPECT_EQ(ASCIIToUTF16(ascii), utf16) | 54 #define EXPECT_STR_EQ(ascii, utf16) EXPECT_EQ(ASCIIToUTF16(ascii), utf16) |
54 | 55 |
55 namespace { | 56 namespace { |
56 | 57 |
57 const base::char16 kHebrewLetterSamekh = 0x05E1; | 58 const base::char16 kHebrewLetterSamekh = 0x05E1; |
58 | 59 |
| 60 // The method used for dispatching key events. Either dispatch directly to the |
| 61 // MockInputMethod using the keycodes it expects internally, or dispatch to the |
| 62 // native window implementation using platform-specific keycodes, which should |
| 63 // be translated into the correct editing commands. |
| 64 enum EventDispatchMethod { |
| 65 DISPATCH_TO_INPUT_METHOD, |
| 66 DISPATCH_TO_WINDOW, |
| 67 }; |
| 68 |
59 // A Textfield wrapper to intercept OnKey[Pressed|Released]() ressults. | 69 // A Textfield wrapper to intercept OnKey[Pressed|Released]() ressults. |
60 class TestTextfield : public views::Textfield { | 70 class TestTextfield : public views::Textfield { |
61 public: | 71 public: |
62 TestTextfield() | 72 TestTextfield() |
63 : Textfield(), | 73 : Textfield(), |
64 key_handled_(false), | 74 key_handled_(false), |
65 key_received_(false), | 75 key_received_(false), |
66 weak_ptr_factory_(this) {} | 76 weak_ptr_factory_(this) {} |
67 | 77 |
68 bool OnKeyPressed(const ui::KeyEvent& e) override { | 78 bool OnKeyPressed(const ui::KeyEvent& e) override { |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 TextfieldTest() | 162 TextfieldTest() |
153 : widget_(NULL), | 163 : widget_(NULL), |
154 textfield_(NULL), | 164 textfield_(NULL), |
155 model_(NULL), | 165 model_(NULL), |
156 input_method_(NULL), | 166 input_method_(NULL), |
157 on_before_user_action_(0), | 167 on_before_user_action_(0), |
158 on_after_user_action_(0), | 168 on_after_user_action_(0), |
159 copied_to_clipboard_(ui::CLIPBOARD_TYPE_LAST) { | 169 copied_to_clipboard_(ui::CLIPBOARD_TYPE_LAST) { |
160 } | 170 } |
161 | 171 |
| 172 // Provide an implementation of GetParam which parameterized subclasses can |
| 173 // override using gtest's GetParam(). |
| 174 virtual EventDispatchMethod GetParamWithDefault() { |
| 175 return DISPATCH_TO_INPUT_METHOD; |
| 176 } |
| 177 |
162 // ::testing::Test: | 178 // ::testing::Test: |
163 void TearDown() override { | 179 void TearDown() override { |
164 if (widget_) | 180 if (widget_) |
165 widget_->Close(); | 181 widget_->Close(); |
166 ViewsTestBase::TearDown(); | 182 ViewsTestBase::TearDown(); |
167 } | 183 } |
168 | 184 |
169 ui::ClipboardType GetAndResetCopiedToClipboard() { | 185 ui::ClipboardType GetAndResetCopiedToClipboard() { |
170 ui::ClipboardType clipboard_type = copied_to_clipboard_; | 186 ui::ClipboardType clipboard_type = copied_to_clipboard_; |
171 copied_to_clipboard_ = ui::CLIPBOARD_TYPE_LAST; | 187 copied_to_clipboard_ = ui::CLIPBOARD_TYPE_LAST; |
(...skipping 23 matching lines...) Expand all Loading... |
195 | 211 |
196 void InitTextfield() { | 212 void InitTextfield() { |
197 InitTextfields(1); | 213 InitTextfields(1); |
198 } | 214 } |
199 | 215 |
200 void InitTextfields(int count) { | 216 void InitTextfields(int count) { |
201 ASSERT_FALSE(textfield_); | 217 ASSERT_FALSE(textfield_); |
202 textfield_ = new TestTextfield(); | 218 textfield_ = new TestTextfield(); |
203 textfield_->set_controller(this); | 219 textfield_->set_controller(this); |
204 widget_ = new Widget(); | 220 widget_ = new Widget(); |
205 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); | 221 |
| 222 // The widget type must be an activatable type, and we don't want to worry |
| 223 // about the non-client view, which leaves just TYPE_WINDOW_FRAMELESS. |
| 224 Widget::InitParams params = |
| 225 CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS); |
| 226 |
206 params.bounds = gfx::Rect(100, 100, 100, 100); | 227 params.bounds = gfx::Rect(100, 100, 100, 100); |
207 widget_->Init(params); | 228 widget_->Init(params); |
208 View* container = new View(); | 229 View* container = new View(); |
209 widget_->SetContentsView(container); | 230 widget_->SetContentsView(container); |
210 container->AddChildView(textfield_); | 231 container->AddChildView(textfield_); |
211 textfield_->SetBoundsRect(params.bounds); | 232 textfield_->SetBoundsRect(params.bounds); |
212 textfield_->set_id(1); | 233 textfield_->set_id(1); |
213 test_api_.reset(new TextfieldTestApi(textfield_)); | 234 test_api_.reset(new TextfieldTestApi(textfield_)); |
214 | 235 |
215 for (int i = 1; i < count; i++) { | 236 for (int i = 1; i < count; i++) { |
216 Textfield* textfield = new Textfield(); | 237 Textfield* textfield = new Textfield(); |
217 container->AddChildView(textfield); | 238 container->AddChildView(textfield); |
218 textfield->set_id(i + 1); | 239 textfield->set_id(i + 1); |
219 } | 240 } |
220 | 241 |
221 model_ = test_api_->model(); | 242 model_ = test_api_->model(); |
222 model_->ClearEditHistory(); | 243 model_->ClearEditHistory(); |
223 | 244 |
224 input_method_ = new MockInputMethod(); | 245 input_method_ = new MockInputMethod(); |
225 widget_->ReplaceInputMethod(input_method_); | 246 widget_->ReplaceInputMethod(input_method_); |
226 | 247 |
227 // Activate the widget and focus the textfield for input handling. | 248 // Since the window type is activatable, showing the widget will also |
228 widget_->Activate(); | 249 // activate it. Calling Activate directly is insufficient, since that does |
| 250 // not also _focus_ an aura::Window (i.e. using the FocusClient). Both the |
| 251 // widget and the textfield must have focus to properly handle input. |
| 252 widget_->Show(); |
229 textfield_->RequestFocus(); | 253 textfield_->RequestFocus(); |
230 | 254 |
231 // On Mac, activation is asynchronous since desktop widgets are used. We | 255 // On Mac, activation is asynchronous since desktop widgets are used. We |
232 // don't want parallel tests to steal active status either, so fake it. | 256 // don't want parallel tests to steal active status either, so fake it. |
233 #if defined(OS_MACOSX) && !defined(USE_AURA) | 257 #if defined(OS_MACOSX) && !defined(USE_AURA) |
234 fake_activation_ = test::WidgetTest::FakeWidgetIsActiveAlways(); | 258 fake_activation_ = test::WidgetTest::FakeWidgetIsActiveAlways(); |
235 #endif | 259 #endif |
| 260 |
| 261 if (GetParamWithDefault() == DISPATCH_TO_WINDOW) { |
| 262 event_generator_.reset(new ui::test::EventGenerator( |
| 263 GetContext(), widget_->GetNativeWindow())); |
| 264 } |
236 } | 265 } |
237 | 266 |
238 ui::MenuModel* GetContextMenuModel() { | 267 ui::MenuModel* GetContextMenuModel() { |
239 test_api_->UpdateContextMenu(); | 268 test_api_->UpdateContextMenu(); |
240 return test_api_->context_menu_contents(); | 269 return test_api_->context_menu_contents(); |
241 } | 270 } |
242 | 271 |
| 272 // On Mac, true if testing a views::TextField in an NSWindow using native |
| 273 // NSEvents. On other platforms, a helper function to avoid ifdef litter. |
| 274 bool TestingNativeMac() { |
| 275 #if defined(OS_MACOSX) |
| 276 return GetParamWithDefault() == DISPATCH_TO_WINDOW; |
| 277 #else |
| 278 return false; |
| 279 #endif |
| 280 } |
| 281 |
243 protected: | 282 protected: |
244 void SendKeyEvent(ui::KeyboardCode key_code, | 283 void SendKeyEvent(ui::KeyboardCode key_code, |
245 bool alt, | 284 bool alt, |
246 bool shift, | 285 bool shift, |
247 bool control, | 286 bool control_or_command, |
248 bool caps_lock) { | 287 bool caps_lock) { |
249 int flags = (alt ? ui::EF_ALT_DOWN : 0) | | 288 bool control = control_or_command; |
250 (shift ? ui::EF_SHIFT_DOWN : 0) | | 289 bool command = false; |
| 290 |
| 291 // By default, swap control and command for native events on Mac. This |
| 292 // handles most cases. |
| 293 if (TestingNativeMac()) |
| 294 std::swap(control, command); |
| 295 |
| 296 int flags = (alt ? ui::EF_ALT_DOWN : 0) | (shift ? ui::EF_SHIFT_DOWN : 0) | |
251 (control ? ui::EF_CONTROL_DOWN : 0) | | 297 (control ? ui::EF_CONTROL_DOWN : 0) | |
| 298 (command ? ui::EF_COMMAND_DOWN : 0) | |
252 (caps_lock ? ui::EF_CAPS_LOCK_DOWN : 0); | 299 (caps_lock ? ui::EF_CAPS_LOCK_DOWN : 0); |
| 300 |
| 301 // If dispatching to the window, ask the event generator to generate |
| 302 // events populated with native event information for each platform. |
| 303 if (GetParamWithDefault() == DISPATCH_TO_WINDOW) { |
| 304 event_generator_->PressKey(key_code, flags); |
| 305 return; |
| 306 } |
| 307 |
253 ui::KeyEvent event(ui::ET_KEY_PRESSED, key_code, flags); | 308 ui::KeyEvent event(ui::ET_KEY_PRESSED, key_code, flags); |
254 input_method_->DispatchKeyEvent(event); | 309 input_method_->DispatchKeyEvent(event); |
255 } | 310 } |
256 | 311 |
257 void SendKeyEvent(ui::KeyboardCode key_code, bool shift, bool control) { | 312 void SendKeyEvent(ui::KeyboardCode key_code, |
258 SendKeyEvent(key_code, false, shift, control, false); | 313 bool shift, |
| 314 bool control_or_command) { |
| 315 SendKeyEvent(key_code, false, shift, control_or_command, false); |
259 } | 316 } |
260 | 317 |
261 void SendKeyEvent(ui::KeyboardCode key_code) { | 318 void SendKeyEvent(ui::KeyboardCode key_code) { |
262 SendKeyEvent(key_code, false, false); | 319 SendKeyEvent(key_code, false, false); |
263 } | 320 } |
264 | 321 |
265 void SendKeyEvent(base::char16 ch) { | 322 void SendKeyEvent(base::char16 ch) { |
266 if (ch < 0x80) { | 323 if (ch < 0x80) { |
267 ui::KeyboardCode code = | 324 ui::KeyboardCode code = |
268 ch == ' ' ? ui::VKEY_SPACE : | 325 ch == ' ' ? ui::VKEY_SPACE : |
269 static_cast<ui::KeyboardCode>(ui::VKEY_A + ch - 'a'); | 326 static_cast<ui::KeyboardCode>(ui::VKEY_A + ch - 'a'); |
270 SendKeyEvent(code); | 327 SendKeyEvent(code); |
271 } else { | 328 } else { |
| 329 // TODO(tapted): Support DISPATCH_TO_WINDOW here. |
272 ui::KeyEvent event(ch, ui::VKEY_UNKNOWN, ui::EF_NONE); | 330 ui::KeyEvent event(ch, ui::VKEY_UNKNOWN, ui::EF_NONE); |
273 input_method_->DispatchKeyEvent(event); | 331 input_method_->DispatchKeyEvent(event); |
274 } | 332 } |
275 } | 333 } |
276 | 334 |
277 View* GetFocusedView() { | 335 View* GetFocusedView() { |
278 return widget_->GetFocusManager()->GetFocusedView(); | 336 return widget_->GetFocusManager()->GetFocusedView(); |
279 } | 337 } |
280 | 338 |
281 int GetCursorPositionX(int cursor_pos) { | 339 int GetCursorPositionX(int cursor_pos) { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 | 408 |
351 // Indicates how many times OnBeforeUserAction() is called. | 409 // Indicates how many times OnBeforeUserAction() is called. |
352 int on_before_user_action_; | 410 int on_before_user_action_; |
353 | 411 |
354 // Indicates how many times OnAfterUserAction() is called. | 412 // Indicates how many times OnAfterUserAction() is called. |
355 int on_after_user_action_; | 413 int on_after_user_action_; |
356 | 414 |
357 private: | 415 private: |
358 ui::ClipboardType copied_to_clipboard_; | 416 ui::ClipboardType copied_to_clipboard_; |
359 scoped_ptr<test::WidgetTest::FakeActivation> fake_activation_; | 417 scoped_ptr<test::WidgetTest::FakeActivation> fake_activation_; |
| 418 scoped_ptr<ui::test::EventGenerator> event_generator_; |
360 | 419 |
361 DISALLOW_COPY_AND_ASSIGN(TextfieldTest); | 420 DISALLOW_COPY_AND_ASSIGN(TextfieldTest); |
362 }; | 421 }; |
363 | 422 |
| 423 // TextfieldTest that overrides GetParamWithDefault() to override the default |
| 424 // using GetParam() from the gtest interface. |
| 425 class TextfieldTestWithParam |
| 426 : public TextfieldTest, |
| 427 public ::testing::WithParamInterface<EventDispatchMethod> { |
| 428 public: |
| 429 TextfieldTestWithParam() {} |
| 430 |
| 431 void SendHomeEvent(bool shift) { |
| 432 if (TestingNativeMac()) { |
| 433 // Use Cmd+Left on native Mac. An RTL-agnostic "end" doesn't have a |
| 434 // default key-binding on Mac. |
| 435 SendKeyEvent(ui::VKEY_LEFT, shift /* shift */, true /* command */); |
| 436 return; |
| 437 } |
| 438 SendKeyEvent(ui::VKEY_HOME, shift /* shift */, false /* control */); |
| 439 } |
| 440 |
| 441 void SendEndEvent(bool shift) { |
| 442 if (TestingNativeMac()) { |
| 443 SendKeyEvent(ui::VKEY_RIGHT, shift, true); // Cmd+Right. |
| 444 return; |
| 445 } |
| 446 SendKeyEvent(ui::VKEY_END, shift, false); |
| 447 } |
| 448 |
| 449 // Sends {delete, move, select} word {forward, backward}. |
| 450 void SendWordEvent(ui::KeyboardCode key, bool shift) { |
| 451 bool alt = false; |
| 452 bool control = true; |
| 453 bool caps = false; |
| 454 if (TestingNativeMac()) { |
| 455 // Use Alt+Left/Right/Backspace on native Mac. |
| 456 alt = true; |
| 457 control = false; |
| 458 } |
| 459 SendKeyEvent(key, alt, shift, control, caps); |
| 460 } |
| 461 |
| 462 // Overridden from TextfieldTest: |
| 463 EventDispatchMethod GetParamWithDefault() override { return GetParam(); } |
| 464 |
| 465 private: |
| 466 DISALLOW_COPY_AND_ASSIGN(TextfieldTestWithParam); |
| 467 }; |
| 468 |
364 TEST_F(TextfieldTest, ModelChangesTest) { | 469 TEST_F(TextfieldTest, ModelChangesTest) { |
365 InitTextfield(); | 470 InitTextfield(); |
366 | 471 |
367 // TextfieldController::ContentsChanged() shouldn't be called when changing | 472 // TextfieldController::ContentsChanged() shouldn't be called when changing |
368 // text programmatically. | 473 // text programmatically. |
369 last_contents_.clear(); | 474 last_contents_.clear(); |
370 textfield_->SetText(ASCIIToUTF16("this is")); | 475 textfield_->SetText(ASCIIToUTF16("this is")); |
371 | 476 |
372 EXPECT_STR_EQ("this is", model_->text()); | 477 EXPECT_STR_EQ("this is", model_->text()); |
373 EXPECT_STR_EQ("this is", textfield_->text()); | 478 EXPECT_STR_EQ("this is", textfield_->text()); |
(...skipping 17 matching lines...) Expand all Loading... |
391 SendKeyEvent(ui::VKEY_E, false, false, false, false); | 496 SendKeyEvent(ui::VKEY_E, false, false, false, false); |
392 SendKeyEvent(ui::VKEY_X, false, true, false, true); | 497 SendKeyEvent(ui::VKEY_X, false, true, false, true); |
393 SendKeyEvent(ui::VKEY_T, false, false, false, true); | 498 SendKeyEvent(ui::VKEY_T, false, false, false, true); |
394 SendKeyEvent(ui::VKEY_1, false, true, false, false); | 499 SendKeyEvent(ui::VKEY_1, false, true, false, false); |
395 SendKeyEvent(ui::VKEY_1, false, false, false, false); | 500 SendKeyEvent(ui::VKEY_1, false, false, false, false); |
396 SendKeyEvent(ui::VKEY_1, false, true, false, true); | 501 SendKeyEvent(ui::VKEY_1, false, true, false, true); |
397 SendKeyEvent(ui::VKEY_1, false, false, false, true); | 502 SendKeyEvent(ui::VKEY_1, false, false, false, true); |
398 EXPECT_STR_EQ("TexT!1!1", textfield_->text()); | 503 EXPECT_STR_EQ("TexT!1!1", textfield_->text()); |
399 } | 504 } |
400 | 505 |
401 TEST_F(TextfieldTest, ControlAndSelectTest) { | 506 TEST_P(TextfieldTestWithParam, ControlAndSelectTest) { |
402 // Insert a test string in a textfield. | 507 // Insert a test string in a textfield. |
403 InitTextfield(); | 508 InitTextfield(); |
404 textfield_->SetText(ASCIIToUTF16("one two three")); | 509 textfield_->SetText(ASCIIToUTF16("one two three")); |
405 SendKeyEvent(ui::VKEY_HOME, false /* shift */, false /* control */); | 510 SendHomeEvent(false); |
406 SendKeyEvent(ui::VKEY_RIGHT, true, false); | 511 SendKeyEvent(ui::VKEY_RIGHT, true, false); |
407 SendKeyEvent(ui::VKEY_RIGHT, true, false); | 512 SendKeyEvent(ui::VKEY_RIGHT, true, false); |
408 SendKeyEvent(ui::VKEY_RIGHT, true, false); | 513 SendKeyEvent(ui::VKEY_RIGHT, true, false); |
409 | 514 |
410 EXPECT_STR_EQ("one", textfield_->GetSelectedText()); | 515 EXPECT_STR_EQ("one", textfield_->GetSelectedText()); |
411 | 516 |
412 // Test word select. | 517 // Test word select. |
413 SendKeyEvent(ui::VKEY_RIGHT, true, true); | 518 SendWordEvent(ui::VKEY_RIGHT, true); |
414 EXPECT_STR_EQ("one two", textfield_->GetSelectedText()); | 519 EXPECT_STR_EQ("one two", textfield_->GetSelectedText()); |
415 SendKeyEvent(ui::VKEY_RIGHT, true, true); | 520 SendWordEvent(ui::VKEY_RIGHT, true); |
416 EXPECT_STR_EQ("one two three", textfield_->GetSelectedText()); | 521 EXPECT_STR_EQ("one two three", textfield_->GetSelectedText()); |
417 SendKeyEvent(ui::VKEY_LEFT, true, true); | 522 SendWordEvent(ui::VKEY_LEFT, true); |
418 EXPECT_STR_EQ("one two ", textfield_->GetSelectedText()); | 523 EXPECT_STR_EQ("one two ", textfield_->GetSelectedText()); |
419 SendKeyEvent(ui::VKEY_LEFT, true, true); | 524 SendWordEvent(ui::VKEY_LEFT, true); |
420 EXPECT_STR_EQ("one ", textfield_->GetSelectedText()); | 525 EXPECT_STR_EQ("one ", textfield_->GetSelectedText()); |
421 | 526 |
422 // Replace the selected text. | 527 // Replace the selected text. |
423 SendKeyEvent(ui::VKEY_Z, true, false); | 528 SendKeyEvent(ui::VKEY_Z, true, false); |
424 SendKeyEvent(ui::VKEY_E, true, false); | 529 SendKeyEvent(ui::VKEY_E, true, false); |
425 SendKeyEvent(ui::VKEY_R, true, false); | 530 SendKeyEvent(ui::VKEY_R, true, false); |
426 SendKeyEvent(ui::VKEY_O, true, false); | 531 SendKeyEvent(ui::VKEY_O, true, false); |
427 SendKeyEvent(ui::VKEY_SPACE, false, false); | 532 SendKeyEvent(ui::VKEY_SPACE, false, false); |
428 EXPECT_STR_EQ("ZERO two three", textfield_->text()); | 533 EXPECT_STR_EQ("ZERO two three", textfield_->text()); |
429 | 534 |
430 SendKeyEvent(ui::VKEY_END, true, false); | 535 SendEndEvent(true); |
431 EXPECT_STR_EQ("two three", textfield_->GetSelectedText()); | 536 EXPECT_STR_EQ("two three", textfield_->GetSelectedText()); |
432 SendKeyEvent(ui::VKEY_HOME, true, false); | 537 SendHomeEvent(true); |
433 EXPECT_STR_EQ("ZERO ", textfield_->GetSelectedText()); | 538 EXPECT_STR_EQ("ZERO ", textfield_->GetSelectedText()); |
434 } | 539 } |
435 | 540 |
436 TEST_F(TextfieldTest, InsertionDeletionTest) { | 541 TEST_P(TextfieldTestWithParam, InsertionDeletionTest) { |
437 // Insert a test string in a textfield. | 542 // Insert a test string in a textfield. |
438 InitTextfield(); | 543 InitTextfield(); |
439 for (size_t i = 0; i < 10; i++) | 544 for (size_t i = 0; i < 10; i++) |
440 SendKeyEvent(static_cast<ui::KeyboardCode>(ui::VKEY_A + i)); | 545 SendKeyEvent(static_cast<ui::KeyboardCode>(ui::VKEY_A + i)); |
441 EXPECT_STR_EQ("abcdefghij", textfield_->text()); | 546 EXPECT_STR_EQ("abcdefghij", textfield_->text()); |
442 | 547 |
443 // Test the delete and backspace keys. | 548 // Test the delete and backspace keys. |
444 textfield_->SelectRange(gfx::Range(5)); | 549 textfield_->SelectRange(gfx::Range(5)); |
445 for (int i = 0; i < 3; i++) | 550 for (int i = 0; i < 3; i++) |
446 SendKeyEvent(ui::VKEY_BACK); | 551 SendKeyEvent(ui::VKEY_BACK); |
447 EXPECT_STR_EQ("abfghij", textfield_->text()); | 552 EXPECT_STR_EQ("abfghij", textfield_->text()); |
448 for (int i = 0; i < 3; i++) | 553 for (int i = 0; i < 3; i++) |
449 SendKeyEvent(ui::VKEY_DELETE); | 554 SendKeyEvent(ui::VKEY_DELETE); |
450 EXPECT_STR_EQ("abij", textfield_->text()); | 555 EXPECT_STR_EQ("abij", textfield_->text()); |
451 | 556 |
452 // Select all and replace with "k". | 557 // Select all and replace with "k". |
453 textfield_->SelectAll(false); | 558 textfield_->SelectAll(false); |
454 SendKeyEvent(ui::VKEY_K); | 559 SendKeyEvent(ui::VKEY_K); |
455 EXPECT_STR_EQ("k", textfield_->text()); | 560 EXPECT_STR_EQ("k", textfield_->text()); |
456 | 561 |
457 // Delete the previous word from cursor. | 562 // Delete the previous word from cursor. |
| 563 bool shift = false; |
458 textfield_->SetText(ASCIIToUTF16("one two three four")); | 564 textfield_->SetText(ASCIIToUTF16("one two three four")); |
459 SendKeyEvent(ui::VKEY_END); | 565 SendEndEvent(shift); |
460 SendKeyEvent(ui::VKEY_BACK, false, false, true, false); | 566 SendWordEvent(ui::VKEY_BACK, shift); |
461 EXPECT_STR_EQ("one two three ", textfield_->text()); | 567 EXPECT_STR_EQ("one two three ", textfield_->text()); |
462 | 568 |
463 // Delete to a line break on Linux and ChromeOS, to a word break on Windows. | 569 // Delete to a line break on Linux and ChromeOS, to a word break on Windows |
464 SendKeyEvent(ui::VKEY_LEFT, false, false, true, false); | 570 // and Mac. |
465 SendKeyEvent(ui::VKEY_BACK, false, true, true, false); | 571 SendWordEvent(ui::VKEY_LEFT, shift); |
| 572 shift = true; |
| 573 SendWordEvent(ui::VKEY_BACK, shift); |
466 #if defined(OS_LINUX) | 574 #if defined(OS_LINUX) |
467 EXPECT_STR_EQ("three ", textfield_->text()); | 575 EXPECT_STR_EQ("three ", textfield_->text()); |
468 #else | 576 #else |
469 EXPECT_STR_EQ("one three ", textfield_->text()); | 577 EXPECT_STR_EQ("one three ", textfield_->text()); |
470 #endif | 578 #endif |
471 | 579 |
472 // Delete the next word from cursor. | 580 // Delete the next word from cursor. |
473 textfield_->SetText(ASCIIToUTF16("one two three four")); | 581 textfield_->SetText(ASCIIToUTF16("one two three four")); |
474 SendKeyEvent(ui::VKEY_HOME); | 582 shift = false; |
475 SendKeyEvent(ui::VKEY_DELETE, false, false, true, false); | 583 SendHomeEvent(shift); |
| 584 SendWordEvent(ui::VKEY_DELETE, shift); |
476 EXPECT_STR_EQ(" two three four", textfield_->text()); | 585 EXPECT_STR_EQ(" two three four", textfield_->text()); |
477 | 586 |
478 // Delete to a line break on Linux and ChromeOS, to a word break on Windows. | 587 // Delete to a line break on Linux and ChromeOS, to a word break on Windows |
479 SendKeyEvent(ui::VKEY_RIGHT, false, false, true, false); | 588 // and Mac. |
480 SendKeyEvent(ui::VKEY_DELETE, false, true, true, false); | 589 SendWordEvent(ui::VKEY_RIGHT, shift); |
| 590 shift = true; |
| 591 SendWordEvent(ui::VKEY_DELETE, shift); |
481 #if defined(OS_LINUX) | 592 #if defined(OS_LINUX) |
482 EXPECT_STR_EQ(" two", textfield_->text()); | 593 EXPECT_STR_EQ(" two", textfield_->text()); |
483 #else | 594 #else |
484 EXPECT_STR_EQ(" two four", textfield_->text()); | 595 EXPECT_STR_EQ(" two four", textfield_->text()); |
485 #endif | 596 #endif |
486 } | 597 } |
487 | 598 |
488 TEST_F(TextfieldTest, PasswordTest) { | 599 TEST_F(TextfieldTest, PasswordTest) { |
489 InitTextfield(); | 600 InitTextfield(); |
490 textfield_->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD); | 601 textfield_->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD); |
(...skipping 1617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2108 EXPECT_EQ(sel_range, range); | 2219 EXPECT_EQ(sel_range, range); |
2109 | 2220 |
2110 // Tap again on selection and check if touch selection handles are still | 2221 // Tap again on selection and check if touch selection handles are still |
2111 // present and selection is changed to a cursor at tap location. | 2222 // present and selection is changed to a cursor at tap location. |
2112 Tap(tap_point); | 2223 Tap(tap_point); |
2113 textfield_->GetSelectionRange(&range); | 2224 textfield_->GetSelectionRange(&range); |
2114 EXPECT_TRUE(test_api_->touch_selection_controller()); | 2225 EXPECT_TRUE(test_api_->touch_selection_controller()); |
2115 EXPECT_EQ(tap_range, range); | 2226 EXPECT_EQ(tap_range, range); |
2116 } | 2227 } |
2117 | 2228 |
| 2229 // Instantiate parameterized tests. These are just the ones above using "TEST_P" |
| 2230 // rather than "TEST_F". |
| 2231 INSTANTIATE_TEST_CASE_P( |
| 2232 TextfieldTestWithParamInstance, |
| 2233 TextfieldTestWithParam, |
| 2234 ::testing::Values<EventDispatchMethod>(DISPATCH_TO_INPUT_METHOD, |
| 2235 DISPATCH_TO_WINDOW)); |
| 2236 |
2118 } // namespace views | 2237 } // namespace views |
OLD | NEW |