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.
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"
23 #include "base/win/windows_version.h"
26 #define EXPECT_STR_EQ(ascii, utf16) EXPECT_EQ(base::ASCIIToUTF16(ascii), utf16)
30 struct WordAndCursor
{
31 WordAndCursor(const wchar_t* w
, size_t c
) : word(w
), cursor(c
) {}
37 void MoveCursorTo(views::TextfieldModel
& model
, size_t pos
) {
38 model
.MoveCursorTo(gfx::SelectionModel(pos
, gfx::CURSOR_FORWARD
));
45 class TextfieldModelTest
: public ViewsTestBase
,
46 public TextfieldModel::Delegate
{
50 composition_text_confirmed_or_cleared_(false) {
53 void OnCompositionTextConfirmedOrCleared() override
{
54 composition_text_confirmed_or_cleared_
= true;
58 void ResetModel(TextfieldModel
* model
) const {
59 model
->SetText(base::string16());
60 model
->ClearEditHistory();
63 bool composition_text_confirmed_or_cleared_
;
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"),
121 MoveCursorTo(model
, 1);
122 model
.InsertChar(0x05f0);
123 EXPECT_EQ(base::WideToUTF16(L
"\x05d0\x05f0\x05d1\x05d2\x05e0\x05e1\x05e2"),
126 // Replace "\x05d1" with "\x05f1".
127 model
.ReplaceChar(0x05f1);
128 EXPECT_EQ(base::WideToUTF16(L
"\x05d0\x05f0\x5f1\x05d2\x05e0\x05e1\x05e2"),
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"),
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;
145 on_windows_xp
= base::win::GetVersion() < base::win::VERSION_VISTA
;
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"),
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"),
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"),
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"),
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.
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());
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.
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"),
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
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);
335 base::WideToUTF16(L
"abc\x05E9\x05BC\x05C1\x05B8\x05E0\x05B8" L
"def"),
336 model
.GetSelectedText());
339 // In case of "aBc", this test shows how to select "aB" or "Bc", assume 'B' is
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
);
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());
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());
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.
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);
565 SelectWordTestVerifier(model
, base::ASCIIToUTF16(" "), 2U);
567 // Test when cursor is at the beginning of a word.
568 MoveCursorTo(model
, 2);
570 SelectWordTestVerifier(model
, base::ASCIIToUTF16("HELLO"), 7U);
572 // Test when cursor is at the end of a word.
573 MoveCursorTo(model
, 15);
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
);
581 SelectWordTestVerifier(model
, base::ASCIIToUTF16(" !! "), 13U);
584 // Test when cursor is somewhere in a whitespace fragment.
585 MoveCursorTo(model
, 17);
587 SelectWordTestVerifier(model
, base::ASCIIToUTF16(" "), 20U);
589 // Test when cursor is at the end.
590 model
.MoveCursor(gfx::LINE_BREAK
, gfx::CURSOR_RIGHT
, false);
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
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);
624 SelectWordTestVerifier(model
, base::WideToUTF16(word_and_cursor
[i
].word
),
625 word_and_cursor
[i
].cursor
);
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());
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());
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
);
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
);
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());
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
);
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
);
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
);
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());
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.
1177 model
.SelectRange(gfx::Range(1, 3));
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());
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());
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());
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());
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());
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));
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.
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.
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