Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / ui / views / controls / textfield / textfield_model_unittest.cc
blobc64120987a63fa7c3b38fca6d64c1effbe0a3207
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
3 // found in the LICENSE file.
5 #include <vector>
7 #include "base/auto_reset.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/string16.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "ui/base/clipboard/clipboard.h"
14 #include "ui/base/clipboard/scoped_clipboard_writer.h"
15 #include "ui/gfx/range/range.h"
16 #include "ui/gfx/render_text.h"
17 #include "ui/views/controls/textfield/textfield.h"
18 #include "ui/views/controls/textfield/textfield_model.h"
19 #include "ui/views/test/test_views_delegate.h"
20 #include "ui/views/test/views_test_base.h"
22 #if defined(OS_WIN)
23 #include "base/win/windows_version.h"
24 #endif
26 #define EXPECT_STR_EQ(ascii, utf16) EXPECT_EQ(base::ASCIIToUTF16(ascii), utf16)
28 namespace {
30 struct WordAndCursor {
31 WordAndCursor(const wchar_t* w, size_t c) : word(w), cursor(c) {}
33 const wchar_t* word;
34 size_t cursor;
37 void MoveCursorTo(views::TextfieldModel& model, size_t pos) {
38 model.MoveCursorTo(gfx::SelectionModel(pos, gfx::CURSOR_FORWARD));
41 } // namespace
43 namespace views {
45 class TextfieldModelTest : public ViewsTestBase,
46 public TextfieldModel::Delegate {
47 public:
48 TextfieldModelTest()
49 : ViewsTestBase(),
50 composition_text_confirmed_or_cleared_(false) {
53 void OnCompositionTextConfirmedOrCleared() override {
54 composition_text_confirmed_or_cleared_ = true;
57 protected:
58 void ResetModel(TextfieldModel* model) const {
59 model->SetText(base::string16());
60 model->ClearEditHistory();
63 bool composition_text_confirmed_or_cleared_;
65 private:
66 DISALLOW_COPY_AND_ASSIGN(TextfieldModelTest);
69 TEST_F(TextfieldModelTest, EditString) {
70 TextfieldModel model(NULL);
71 // Append two strings.
72 model.Append(base::ASCIIToUTF16("HILL"));
73 EXPECT_STR_EQ("HILL", model.text());
74 model.Append(base::ASCIIToUTF16("WORLD"));
75 EXPECT_STR_EQ("HILLWORLD", model.text());
77 // Insert "E" and replace "I" with "L" to make "HELLO".
78 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, false);
79 model.InsertChar('E');
80 EXPECT_STR_EQ("HEILLWORLD", model.text());
81 model.ReplaceChar('L');
82 EXPECT_STR_EQ("HELLLWORLD", model.text());
83 model.ReplaceChar('L');
84 model.ReplaceChar('O');
85 EXPECT_STR_EQ("HELLOWORLD", model.text());
87 // Delete 6th char "W", then delete 5th char "O".
88 EXPECT_EQ(5U, model.GetCursorPosition());
89 EXPECT_TRUE(model.Delete());
90 EXPECT_STR_EQ("HELLOORLD", model.text());
91 EXPECT_TRUE(model.Backspace());
92 EXPECT_EQ(4U, model.GetCursorPosition());
93 EXPECT_STR_EQ("HELLORLD", model.text());
95 // Move the cursor to start; backspace should fail.
96 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_LEFT, false);
97 EXPECT_FALSE(model.Backspace());
98 EXPECT_STR_EQ("HELLORLD", model.text());
99 // Move the cursor to the end; delete should fail, but backspace should work.
100 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_RIGHT, false);
101 EXPECT_FALSE(model.Delete());
102 EXPECT_STR_EQ("HELLORLD", model.text());
103 EXPECT_TRUE(model.Backspace());
104 EXPECT_STR_EQ("HELLORL", model.text());
106 MoveCursorTo(model, 5);
107 model.ReplaceText(base::ASCIIToUTF16(" WOR"));
108 EXPECT_STR_EQ("HELLO WORL", model.text());
111 TEST_F(TextfieldModelTest, EditString_SimpleRTL) {
112 TextfieldModel model(NULL);
113 // Append two strings.
114 model.Append(base::WideToUTF16(L"\x05d0\x05d1\x05d2"));
115 EXPECT_EQ(base::WideToUTF16(L"\x05d0\x05d1\x05d2"), model.text());
116 model.Append(base::WideToUTF16(L"\x05e0\x05e1\x05e2"));
117 EXPECT_EQ(base::WideToUTF16(L"\x05d0\x05d1\x05d2\x05e0\x05e1\x05e2"),
118 model.text());
120 // Insert "\x05f0".
121 MoveCursorTo(model, 1);
122 model.InsertChar(0x05f0);
123 EXPECT_EQ(base::WideToUTF16(L"\x05d0\x05f0\x05d1\x05d2\x05e0\x05e1\x05e2"),
124 model.text());
126 // Replace "\x05d1" with "\x05f1".
127 model.ReplaceChar(0x05f1);
128 EXPECT_EQ(base::WideToUTF16(L"\x05d0\x05f0\x5f1\x05d2\x05e0\x05e1\x05e2"),
129 model.text());
131 // Test Delete and backspace.
132 EXPECT_EQ(3U, model.GetCursorPosition());
133 EXPECT_TRUE(model.Delete());
134 EXPECT_EQ(base::WideToUTF16(L"\x05d0\x05f0\x5f1\x05e0\x05e1\x05e2"),
135 model.text());
136 EXPECT_TRUE(model.Backspace());
137 EXPECT_EQ(2U, model.GetCursorPosition());
138 EXPECT_EQ(base::WideToUTF16(L"\x05d0\x05f0\x05e0\x05e1\x05e2"), model.text());
141 TEST_F(TextfieldModelTest, EditString_ComplexScript) {
142 // TODO(msw): XP fails due to lack of font support: http://crbug.com/106450
143 bool on_windows_xp = false;
144 #if defined(OS_WIN)
145 on_windows_xp = base::win::GetVersion() < base::win::VERSION_VISTA;
146 #endif
148 TextfieldModel model(NULL);
150 // Append two Hindi strings.
151 model.Append(base::WideToUTF16(L"\x0915\x093f\x0915\x094d\x0915"));
152 EXPECT_EQ(base::WideToUTF16(L"\x0915\x093f\x0915\x094d\x0915"), model.text());
153 model.Append(base::WideToUTF16(L"\x0915\x094d\x092e\x094d"));
154 EXPECT_EQ(base::WideToUTF16(
155 L"\x0915\x093f\x0915\x094d\x0915\x0915\x094d\x092e\x094d"), model.text());
157 if (!on_windows_xp) {
158 // Ensure the cursor cannot be placed in the middle of a grapheme.
159 MoveCursorTo(model, 1);
160 EXPECT_EQ(0U, model.GetCursorPosition());
162 MoveCursorTo(model, 2);
163 EXPECT_EQ(2U, model.GetCursorPosition());
164 model.InsertChar('a');
165 EXPECT_EQ(base::WideToUTF16(
166 L"\x0915\x093f\x0061\x0915\x094d\x0915\x0915\x094d\x092e\x094d"),
167 model.text());
169 // ReplaceChar will replace the whole grapheme.
170 model.ReplaceChar('b');
171 // TODO(xji): temporarily disable in platform Win since the complex script
172 // characters turned into empty square due to font regression. So, not able
173 // to test 2 characters belong to the same grapheme.
174 #if defined(OS_LINUX)
175 EXPECT_EQ(base::WideToUTF16(
176 L"\x0915\x093f\x0061\x0062\x0915\x0915\x094d\x092e\x094d"),
177 model.text());
178 #endif
179 EXPECT_EQ(4U, model.GetCursorPosition());
182 // Delete should delete the whole grapheme.
183 MoveCursorTo(model, 0);
184 // TODO(xji): temporarily disable in platform Win since the complex script
185 // characters turned into empty square due to font regression. So, not able
186 // to test 2 characters belong to the same grapheme.
187 #if defined(OS_LINUX)
188 EXPECT_TRUE(model.Delete());
189 EXPECT_EQ(base::WideToUTF16(L"\x0061\x0062\x0915\x0915\x094d\x092e\x094d"),
190 model.text());
191 MoveCursorTo(model, model.text().length());
192 EXPECT_EQ(model.text().length(), model.GetCursorPosition());
193 EXPECT_TRUE(model.Backspace());
194 EXPECT_EQ(base::WideToUTF16(L"\x0061\x0062\x0915\x0915\x094d\x092e"),
195 model.text());
196 #endif
198 // Test cursor position and deletion for Hindi Virama.
199 model.SetText(base::WideToUTF16(L"\x0D38\x0D4D\x0D15\x0D16\x0D2E"));
200 MoveCursorTo(model, 0);
201 EXPECT_EQ(0U, model.GetCursorPosition());
203 if (!on_windows_xp) {
204 MoveCursorTo(model, 1);
205 EXPECT_EQ(0U, model.GetCursorPosition());
206 MoveCursorTo(model, 3);
207 EXPECT_EQ(3U, model.GetCursorPosition());
210 // TODO(asvitkine): Temporarily disable the following check on Windows. It
211 // seems Windows treats "\x0D38\x0D4D\x0D15" as a single grapheme.
212 #if !defined(OS_WIN)
213 MoveCursorTo(model, 2);
214 EXPECT_EQ(2U, model.GetCursorPosition());
215 EXPECT_TRUE(model.Backspace());
216 EXPECT_EQ(base::WideToUTF16(L"\x0D38\x0D15\x0D16\x0D2E"), model.text());
217 #endif
219 model.SetText(
220 base::WideToUTF16(L"\x05d5\x05b7\x05D9\x05B0\x05D4\x05B4\x05D9"));
221 MoveCursorTo(model, 0);
222 EXPECT_TRUE(model.Delete());
223 EXPECT_TRUE(model.Delete());
224 EXPECT_TRUE(model.Delete());
225 EXPECT_TRUE(model.Delete());
226 EXPECT_EQ(base::WideToUTF16(L""), model.text());
228 // The first 2 characters are not strong directionality characters.
229 model.SetText(
230 base::WideToUTF16(L"\x002C\x0020\x05D1\x05BC\x05B7\x05E9\x05BC"));
231 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_LEFT, false);
232 EXPECT_TRUE(model.Backspace());
233 EXPECT_EQ(base::WideToUTF16(L"\x002C\x0020\x05D1\x05BC\x05B7\x05E9"),
234 model.text());
237 TEST_F(TextfieldModelTest, EmptyString) {
238 TextfieldModel model(NULL);
239 EXPECT_EQ(base::string16(), model.text());
240 EXPECT_EQ(base::string16(), model.GetSelectedText());
242 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, true);
243 EXPECT_EQ(0U, model.GetCursorPosition());
244 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true);
245 EXPECT_EQ(0U, model.GetCursorPosition());
247 EXPECT_EQ(base::string16(), model.GetSelectedText());
249 EXPECT_FALSE(model.Delete());
250 EXPECT_FALSE(model.Backspace());
253 TEST_F(TextfieldModelTest, Selection) {
254 TextfieldModel model(NULL);
255 model.Append(base::ASCIIToUTF16("HELLO"));
256 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, false);
257 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true);
258 EXPECT_STR_EQ("E", model.GetSelectedText());
259 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true);
260 EXPECT_STR_EQ("EL", model.GetSelectedText());
262 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_LEFT, true);
263 EXPECT_STR_EQ("H", model.GetSelectedText());
264 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_RIGHT, true);
265 EXPECT_STR_EQ("ELLO", model.GetSelectedText());
266 model.ClearSelection();
267 EXPECT_EQ(base::string16(), model.GetSelectedText());
269 // SelectAll(false) selects towards the end.
270 model.SelectAll(false);
271 EXPECT_STR_EQ("HELLO", model.GetSelectedText());
272 EXPECT_EQ(gfx::Range(0, 5), model.render_text()->selection());
274 // SelectAll(true) selects towards the beginning.
275 model.SelectAll(true);
276 EXPECT_STR_EQ("HELLO", model.GetSelectedText());
277 EXPECT_EQ(gfx::Range(5, 0), model.render_text()->selection());
279 // Select and move cursor.
280 model.SelectRange(gfx::Range(1U, 3U));
281 EXPECT_STR_EQ("EL", model.GetSelectedText());
282 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, false);
283 EXPECT_EQ(1U, model.GetCursorPosition());
284 model.SelectRange(gfx::Range(1U, 3U));
285 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, false);
286 EXPECT_EQ(3U, model.GetCursorPosition());
288 // Select all and move cursor.
289 model.SelectAll(false);
290 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, false);
291 EXPECT_EQ(0U, model.GetCursorPosition());
292 model.SelectAll(false);
293 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, false);
294 EXPECT_EQ(5U, model.GetCursorPosition());
297 TEST_F(TextfieldModelTest, Selection_BidiWithNonSpacingMarks) {
298 // Selection is a logical operation. And it should work with the arrow
299 // keys doing visual movements, while the selection is logical between
300 // the (logical) start and end points. Selection is simply defined as
301 // the portion of text between the logical positions of the start and end
302 // caret positions.
303 TextfieldModel model(NULL);
304 // TODO(xji): temporarily disable in platform Win since the complex script
305 // characters turned into empty square due to font regression. So, not able
306 // to test 2 characters belong to the same grapheme.
307 #if defined(OS_LINUX)
308 model.Append(base::WideToUTF16(
309 L"abc\x05E9\x05BC\x05C1\x05B8\x05E0\x05B8" L"def"));
310 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, false);
311 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, false);
313 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true);
314 EXPECT_EQ(gfx::Range(2, 3), model.render_text()->selection());
315 EXPECT_EQ(base::WideToUTF16(L"c"), model.GetSelectedText());
317 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true);
318 EXPECT_EQ(gfx::Range(2, 7), model.render_text()->selection());
319 EXPECT_EQ(base::WideToUTF16(L"c\x05E9\x05BC\x05C1\x05B8"),
320 model.GetSelectedText());
322 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true);
323 EXPECT_EQ(gfx::Range(2, 3), model.render_text()->selection());
324 EXPECT_EQ(base::WideToUTF16(L"c"), model.GetSelectedText());
326 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true);
327 EXPECT_EQ(gfx::Range(2, 10), model.render_text()->selection());
328 EXPECT_EQ(base::WideToUTF16(L"c\x05E9\x05BC\x05C1\x05B8\x05E0\x05B8" L"d"),
329 model.GetSelectedText());
331 model.ClearSelection();
332 EXPECT_EQ(base::string16(), model.GetSelectedText());
333 model.SelectAll(false);
334 EXPECT_EQ(
335 base::WideToUTF16(L"abc\x05E9\x05BC\x05C1\x05B8\x05E0\x05B8" L"def"),
336 model.GetSelectedText());
337 #endif
339 // In case of "aBc", this test shows how to select "aB" or "Bc", assume 'B' is
340 // an RTL character.
341 model.SetText(base::WideToUTF16(L"a\x05E9" L"b"));
342 MoveCursorTo(model, 0);
343 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true);
344 EXPECT_EQ(base::WideToUTF16(L"a"), model.GetSelectedText());
346 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true);
347 EXPECT_EQ(base::WideToUTF16(L"a"), model.GetSelectedText());
349 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true);
350 EXPECT_EQ(base::WideToUTF16(L"a\x05E9" L"b"), model.GetSelectedText());
352 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, false);
353 EXPECT_EQ(3U, model.GetCursorPosition());
354 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, true);
355 EXPECT_EQ(base::WideToUTF16(L"b"), model.GetSelectedText());
357 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, true);
358 EXPECT_EQ(base::WideToUTF16(L"b"), model.GetSelectedText());
360 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, true);
361 EXPECT_EQ(base::WideToUTF16(L"a\x05E9" L"b"), model.GetSelectedText());
363 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_LEFT, false);
364 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true);
365 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true);
366 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, true);
367 EXPECT_EQ(base::WideToUTF16(L"a\x05E9"), model.GetSelectedText());
369 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_RIGHT, false);
370 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, true);
371 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, true);
372 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true);
373 EXPECT_EQ(base::WideToUTF16(L"\x05E9" L"b"), model.GetSelectedText());
375 model.ClearSelection();
376 EXPECT_EQ(base::string16(), model.GetSelectedText());
377 model.SelectAll(false);
378 EXPECT_EQ(base::WideToUTF16(L"a\x05E9" L"b"), model.GetSelectedText());
381 TEST_F(TextfieldModelTest, SelectionAndEdit) {
382 TextfieldModel model(NULL);
383 model.Append(base::ASCIIToUTF16("HELLO"));
384 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, false);
385 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true);
386 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true); // "EL"
387 EXPECT_TRUE(model.Backspace());
388 EXPECT_STR_EQ("HLO", model.text());
390 model.Append(base::ASCIIToUTF16("ILL"));
391 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true);
392 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true); // "LO"
393 EXPECT_TRUE(model.Delete());
394 EXPECT_STR_EQ("HILL", model.text());
395 EXPECT_EQ(1U, model.GetCursorPosition());
396 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true); // "I"
397 model.InsertChar('E');
398 EXPECT_STR_EQ("HELL", model.text());
399 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_LEFT, false);
400 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true); // "H"
401 model.ReplaceChar('B');
402 EXPECT_STR_EQ("BELL", model.text());
403 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_RIGHT, false);
404 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, true);
405 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, true); // "ELL"
406 model.ReplaceChar('E');
407 EXPECT_STR_EQ("BEE", model.text());
410 TEST_F(TextfieldModelTest, Word) {
411 TextfieldModel model(NULL);
412 model.Append(
413 base::ASCIIToUTF16("The answer to Life, the Universe, and Everything"));
414 model.MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_RIGHT, false);
415 EXPECT_EQ(3U, model.GetCursorPosition());
416 model.MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_RIGHT, false);
417 EXPECT_EQ(10U, model.GetCursorPosition());
418 model.MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_RIGHT, false);
419 model.MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_RIGHT, false);
420 EXPECT_EQ(18U, model.GetCursorPosition());
422 // Should passes the non word char ','
423 model.MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_RIGHT, true);
424 EXPECT_EQ(23U, model.GetCursorPosition());
425 EXPECT_STR_EQ(", the", model.GetSelectedText());
427 // Move to the end.
428 model.MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_RIGHT, true);
429 model.MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_RIGHT, true);
430 model.MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_RIGHT, true);
431 EXPECT_STR_EQ(", the Universe, and Everything", model.GetSelectedText());
432 // Should be safe to go next word at the end.
433 model.MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_RIGHT, true);
434 EXPECT_STR_EQ(", the Universe, and Everything", model.GetSelectedText());
435 model.InsertChar('2');
436 EXPECT_EQ(19U, model.GetCursorPosition());
438 // Now backwards.
439 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, false); // leave 2.
440 model.MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_LEFT, true);
441 EXPECT_EQ(14U, model.GetCursorPosition());
442 EXPECT_STR_EQ("Life", model.GetSelectedText());
443 model.MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_LEFT, true);
444 EXPECT_STR_EQ("to Life", model.GetSelectedText());
445 model.MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_LEFT, true);
446 model.MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_LEFT, true);
447 model.MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_LEFT, true); // Now at start.
448 EXPECT_STR_EQ("The answer to Life", model.GetSelectedText());
449 // Should be safe to go to the previous word at the beginning.
450 model.MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_LEFT, true);
451 EXPECT_STR_EQ("The answer to Life", model.GetSelectedText());
452 model.ReplaceChar('4');
453 EXPECT_EQ(base::string16(), model.GetSelectedText());
454 EXPECT_STR_EQ("42", model.text());
457 TEST_F(TextfieldModelTest, SetText) {
458 TextfieldModel model(NULL);
459 model.Append(base::ASCIIToUTF16("HELLO"));
460 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_RIGHT, false);
461 model.SetText(base::ASCIIToUTF16("GOODBYE"));
462 EXPECT_STR_EQ("GOODBYE", model.text());
463 // SetText move the cursor to the end of the new text.
464 EXPECT_EQ(7U, model.GetCursorPosition());
465 model.SelectAll(false);
466 EXPECT_STR_EQ("GOODBYE", model.GetSelectedText());
467 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_RIGHT, false);
468 EXPECT_EQ(7U, model.GetCursorPosition());
470 model.SetText(base::ASCIIToUTF16("BYE"));
471 // Setting shorter string moves the cursor to the end of the new string.
472 EXPECT_EQ(3U, model.GetCursorPosition());
473 EXPECT_EQ(base::string16(), model.GetSelectedText());
474 model.SetText(base::string16());
475 EXPECT_EQ(0U, model.GetCursorPosition());
478 TEST_F(TextfieldModelTest, Clipboard) {
479 ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
480 const base::string16 initial_clipboard_text =
481 base::ASCIIToUTF16("initial text");
482 ui::ScopedClipboardWriter(ui::CLIPBOARD_TYPE_COPY_PASTE)
483 .WriteText(initial_clipboard_text);
485 base::string16 clipboard_text;
486 TextfieldModel model(NULL);
487 model.Append(base::ASCIIToUTF16("HELLO WORLD"));
489 // Cut with an empty selection should do nothing.
490 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_RIGHT, false);
491 EXPECT_FALSE(model.Cut());
492 clipboard->ReadText(ui::CLIPBOARD_TYPE_COPY_PASTE, &clipboard_text);
493 EXPECT_EQ(initial_clipboard_text, clipboard_text);
494 EXPECT_STR_EQ("HELLO WORLD", model.text());
495 EXPECT_EQ(11U, model.GetCursorPosition());
497 // Copy with an empty selection should do nothing.
498 model.Copy();
499 clipboard->ReadText(ui::CLIPBOARD_TYPE_COPY_PASTE, &clipboard_text);
500 EXPECT_EQ(initial_clipboard_text, clipboard_text);
501 EXPECT_STR_EQ("HELLO WORLD", model.text());
502 EXPECT_EQ(11U, model.GetCursorPosition());
504 // Cut on obscured (password) text should do nothing.
505 model.render_text()->SetObscured(true);
506 model.SelectAll(false);
507 EXPECT_FALSE(model.Cut());
508 clipboard->ReadText(ui::CLIPBOARD_TYPE_COPY_PASTE, &clipboard_text);
509 EXPECT_EQ(initial_clipboard_text, clipboard_text);
510 EXPECT_STR_EQ("HELLO WORLD", model.text());
511 EXPECT_STR_EQ("HELLO WORLD", model.GetSelectedText());
513 // Copy on obscured (password) text should do nothing.
514 model.SelectAll(false);
515 EXPECT_FALSE(model.Copy());
516 clipboard->ReadText(ui::CLIPBOARD_TYPE_COPY_PASTE, &clipboard_text);
517 EXPECT_EQ(initial_clipboard_text, clipboard_text);
518 EXPECT_STR_EQ("HELLO WORLD", model.text());
519 EXPECT_STR_EQ("HELLO WORLD", model.GetSelectedText());
521 // Cut with non-empty selection.
522 model.render_text()->SetObscured(false);
523 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_RIGHT, false);
524 model.MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_LEFT, true);
525 EXPECT_TRUE(model.Cut());
526 clipboard->ReadText(ui::CLIPBOARD_TYPE_COPY_PASTE, &clipboard_text);
527 EXPECT_STR_EQ("WORLD", clipboard_text);
528 EXPECT_STR_EQ("HELLO ", model.text());
529 EXPECT_EQ(6U, model.GetCursorPosition());
531 // Copy with non-empty selection.
532 model.SelectAll(false);
533 EXPECT_TRUE(model.Copy());
534 clipboard->ReadText(ui::CLIPBOARD_TYPE_COPY_PASTE, &clipboard_text);
535 EXPECT_STR_EQ("HELLO ", clipboard_text);
536 EXPECT_STR_EQ("HELLO ", model.text());
537 EXPECT_EQ(6U, model.GetCursorPosition());
539 // Test that paste works regardless of the obscured bit.
540 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_RIGHT, false);
541 EXPECT_TRUE(model.Paste());
542 EXPECT_STR_EQ("HELLO HELLO ", model.text());
543 EXPECT_EQ(12U, model.GetCursorPosition());
544 model.render_text()->SetObscured(true);
545 EXPECT_TRUE(model.Paste());
546 EXPECT_STR_EQ("HELLO HELLO HELLO ", model.text());
547 EXPECT_EQ(18U, model.GetCursorPosition());
550 static void SelectWordTestVerifier(
551 const TextfieldModel& model,
552 const base::string16 &expected_selected_string,
553 size_t expected_cursor_pos) {
554 EXPECT_EQ(expected_selected_string, model.GetSelectedText());
555 EXPECT_EQ(expected_cursor_pos, model.GetCursorPosition());
558 TEST_F(TextfieldModelTest, SelectWordTest) {
559 TextfieldModel model(NULL);
560 model.Append(base::ASCIIToUTF16(" HELLO !! WO RLD "));
562 // Test when cursor is at the beginning.
563 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_LEFT, false);
564 model.SelectWord();
565 SelectWordTestVerifier(model, base::ASCIIToUTF16(" "), 2U);
567 // Test when cursor is at the beginning of a word.
568 MoveCursorTo(model, 2);
569 model.SelectWord();
570 SelectWordTestVerifier(model, base::ASCIIToUTF16("HELLO"), 7U);
572 // Test when cursor is at the end of a word.
573 MoveCursorTo(model, 15);
574 model.SelectWord();
575 SelectWordTestVerifier(model, base::ASCIIToUTF16(" "), 20U);
577 // Test when cursor is somewhere in a non-alpha-numeric fragment.
578 for (size_t cursor_pos = 8; cursor_pos < 13U; cursor_pos++) {
579 MoveCursorTo(model, cursor_pos);
580 model.SelectWord();
581 SelectWordTestVerifier(model, base::ASCIIToUTF16(" !! "), 13U);
584 // Test when cursor is somewhere in a whitespace fragment.
585 MoveCursorTo(model, 17);
586 model.SelectWord();
587 SelectWordTestVerifier(model, base::ASCIIToUTF16(" "), 20U);
589 // Test when cursor is at the end.
590 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_RIGHT, false);
591 model.SelectWord();
592 SelectWordTestVerifier(model, base::ASCIIToUTF16(" "), 24U);
595 // TODO(xji): temporarily disable in platform Win since the complex script
596 // characters and Chinese characters are turned into empty square due to font
597 // regression.
598 #if defined(OS_LINUX)
599 TEST_F(TextfieldModelTest, SelectWordTest_MixScripts) {
600 TextfieldModel model(NULL);
601 std::vector<WordAndCursor> word_and_cursor;
602 word_and_cursor.push_back(WordAndCursor(L"a\x05d0", 2));
603 word_and_cursor.push_back(WordAndCursor(L"a\x05d0", 2));
604 word_and_cursor.push_back(WordAndCursor(L"\x05d1\x05d2", 5));
605 word_and_cursor.push_back(WordAndCursor(L"\x05d1\x05d2", 5));
606 word_and_cursor.push_back(WordAndCursor(L" ", 3));
607 word_and_cursor.push_back(WordAndCursor(L"a\x05d0", 2));
608 word_and_cursor.push_back(WordAndCursor(L"\x0915\x094d\x0915", 9));
609 word_and_cursor.push_back(WordAndCursor(L"\x0915\x094d\x0915", 9));
610 word_and_cursor.push_back(WordAndCursor(L" ", 10));
611 word_and_cursor.push_back(WordAndCursor(L"\x4E2D\x56FD", 12));
612 word_and_cursor.push_back(WordAndCursor(L"\x4E2D\x56FD", 12));
613 word_and_cursor.push_back(WordAndCursor(L"\x82B1", 13));
614 word_and_cursor.push_back(WordAndCursor(L"\x5929", 14));
616 // The text consists of Ascii, Hebrew, Hindi with Virama sign, and Chinese.
617 model.SetText(base::WideToUTF16(L"a\x05d0 \x05d1\x05d2 \x0915\x094d\x0915 "
618 L"\x4E2D\x56FD\x82B1\x5929"));
619 for (size_t i = 0; i < word_and_cursor.size(); ++i) {
620 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_LEFT, false);
621 for (size_t j = 0; j < i; ++j)
622 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, false);
623 model.SelectWord();
624 SelectWordTestVerifier(model, base::WideToUTF16(word_and_cursor[i].word),
625 word_and_cursor[i].cursor);
628 #endif
630 TEST_F(TextfieldModelTest, RangeTest) {
631 TextfieldModel model(NULL);
632 model.Append(base::ASCIIToUTF16("HELLO WORLD"));
633 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_LEFT, false);
634 gfx::Range range = model.render_text()->selection();
635 EXPECT_TRUE(range.is_empty());
636 EXPECT_EQ(0U, range.start());
637 EXPECT_EQ(0U, range.end());
639 model.MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_RIGHT, true);
640 range = model.render_text()->selection();
641 EXPECT_FALSE(range.is_empty());
642 EXPECT_FALSE(range.is_reversed());
643 EXPECT_EQ(0U, range.start());
644 EXPECT_EQ(5U, range.end());
646 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, true);
647 range = model.render_text()->selection();
648 EXPECT_FALSE(range.is_empty());
649 EXPECT_EQ(0U, range.start());
650 EXPECT_EQ(4U, range.end());
652 model.MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_LEFT, true);
653 range = model.render_text()->selection();
654 EXPECT_TRUE(range.is_empty());
655 EXPECT_EQ(0U, range.start());
656 EXPECT_EQ(0U, range.end());
658 // now from the end.
659 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_RIGHT, false);
660 range = model.render_text()->selection();
661 EXPECT_TRUE(range.is_empty());
662 EXPECT_EQ(11U, range.start());
663 EXPECT_EQ(11U, range.end());
665 model.MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_LEFT, true);
666 range = model.render_text()->selection();
667 EXPECT_FALSE(range.is_empty());
668 EXPECT_TRUE(range.is_reversed());
669 EXPECT_EQ(11U, range.start());
670 EXPECT_EQ(6U, range.end());
672 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true);
673 range = model.render_text()->selection();
674 EXPECT_FALSE(range.is_empty());
675 EXPECT_TRUE(range.is_reversed());
676 EXPECT_EQ(11U, range.start());
677 EXPECT_EQ(7U, range.end());
679 model.MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_RIGHT, true);
680 range = model.render_text()->selection();
681 EXPECT_TRUE(range.is_empty());
682 EXPECT_EQ(11U, range.start());
683 EXPECT_EQ(11U, range.end());
685 // Select All
686 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_LEFT, true);
687 range = model.render_text()->selection();
688 EXPECT_FALSE(range.is_empty());
689 EXPECT_TRUE(range.is_reversed());
690 EXPECT_EQ(11U, range.start());
691 EXPECT_EQ(0U, range.end());
694 TEST_F(TextfieldModelTest, SelectRangeTest) {
695 TextfieldModel model(NULL);
696 model.Append(base::ASCIIToUTF16("HELLO WORLD"));
697 gfx::Range range(0, 6);
698 EXPECT_FALSE(range.is_reversed());
699 model.SelectRange(range);
700 EXPECT_STR_EQ("HELLO ", model.GetSelectedText());
702 range = gfx::Range(6, 1);
703 EXPECT_TRUE(range.is_reversed());
704 model.SelectRange(range);
705 EXPECT_STR_EQ("ELLO ", model.GetSelectedText());
707 range = gfx::Range(2, 1000);
708 EXPECT_FALSE(range.is_reversed());
709 model.SelectRange(range);
710 EXPECT_STR_EQ("LLO WORLD", model.GetSelectedText());
712 range = gfx::Range(1000, 3);
713 EXPECT_TRUE(range.is_reversed());
714 model.SelectRange(range);
715 EXPECT_STR_EQ("LO WORLD", model.GetSelectedText());
717 range = gfx::Range(0, 0);
718 EXPECT_TRUE(range.is_empty());
719 model.SelectRange(range);
720 EXPECT_TRUE(model.GetSelectedText().empty());
722 range = gfx::Range(3, 3);
723 EXPECT_TRUE(range.is_empty());
724 model.SelectRange(range);
725 EXPECT_TRUE(model.GetSelectedText().empty());
727 range = gfx::Range(1000, 100);
728 EXPECT_FALSE(range.is_empty());
729 model.SelectRange(range);
730 EXPECT_TRUE(model.GetSelectedText().empty());
732 range = gfx::Range(1000, 1000);
733 EXPECT_TRUE(range.is_empty());
734 model.SelectRange(range);
735 EXPECT_TRUE(model.GetSelectedText().empty());
738 TEST_F(TextfieldModelTest, SelectionTest) {
739 TextfieldModel model(NULL);
740 model.Append(base::ASCIIToUTF16("HELLO WORLD"));
741 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_LEFT, false);
742 gfx::Range selection = model.render_text()->selection();
743 EXPECT_EQ(gfx::Range(0), selection);
745 model.MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_RIGHT, true);
746 selection = model.render_text()->selection();
747 EXPECT_EQ(gfx::Range(0, 5), selection);
749 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, true);
750 selection = model.render_text()->selection();
751 EXPECT_EQ(gfx::Range(0, 4), selection);
753 model.MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_LEFT, true);
754 selection = model.render_text()->selection();
755 EXPECT_EQ(gfx::Range(0), selection);
757 // now from the end.
758 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_RIGHT, false);
759 selection = model.render_text()->selection();
760 EXPECT_EQ(gfx::Range(11), selection);
762 model.MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_LEFT, true);
763 selection = model.render_text()->selection();
764 EXPECT_EQ(gfx::Range(11, 6), selection);
766 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true);
767 selection = model.render_text()->selection();
768 EXPECT_EQ(gfx::Range(11, 7), selection);
770 model.MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_RIGHT, true);
771 selection = model.render_text()->selection();
772 EXPECT_EQ(gfx::Range(11), selection);
774 // Select All
775 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_LEFT, true);
776 selection = model.render_text()->selection();
777 EXPECT_EQ(gfx::Range(11, 0), selection);
780 TEST_F(TextfieldModelTest, SelectSelectionModelTest) {
781 TextfieldModel model(NULL);
782 model.Append(base::ASCIIToUTF16("HELLO WORLD"));
783 model.SelectSelectionModel(gfx::SelectionModel(gfx::Range(0, 6),
784 gfx::CURSOR_BACKWARD));
785 EXPECT_STR_EQ("HELLO ", model.GetSelectedText());
787 model.SelectSelectionModel(gfx::SelectionModel(gfx::Range(6, 1),
788 gfx::CURSOR_FORWARD));
789 EXPECT_STR_EQ("ELLO ", model.GetSelectedText());
791 model.SelectSelectionModel(gfx::SelectionModel(gfx::Range(2, 1000),
792 gfx::CURSOR_BACKWARD));
793 EXPECT_STR_EQ("LLO WORLD", model.GetSelectedText());
795 model.SelectSelectionModel(gfx::SelectionModel(gfx::Range(1000, 3),
796 gfx::CURSOR_FORWARD));
797 EXPECT_STR_EQ("LO WORLD", model.GetSelectedText());
799 model.SelectSelectionModel(gfx::SelectionModel(0, gfx::CURSOR_FORWARD));
800 EXPECT_TRUE(model.GetSelectedText().empty());
802 model.SelectSelectionModel(gfx::SelectionModel(3, gfx::CURSOR_FORWARD));
803 EXPECT_TRUE(model.GetSelectedText().empty());
805 model.SelectSelectionModel(gfx::SelectionModel(gfx::Range(1000, 100),
806 gfx::CURSOR_FORWARD));
807 EXPECT_TRUE(model.GetSelectedText().empty());
809 model.SelectSelectionModel(gfx::SelectionModel(1000, gfx::CURSOR_BACKWARD));
810 EXPECT_TRUE(model.GetSelectedText().empty());
813 TEST_F(TextfieldModelTest, CompositionTextTest) {
814 TextfieldModel model(this);
815 model.Append(base::ASCIIToUTF16("1234590"));
816 model.SelectRange(gfx::Range(5, 5));
817 EXPECT_FALSE(model.HasSelection());
818 EXPECT_EQ(5U, model.GetCursorPosition());
820 gfx::Range range;
821 model.GetTextRange(&range);
822 EXPECT_EQ(gfx::Range(0, 7), range);
824 ui::CompositionText composition;
825 composition.text = base::ASCIIToUTF16("678");
826 composition.underlines.push_back(ui::CompositionUnderline(0, 3, 0, false));
828 // Cursor should be at the end of composition when characters are just typed.
829 composition.selection = gfx::Range(3, 3);
830 model.SetCompositionText(composition);
831 EXPECT_TRUE(model.HasCompositionText());
832 EXPECT_FALSE(model.HasSelection());
834 // Cancel the composition.
835 model.CancelCompositionText();
836 composition_text_confirmed_or_cleared_ = false;
838 // Restart composition with targeting "67" in "678".
839 composition.selection = gfx::Range(0, 2);
840 composition.underlines.clear();
841 composition.underlines.push_back(ui::CompositionUnderline(0, 2, 0, true));
842 composition.underlines.push_back(ui::CompositionUnderline(2, 3, 0, false));
843 model.SetCompositionText(composition);
844 EXPECT_TRUE(model.HasCompositionText());
845 EXPECT_TRUE(model.HasSelection());
846 EXPECT_EQ(gfx::Range(5, 7), model.render_text()->selection());
848 model.GetTextRange(&range);
849 EXPECT_EQ(10U, range.end());
850 EXPECT_STR_EQ("1234567890", model.text());
852 model.GetCompositionTextRange(&range);
853 EXPECT_EQ(gfx::Range(5, 8), range);
854 // Check the composition text.
855 EXPECT_STR_EQ("456", model.GetTextFromRange(gfx::Range(3, 6)));
856 EXPECT_EQ(gfx::Range(5, 7), model.render_text()->selection());
858 EXPECT_FALSE(composition_text_confirmed_or_cleared_);
859 model.CancelCompositionText();
860 EXPECT_TRUE(composition_text_confirmed_or_cleared_);
861 composition_text_confirmed_or_cleared_ = false;
862 EXPECT_FALSE(model.HasCompositionText());
863 EXPECT_FALSE(model.HasSelection());
864 EXPECT_EQ(5U, model.GetCursorPosition());
866 model.SetCompositionText(composition);
867 EXPECT_STR_EQ("1234567890", model.text());
868 EXPECT_TRUE(model.SetText(base::ASCIIToUTF16("1234567890")));
869 EXPECT_TRUE(composition_text_confirmed_or_cleared_);
870 composition_text_confirmed_or_cleared_ = false;
871 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_RIGHT, false);
873 model.SetCompositionText(composition);
874 EXPECT_STR_EQ("1234567890678", model.text());
876 model.InsertText(base::UTF8ToUTF16("-"));
877 EXPECT_TRUE(composition_text_confirmed_or_cleared_);
878 composition_text_confirmed_or_cleared_ = false;
879 EXPECT_STR_EQ("1234567890-", model.text());
880 EXPECT_FALSE(model.HasCompositionText());
881 EXPECT_FALSE(model.HasSelection());
883 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, true);
884 EXPECT_STR_EQ("-", model.GetSelectedText());
885 model.SetCompositionText(composition);
886 EXPECT_STR_EQ("1234567890678", model.text());
888 model.ReplaceText(base::UTF8ToUTF16("-"));
889 EXPECT_TRUE(composition_text_confirmed_or_cleared_);
890 composition_text_confirmed_or_cleared_ = false;
891 EXPECT_STR_EQ("1234567890-", model.text());
892 EXPECT_FALSE(model.HasCompositionText());
893 EXPECT_FALSE(model.HasSelection());
895 model.SetCompositionText(composition);
896 model.Append(base::UTF8ToUTF16("-"));
897 EXPECT_TRUE(composition_text_confirmed_or_cleared_);
898 composition_text_confirmed_or_cleared_ = false;
899 EXPECT_STR_EQ("1234567890-678-", model.text());
901 model.SetCompositionText(composition);
902 model.Delete();
903 EXPECT_TRUE(composition_text_confirmed_or_cleared_);
904 composition_text_confirmed_or_cleared_ = false;
905 EXPECT_STR_EQ("1234567890-678-", model.text());
907 model.SetCompositionText(composition);
908 model.Backspace();
909 EXPECT_TRUE(composition_text_confirmed_or_cleared_);
910 composition_text_confirmed_or_cleared_ = false;
911 EXPECT_STR_EQ("1234567890-678-", model.text());
913 model.SetText(base::string16());
914 model.SetCompositionText(composition);
915 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, false);
916 EXPECT_TRUE(composition_text_confirmed_or_cleared_);
917 composition_text_confirmed_or_cleared_ = false;
918 EXPECT_STR_EQ("678", model.text());
919 EXPECT_EQ(2U, model.GetCursorPosition());
921 model.SetCompositionText(composition);
922 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, false);
923 EXPECT_TRUE(composition_text_confirmed_or_cleared_);
924 composition_text_confirmed_or_cleared_ = false;
925 EXPECT_STR_EQ("676788", model.text());
926 EXPECT_EQ(6U, model.GetCursorPosition());
928 model.SetCompositionText(composition);
929 model.MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_LEFT, false);
930 EXPECT_TRUE(composition_text_confirmed_or_cleared_);
931 composition_text_confirmed_or_cleared_ = false;
932 EXPECT_STR_EQ("676788678", model.text());
934 model.SetText(base::string16());
935 model.SetCompositionText(composition);
936 model.MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_RIGHT, false);
937 EXPECT_TRUE(composition_text_confirmed_or_cleared_);
938 composition_text_confirmed_or_cleared_ = false;
940 model.SetCompositionText(composition);
941 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_LEFT, true);
942 EXPECT_TRUE(composition_text_confirmed_or_cleared_);
943 composition_text_confirmed_or_cleared_ = false;
944 EXPECT_STR_EQ("678678", model.text());
946 model.SetCompositionText(composition);
947 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_RIGHT, false);
948 EXPECT_TRUE(composition_text_confirmed_or_cleared_);
949 composition_text_confirmed_or_cleared_ = false;
950 EXPECT_STR_EQ("678", model.text());
952 model.SetCompositionText(composition);
953 gfx::SelectionModel sel(
954 gfx::Range(model.render_text()->selection().start(), 0),
955 gfx::CURSOR_FORWARD);
956 model.MoveCursorTo(sel);
957 EXPECT_TRUE(composition_text_confirmed_or_cleared_);
958 composition_text_confirmed_or_cleared_ = false;
959 EXPECT_STR_EQ("678678", model.text());
961 model.SetCompositionText(composition);
962 model.SelectRange(gfx::Range(0, 3));
963 EXPECT_TRUE(composition_text_confirmed_or_cleared_);
964 composition_text_confirmed_or_cleared_ = false;
965 EXPECT_STR_EQ("678", model.text());
967 model.SetCompositionText(composition);
968 model.SelectAll(false);
969 EXPECT_TRUE(composition_text_confirmed_or_cleared_);
970 composition_text_confirmed_or_cleared_ = false;
971 EXPECT_STR_EQ("678", model.text());
973 model.SetCompositionText(composition);
974 model.SelectWord();
975 EXPECT_TRUE(composition_text_confirmed_or_cleared_);
976 composition_text_confirmed_or_cleared_ = false;
977 EXPECT_STR_EQ("678", model.text());
979 model.SetCompositionText(composition);
980 model.ClearSelection();
981 EXPECT_TRUE(composition_text_confirmed_or_cleared_);
982 composition_text_confirmed_or_cleared_ = false;
984 model.SetCompositionText(composition);
985 EXPECT_FALSE(model.Cut());
986 EXPECT_FALSE(composition_text_confirmed_or_cleared_);
989 TEST_F(TextfieldModelTest, UndoRedo_BasicTest) {
990 TextfieldModel model(NULL);
991 model.InsertChar('a');
992 EXPECT_FALSE(model.Redo()); // There is nothing to redo.
993 EXPECT_TRUE(model.Undo());
994 EXPECT_STR_EQ("", model.text());
995 EXPECT_TRUE(model.Redo());
996 EXPECT_STR_EQ("a", model.text());
998 // Continuous inserts are treated as one edit.
999 model.InsertChar('b');
1000 model.InsertChar('c');
1001 EXPECT_STR_EQ("abc", model.text());
1002 EXPECT_TRUE(model.Undo());
1003 EXPECT_STR_EQ("a", model.text());
1004 EXPECT_EQ(1U, model.GetCursorPosition());
1005 EXPECT_TRUE(model.Undo());
1006 EXPECT_STR_EQ("", model.text());
1007 EXPECT_EQ(0U, model.GetCursorPosition());
1009 // Undoing further shouldn't change the text.
1010 EXPECT_FALSE(model.Undo());
1011 EXPECT_STR_EQ("", model.text());
1012 EXPECT_FALSE(model.Undo());
1013 EXPECT_STR_EQ("", model.text());
1014 EXPECT_EQ(0U, model.GetCursorPosition());
1016 // Redoing to the latest text.
1017 EXPECT_TRUE(model.Redo());
1018 EXPECT_STR_EQ("a", model.text());
1019 EXPECT_EQ(1U, model.GetCursorPosition());
1020 EXPECT_TRUE(model.Redo());
1021 EXPECT_STR_EQ("abc", model.text());
1022 EXPECT_EQ(3U, model.GetCursorPosition());
1024 // Backspace ===============================
1025 EXPECT_TRUE(model.Backspace());
1026 EXPECT_STR_EQ("ab", model.text());
1027 EXPECT_TRUE(model.Undo());
1028 EXPECT_STR_EQ("abc", model.text());
1029 EXPECT_EQ(3U, model.GetCursorPosition());
1030 EXPECT_TRUE(model.Redo());
1031 EXPECT_STR_EQ("ab", model.text());
1032 EXPECT_EQ(2U, model.GetCursorPosition());
1033 // Continous backspaces are treated as one edit.
1034 EXPECT_TRUE(model.Backspace());
1035 EXPECT_TRUE(model.Backspace());
1036 EXPECT_STR_EQ("", model.text());
1037 // Extra backspace shouldn't affect the history.
1038 EXPECT_FALSE(model.Backspace());
1039 EXPECT_TRUE(model.Undo());
1040 EXPECT_STR_EQ("ab", model.text());
1041 EXPECT_EQ(2U, model.GetCursorPosition());
1042 EXPECT_TRUE(model.Undo());
1043 EXPECT_STR_EQ("abc", model.text());
1044 EXPECT_EQ(3U, model.GetCursorPosition());
1045 EXPECT_TRUE(model.Undo());
1046 EXPECT_STR_EQ("a", model.text());
1047 EXPECT_EQ(1U, model.GetCursorPosition());
1049 // Clear history
1050 model.ClearEditHistory();
1051 EXPECT_FALSE(model.Undo());
1052 EXPECT_FALSE(model.Redo());
1053 EXPECT_STR_EQ("a", model.text());
1054 EXPECT_EQ(1U, model.GetCursorPosition());
1056 // Delete ===============================
1057 model.SetText(base::ASCIIToUTF16("ABCDE"));
1058 model.ClearEditHistory();
1059 MoveCursorTo(model, 2);
1060 EXPECT_TRUE(model.Delete());
1061 EXPECT_STR_EQ("ABDE", model.text());
1062 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_LEFT, false);
1063 EXPECT_TRUE(model.Delete());
1064 EXPECT_STR_EQ("BDE", model.text());
1065 EXPECT_TRUE(model.Undo());
1066 EXPECT_STR_EQ("ABDE", model.text());
1067 EXPECT_EQ(0U, model.GetCursorPosition());
1068 EXPECT_TRUE(model.Undo());
1069 EXPECT_STR_EQ("ABCDE", model.text());
1070 EXPECT_EQ(2U, model.GetCursorPosition());
1071 EXPECT_TRUE(model.Redo());
1072 EXPECT_STR_EQ("ABDE", model.text());
1073 EXPECT_EQ(2U, model.GetCursorPosition());
1074 // Continous deletes are treated as one edit.
1075 EXPECT_TRUE(model.Delete());
1076 EXPECT_TRUE(model.Delete());
1077 EXPECT_STR_EQ("AB", model.text());
1078 EXPECT_TRUE(model.Undo());
1079 EXPECT_STR_EQ("ABDE", model.text());
1080 EXPECT_EQ(2U, model.GetCursorPosition());
1081 EXPECT_TRUE(model.Redo());
1082 EXPECT_STR_EQ("AB", model.text());
1083 EXPECT_EQ(2U, model.GetCursorPosition());
1086 TEST_F(TextfieldModelTest, UndoRedo_SetText) {
1087 // This is to test the undo/redo behavior of omnibox.
1088 TextfieldModel model(NULL);
1089 model.InsertChar('w');
1090 EXPECT_STR_EQ("w", model.text());
1091 EXPECT_EQ(1U, model.GetCursorPosition());
1092 model.SetText(base::ASCIIToUTF16("www.google.com"));
1093 EXPECT_EQ(14U, model.GetCursorPosition());
1094 EXPECT_STR_EQ("www.google.com", model.text());
1095 model.SelectRange(gfx::Range(14, 1));
1096 model.InsertChar('w');
1097 EXPECT_STR_EQ("ww", model.text());
1098 model.SetText(base::ASCIIToUTF16("www.google.com"));
1099 model.SelectRange(gfx::Range(14, 2));
1100 model.InsertChar('w');
1101 EXPECT_STR_EQ("www", model.text());
1102 model.SetText(base::ASCIIToUTF16("www.google.com"));
1103 model.SelectRange(gfx::Range(14, 3));
1104 model.InsertChar('.');
1105 EXPECT_STR_EQ("www.", model.text());
1106 model.SetText(base::ASCIIToUTF16("www.google.com"));
1107 model.SelectRange(gfx::Range(14, 4));
1108 model.InsertChar('y');
1109 EXPECT_STR_EQ("www.y", model.text());
1110 model.SetText(base::ASCIIToUTF16("www.youtube.com"));
1111 EXPECT_STR_EQ("www.youtube.com", model.text());
1112 EXPECT_EQ(15U, model.GetCursorPosition());
1114 EXPECT_TRUE(model.Undo());
1115 EXPECT_STR_EQ("www.google.com", model.text());
1116 EXPECT_EQ(4U, model.GetCursorPosition());
1117 EXPECT_TRUE(model.Undo());
1118 EXPECT_STR_EQ("www.google.com", model.text());
1119 EXPECT_EQ(3U, model.GetCursorPosition());
1120 EXPECT_TRUE(model.Undo());
1121 EXPECT_STR_EQ("www.google.com", model.text());
1122 EXPECT_EQ(2U, model.GetCursorPosition());
1123 EXPECT_TRUE(model.Undo());
1124 EXPECT_STR_EQ("www.google.com", model.text());
1125 EXPECT_EQ(1U, model.GetCursorPosition());
1126 EXPECT_TRUE(model.Undo());
1127 EXPECT_STR_EQ("", model.text());
1128 EXPECT_EQ(0U, model.GetCursorPosition());
1129 EXPECT_FALSE(model.Undo());
1130 EXPECT_TRUE(model.Redo());
1131 EXPECT_STR_EQ("www.google.com", model.text());
1132 EXPECT_EQ(1U, model.GetCursorPosition());
1133 EXPECT_TRUE(model.Redo());
1134 EXPECT_STR_EQ("www.google.com", model.text());
1135 EXPECT_EQ(2U, model.GetCursorPosition());
1136 EXPECT_TRUE(model.Redo());
1137 EXPECT_STR_EQ("www.google.com", model.text());
1138 EXPECT_EQ(3U, model.GetCursorPosition());
1139 EXPECT_TRUE(model.Redo());
1140 EXPECT_STR_EQ("www.google.com", model.text());
1141 EXPECT_EQ(4U, model.GetCursorPosition());
1142 EXPECT_TRUE(model.Redo());
1143 EXPECT_STR_EQ("www.youtube.com", model.text());
1144 EXPECT_EQ(5U, model.GetCursorPosition());
1145 EXPECT_FALSE(model.Redo());
1148 TEST_F(TextfieldModelTest, UndoRedo_BackspaceThenSetText) {
1149 // This is to test the undo/redo behavior of omnibox.
1150 TextfieldModel model(NULL);
1151 model.InsertChar('w');
1152 EXPECT_STR_EQ("w", model.text());
1153 EXPECT_EQ(1U, model.GetCursorPosition());
1154 model.SetText(base::ASCIIToUTF16("www.google.com"));
1155 EXPECT_EQ(14U, model.GetCursorPosition());
1156 EXPECT_STR_EQ("www.google.com", model.text());
1157 model.SetText(base::ASCIIToUTF16("www.google.com")); // Confirm the text.
1158 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_RIGHT, false);
1159 EXPECT_EQ(14U, model.GetCursorPosition());
1160 EXPECT_TRUE(model.Backspace());
1161 EXPECT_TRUE(model.Backspace());
1162 EXPECT_STR_EQ("www.google.c", model.text());
1163 // Autocomplete sets the text.
1164 model.SetText(base::ASCIIToUTF16("www.google.com/search=www.google.c"));
1165 EXPECT_STR_EQ("www.google.com/search=www.google.c", model.text());
1166 EXPECT_TRUE(model.Undo());
1167 EXPECT_STR_EQ("www.google.c", model.text());
1168 EXPECT_TRUE(model.Undo());
1169 EXPECT_STR_EQ("www.google.com", model.text());
1172 TEST_F(TextfieldModelTest, UndoRedo_CutCopyPasteTest) {
1173 TextfieldModel model(NULL);
1174 model.SetText(base::ASCIIToUTF16("ABCDE"));
1175 EXPECT_FALSE(model.Redo()); // There is nothing to redo.
1176 // Test Cut.
1177 model.SelectRange(gfx::Range(1, 3));
1178 model.Cut();
1179 EXPECT_STR_EQ("ADE", model.text());
1180 EXPECT_EQ(1U, model.GetCursorPosition());
1181 EXPECT_TRUE(model.Undo());
1182 EXPECT_STR_EQ("ABCDE", model.text());
1183 EXPECT_EQ(3U, model.GetCursorPosition());
1184 EXPECT_TRUE(model.Undo());
1185 EXPECT_STR_EQ("", model.text());
1186 EXPECT_EQ(0U, model.GetCursorPosition());
1187 EXPECT_FALSE(model.Undo()); // There is no more to undo.
1188 EXPECT_STR_EQ("", model.text());
1189 EXPECT_TRUE(model.Redo());
1190 EXPECT_STR_EQ("ABCDE", model.text());
1191 EXPECT_EQ(5U, model.GetCursorPosition());
1192 EXPECT_TRUE(model.Redo());
1193 EXPECT_STR_EQ("ADE", model.text());
1194 EXPECT_EQ(1U, model.GetCursorPosition());
1195 EXPECT_FALSE(model.Redo()); // There is no more to redo.
1196 EXPECT_STR_EQ("ADE", model.text());
1198 model.Paste();
1199 model.Paste();
1200 model.Paste();
1201 EXPECT_STR_EQ("ABCBCBCDE", model.text());
1202 EXPECT_EQ(7U, model.GetCursorPosition());
1203 EXPECT_TRUE(model.Undo());
1204 EXPECT_STR_EQ("ABCBCDE", model.text());
1205 EXPECT_EQ(5U, model.GetCursorPosition());
1206 EXPECT_TRUE(model.Undo());
1207 EXPECT_STR_EQ("ABCDE", model.text());
1208 EXPECT_EQ(3U, model.GetCursorPosition());
1209 EXPECT_TRUE(model.Undo());
1210 EXPECT_STR_EQ("ADE", model.text());
1211 EXPECT_EQ(1U, model.GetCursorPosition());
1212 EXPECT_TRUE(model.Undo());
1213 EXPECT_STR_EQ("ABCDE", model.text());
1214 EXPECT_EQ(3U, model.GetCursorPosition());
1215 EXPECT_TRUE(model.Undo());
1216 EXPECT_STR_EQ("", model.text());
1217 EXPECT_EQ(0U, model.GetCursorPosition());
1218 EXPECT_FALSE(model.Undo());
1219 EXPECT_STR_EQ("", model.text());
1220 EXPECT_TRUE(model.Redo());
1221 EXPECT_STR_EQ("ABCDE", model.text());
1222 EXPECT_EQ(5U, model.GetCursorPosition());
1224 // Test Redo.
1225 EXPECT_TRUE(model.Redo());
1226 EXPECT_STR_EQ("ADE", model.text());
1227 EXPECT_EQ(1U, model.GetCursorPosition());
1228 EXPECT_TRUE(model.Redo());
1229 EXPECT_STR_EQ("ABCDE", model.text());
1230 EXPECT_EQ(3U, model.GetCursorPosition());
1231 EXPECT_TRUE(model.Redo());
1232 EXPECT_STR_EQ("ABCBCDE", model.text());
1233 EXPECT_EQ(5U, model.GetCursorPosition());
1234 EXPECT_TRUE(model.Redo());
1235 EXPECT_STR_EQ("ABCBCBCDE", model.text());
1236 EXPECT_EQ(7U, model.GetCursorPosition());
1237 EXPECT_FALSE(model.Redo());
1239 // Test using SelectRange.
1240 model.SelectRange(gfx::Range(1, 3));
1241 EXPECT_TRUE(model.Cut());
1242 EXPECT_STR_EQ("ABCBCDE", model.text());
1243 EXPECT_EQ(1U, model.GetCursorPosition());
1244 model.SelectRange(gfx::Range(1, 1));
1245 EXPECT_FALSE(model.Cut());
1246 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_RIGHT, false);
1247 EXPECT_TRUE(model.Paste());
1248 EXPECT_STR_EQ("ABCBCDEBC", model.text());
1249 EXPECT_EQ(9U, model.GetCursorPosition());
1250 EXPECT_TRUE(model.Undo());
1251 EXPECT_STR_EQ("ABCBCDE", model.text());
1252 EXPECT_EQ(7U, model.GetCursorPosition());
1253 // An empty cut shouldn't create an edit.
1254 EXPECT_TRUE(model.Undo());
1255 EXPECT_STR_EQ("ABCBCBCDE", model.text());
1256 EXPECT_EQ(3U, model.GetCursorPosition());
1258 // Test Copy.
1259 ResetModel(&model);
1260 model.SetText(base::ASCIIToUTF16("12345"));
1261 EXPECT_STR_EQ("12345", model.text());
1262 EXPECT_EQ(5U, model.GetCursorPosition());
1263 model.SelectRange(gfx::Range(1, 3));
1264 model.Copy(); // Copy "23".
1265 EXPECT_STR_EQ("12345", model.text());
1266 EXPECT_EQ(3U, model.GetCursorPosition());
1267 model.Paste(); // Paste "23" into "23".
1268 EXPECT_STR_EQ("12345", model.text());
1269 EXPECT_EQ(3U, model.GetCursorPosition());
1270 model.Paste();
1271 EXPECT_STR_EQ("1232345", model.text());
1272 EXPECT_EQ(5U, model.GetCursorPosition());
1273 EXPECT_TRUE(model.Undo());
1274 EXPECT_STR_EQ("12345", model.text());
1275 EXPECT_EQ(3U, model.GetCursorPosition());
1276 // TODO(oshima): Change the return type from bool to enum.
1277 EXPECT_FALSE(model.Undo()); // No text change.
1278 EXPECT_STR_EQ("12345", model.text());
1279 EXPECT_EQ(3U, model.GetCursorPosition());
1280 EXPECT_TRUE(model.Undo());
1281 EXPECT_STR_EQ("", model.text());
1282 EXPECT_FALSE(model.Undo());
1283 // Test Redo.
1284 EXPECT_TRUE(model.Redo());
1285 EXPECT_STR_EQ("12345", model.text());
1286 EXPECT_EQ(5U, model.GetCursorPosition());
1287 EXPECT_TRUE(model.Redo());
1288 EXPECT_STR_EQ("12345", model.text()); // For 1st paste
1289 EXPECT_EQ(3U, model.GetCursorPosition());
1290 EXPECT_TRUE(model.Redo());
1291 EXPECT_STR_EQ("1232345", model.text());
1292 EXPECT_EQ(5U, model.GetCursorPosition());
1293 EXPECT_FALSE(model.Redo());
1294 EXPECT_STR_EQ("1232345", model.text());
1296 // Test using SelectRange.
1297 model.SelectRange(gfx::Range(1, 3));
1298 model.Copy();
1299 EXPECT_STR_EQ("1232345", model.text());
1300 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_RIGHT, false);
1301 EXPECT_TRUE(model.Paste());
1302 EXPECT_STR_EQ("123234523", model.text());
1303 EXPECT_EQ(9U, model.GetCursorPosition());
1304 EXPECT_TRUE(model.Undo());
1305 EXPECT_STR_EQ("1232345", model.text());
1306 EXPECT_EQ(7U, model.GetCursorPosition());
1309 TEST_F(TextfieldModelTest, UndoRedo_CursorTest) {
1310 TextfieldModel model(NULL);
1311 model.InsertChar('a');
1312 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, false);
1313 model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, false);
1314 model.InsertChar('b');
1315 // Moving the cursor shouldn't create a new edit.
1316 EXPECT_STR_EQ("ab", model.text());
1317 EXPECT_FALSE(model.Redo());
1318 EXPECT_TRUE(model.Undo());
1319 EXPECT_STR_EQ("", model.text());
1320 EXPECT_FALSE(model.Undo());
1321 EXPECT_STR_EQ("", model.text());
1322 EXPECT_TRUE(model.Redo());
1323 EXPECT_STR_EQ("ab", model.text());
1324 EXPECT_EQ(2U, model.GetCursorPosition());
1325 EXPECT_FALSE(model.Redo());
1328 void RunInsertReplaceTest(TextfieldModel& model) {
1329 const bool reverse = model.render_text()->selection().is_reversed();
1330 model.InsertChar('1');
1331 model.InsertChar('2');
1332 model.InsertChar('3');
1333 EXPECT_STR_EQ("a123d", model.text());
1334 EXPECT_EQ(4U, model.GetCursorPosition());
1335 EXPECT_TRUE(model.Undo());
1336 EXPECT_STR_EQ("abcd", model.text());
1337 EXPECT_EQ(reverse ? 1U : 3U, model.GetCursorPosition());
1338 EXPECT_TRUE(model.Undo());
1339 EXPECT_STR_EQ("", model.text());
1340 EXPECT_EQ(0U, model.GetCursorPosition());
1341 EXPECT_FALSE(model.Undo());
1342 EXPECT_TRUE(model.Redo());
1343 EXPECT_STR_EQ("abcd", model.text());
1344 EXPECT_EQ(4U, model.GetCursorPosition());
1345 EXPECT_TRUE(model.Redo());
1346 EXPECT_STR_EQ("a123d", model.text());
1347 EXPECT_EQ(4U, model.GetCursorPosition());
1348 EXPECT_FALSE(model.Redo());
1351 void RunOverwriteReplaceTest(TextfieldModel& model) {
1352 const bool reverse = model.render_text()->selection().is_reversed();
1353 model.ReplaceChar('1');
1354 model.ReplaceChar('2');
1355 model.ReplaceChar('3');
1356 model.ReplaceChar('4');
1357 EXPECT_STR_EQ("a1234", model.text());
1358 EXPECT_EQ(5U, model.GetCursorPosition());
1359 EXPECT_TRUE(model.Undo());
1360 EXPECT_STR_EQ("abcd", model.text());
1361 EXPECT_EQ(reverse ? 1U : 3U, model.GetCursorPosition());
1362 EXPECT_TRUE(model.Undo());
1363 EXPECT_STR_EQ("", model.text());
1364 EXPECT_EQ(0U, model.GetCursorPosition());
1365 EXPECT_FALSE(model.Undo());
1366 EXPECT_TRUE(model.Redo());
1367 EXPECT_STR_EQ("abcd", model.text());
1368 EXPECT_EQ(4U, model.GetCursorPosition());
1369 EXPECT_TRUE(model.Redo());
1370 EXPECT_STR_EQ("a1234", model.text());
1371 EXPECT_EQ(5U, model.GetCursorPosition());
1372 EXPECT_FALSE(model.Redo());
1375 TEST_F(TextfieldModelTest, UndoRedo_ReplaceTest) {
1377 SCOPED_TRACE("Select forwards and insert.");
1378 TextfieldModel model(NULL);
1379 model.SetText(base::ASCIIToUTF16("abcd"));
1380 model.SelectRange(gfx::Range(1, 3));
1381 RunInsertReplaceTest(model);
1384 SCOPED_TRACE("Select reversed and insert.");
1385 TextfieldModel model(NULL);
1386 model.SetText(base::ASCIIToUTF16("abcd"));
1387 model.SelectRange(gfx::Range(3, 1));
1388 RunInsertReplaceTest(model);
1391 SCOPED_TRACE("Select forwards and overwrite.");
1392 TextfieldModel model(NULL);
1393 model.SetText(base::ASCIIToUTF16("abcd"));
1394 model.SelectRange(gfx::Range(1, 3));
1395 RunOverwriteReplaceTest(model);
1398 SCOPED_TRACE("Select reversed and overwrite.");
1399 TextfieldModel model(NULL);
1400 model.SetText(base::ASCIIToUTF16("abcd"));
1401 model.SelectRange(gfx::Range(3, 1));
1402 RunOverwriteReplaceTest(model);
1406 TEST_F(TextfieldModelTest, UndoRedo_CompositionText) {
1407 TextfieldModel model(NULL);
1409 ui::CompositionText composition;
1410 composition.text = base::ASCIIToUTF16("abc");
1411 composition.underlines.push_back(ui::CompositionUnderline(0, 3, 0, false));
1412 composition.selection = gfx::Range(2, 3);
1414 model.SetText(base::ASCIIToUTF16("ABCDE"));
1415 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_RIGHT, false);
1416 model.InsertChar('x');
1417 EXPECT_STR_EQ("ABCDEx", model.text());
1418 EXPECT_TRUE(model.Undo()); // set composition should forget undone edit.
1419 model.SetCompositionText(composition);
1420 EXPECT_TRUE(model.HasCompositionText());
1421 EXPECT_TRUE(model.HasSelection());
1422 EXPECT_STR_EQ("ABCDEabc", model.text());
1424 // Confirm the composition.
1425 model.ConfirmCompositionText();
1426 EXPECT_STR_EQ("ABCDEabc", model.text());
1427 EXPECT_TRUE(model.Undo());
1428 EXPECT_STR_EQ("ABCDE", model.text());
1429 EXPECT_TRUE(model.Undo());
1430 EXPECT_STR_EQ("", model.text());
1431 EXPECT_TRUE(model.Redo());
1432 EXPECT_STR_EQ("ABCDE", model.text());
1433 EXPECT_TRUE(model.Redo());
1434 EXPECT_STR_EQ("ABCDEabc", model.text());
1435 EXPECT_FALSE(model.Redo());
1437 // Cancel the composition.
1438 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_LEFT, false);
1439 model.SetCompositionText(composition);
1440 EXPECT_STR_EQ("abcABCDEabc", model.text());
1441 model.CancelCompositionText();
1442 EXPECT_STR_EQ("ABCDEabc", model.text());
1443 EXPECT_FALSE(model.Redo());
1444 EXPECT_STR_EQ("ABCDEabc", model.text());
1445 EXPECT_TRUE(model.Undo());
1446 EXPECT_STR_EQ("ABCDE", model.text());
1447 EXPECT_TRUE(model.Redo());
1448 EXPECT_STR_EQ("ABCDEabc", model.text());
1449 EXPECT_FALSE(model.Redo());
1451 // Call SetText with the same text as the result.
1452 ResetModel(&model);
1453 model.SetText(base::ASCIIToUTF16("ABCDE"));
1454 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_RIGHT, false);
1455 model.SetCompositionText(composition);
1456 EXPECT_STR_EQ("ABCDEabc", model.text());
1457 model.SetText(base::ASCIIToUTF16("ABCDEabc"));
1458 EXPECT_STR_EQ("ABCDEabc", model.text());
1459 EXPECT_TRUE(model.Undo());
1460 EXPECT_STR_EQ("ABCDE", model.text());
1461 EXPECT_TRUE(model.Redo());
1462 EXPECT_STR_EQ("ABCDEabc", model.text());
1463 EXPECT_FALSE(model.Redo());
1465 // Call SetText with a different result; the composition should be forgotten.
1466 ResetModel(&model);
1467 model.SetText(base::ASCIIToUTF16("ABCDE"));
1468 model.MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_RIGHT, false);
1469 model.SetCompositionText(composition);
1470 EXPECT_STR_EQ("ABCDEabc", model.text());
1471 model.SetText(base::ASCIIToUTF16("1234"));
1472 EXPECT_STR_EQ("1234", model.text());
1473 EXPECT_TRUE(model.Undo());
1474 EXPECT_STR_EQ("ABCDE", model.text());
1475 EXPECT_TRUE(model.Redo());
1476 EXPECT_STR_EQ("1234", model.text());
1477 EXPECT_FALSE(model.Redo());
1479 // TODO(oshima): Test the behavior with an IME.
1482 } // namespace views