Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / ui / views / controls / textfield / textfield_model_unittest.cc
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.
4
5 #include <vector>
6
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"
21
22 #if defined(OS_WIN)
23 #include "base/win/windows_version.h"
24 #endif
25
26 #define EXPECT_STR_EQ(ascii, utf16) EXPECT_EQ(base::ASCIIToUTF16(ascii), utf16)
27
28 namespace {
29
30 struct WordAndCursor {
31   WordAndCursor(const wchar_t* w, size_t c) : word(w), cursor(c) {}
32
33   const wchar_t* word;
34   size_t cursor;
35 };
36
37 void MoveCursorTo(views::TextfieldModel& model, size_t pos) {
38   model.MoveCursorTo(gfx::SelectionModel(pos, gfx::CURSOR_FORWARD));
39 }
40
41 }  // namespace
42
43 namespace views {
44
45 class TextfieldModelTest : public ViewsTestBase,
46                            public TextfieldModel::Delegate {
47  public:
48   TextfieldModelTest()
49       : ViewsTestBase(),
50         composition_text_confirmed_or_cleared_(false) {
51   }
52
53   void OnCompositionTextConfirmedOrCleared() override {
54     composition_text_confirmed_or_cleared_ = true;
55   }
56
57  protected:
58   void ResetModel(TextfieldModel* model) const {
59     model->SetText(base::string16());
60     model->ClearEditHistory();
61   }
62
63   bool composition_text_confirmed_or_cleared_;
64
65  private:
66   DISALLOW_COPY_AND_ASSIGN(TextfieldModelTest);
67 };
68
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());
76
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());
86
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());
94
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());
105
106   MoveCursorTo(model, 5);
107   model.ReplaceText(base::ASCIIToUTF16(" WOR"));
108   EXPECT_STR_EQ("HELLO WORL", model.text());
109 }
110
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());
119
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());
125
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());
130
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());
139 }
140
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
147
148   TextfieldModel model(NULL);
149
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());
156
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());
161
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());
168
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());
180   }
181
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
197
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());
202
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());
208   }
209
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
218
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());
227
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());
235 }
236
237 TEST_F(TextfieldModelTest, EmptyString) {
238   TextfieldModel model(NULL);
239   EXPECT_EQ(base::string16(), model.text());
240   EXPECT_EQ(base::string16(), model.GetSelectedText());
241
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());
246
247   EXPECT_EQ(base::string16(), model.GetSelectedText());
248
249   EXPECT_FALSE(model.Delete());
250   EXPECT_FALSE(model.Backspace());
251 }
252
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());
261
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());
268
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());
273
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());
278
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());
287
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());
295 }
296
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);
312
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());
316
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());
321
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());
325
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());
330
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
338
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());
345
346   model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true);
347   EXPECT_EQ(base::WideToUTF16(L"a"), model.GetSelectedText());
348
349   model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true);
350   EXPECT_EQ(base::WideToUTF16(L"a\x05E9" L"b"), model.GetSelectedText());
351
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());
356
357   model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, true);
358   EXPECT_EQ(base::WideToUTF16(L"b"), model.GetSelectedText());
359
360   model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, true);
361   EXPECT_EQ(base::WideToUTF16(L"a\x05E9" L"b"), model.GetSelectedText());
362
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());
368
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());
374
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());
379 }
380
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());
389
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());
408 }
409
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());
421
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());
426
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());
437
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());
455 }
456
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());
469
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());
476 }
477
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);
484
485   base::string16 clipboard_text;
486   TextfieldModel model(NULL);
487   model.Append(base::ASCIIToUTF16("HELLO WORLD"));
488
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());
496
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());
503
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());
512
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());
520
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());
530
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());
538
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());
548 }
549
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());
556 }
557
558 TEST_F(TextfieldModelTest, SelectWordTest) {
559   TextfieldModel model(NULL);
560   model.Append(base::ASCIIToUTF16("  HELLO  !!  WO     RLD "));
561
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);
566
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);
571
572   // Test when cursor is at the end of a word.
573   MoveCursorTo(model, 15);
574   model.SelectWord();
575   SelectWordTestVerifier(model, base::ASCIIToUTF16("     "), 20U);
576
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);
582   }
583
584   // Test when cursor is somewhere in a whitespace fragment.
585   MoveCursorTo(model, 17);
586   model.SelectWord();
587   SelectWordTestVerifier(model, base::ASCIIToUTF16("     "), 20U);
588
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);
593 }
594
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));
615
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);
626   }
627 }
628 #endif
629
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());
638
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());
645
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());
651
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());
657
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());
664
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());
671
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());
678
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());
684
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());
692 }
693
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());
701
702   range = gfx::Range(6, 1);
703   EXPECT_TRUE(range.is_reversed());
704   model.SelectRange(range);
705   EXPECT_STR_EQ("ELLO ", model.GetSelectedText());
706
707   range = gfx::Range(2, 1000);
708   EXPECT_FALSE(range.is_reversed());
709   model.SelectRange(range);
710   EXPECT_STR_EQ("LLO WORLD", model.GetSelectedText());
711
712   range = gfx::Range(1000, 3);
713   EXPECT_TRUE(range.is_reversed());
714   model.SelectRange(range);
715   EXPECT_STR_EQ("LO WORLD", model.GetSelectedText());
716
717   range = gfx::Range(0, 0);
718   EXPECT_TRUE(range.is_empty());
719   model.SelectRange(range);
720   EXPECT_TRUE(model.GetSelectedText().empty());
721
722   range = gfx::Range(3, 3);
723   EXPECT_TRUE(range.is_empty());
724   model.SelectRange(range);
725   EXPECT_TRUE(model.GetSelectedText().empty());
726
727   range = gfx::Range(1000, 100);
728   EXPECT_FALSE(range.is_empty());
729   model.SelectRange(range);
730   EXPECT_TRUE(model.GetSelectedText().empty());
731
732   range = gfx::Range(1000, 1000);
733   EXPECT_TRUE(range.is_empty());
734   model.SelectRange(range);
735   EXPECT_TRUE(model.GetSelectedText().empty());
736 }
737
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);
744
745   model.MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_RIGHT, true);
746   selection = model.render_text()->selection();
747   EXPECT_EQ(gfx::Range(0, 5), selection);
748
749   model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, true);
750   selection = model.render_text()->selection();
751   EXPECT_EQ(gfx::Range(0, 4), selection);
752
753   model.MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_LEFT, true);
754   selection = model.render_text()->selection();
755   EXPECT_EQ(gfx::Range(0), selection);
756
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);
761
762   model.MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_LEFT, true);
763   selection = model.render_text()->selection();
764   EXPECT_EQ(gfx::Range(11, 6), selection);
765
766   model.MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true);
767   selection = model.render_text()->selection();
768   EXPECT_EQ(gfx::Range(11, 7), selection);
769
770   model.MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_RIGHT, true);
771   selection = model.render_text()->selection();
772   EXPECT_EQ(gfx::Range(11), selection);
773
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);
778 }
779
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());
786
787   model.SelectSelectionModel(gfx::SelectionModel(gfx::Range(6, 1),
788       gfx::CURSOR_FORWARD));
789   EXPECT_STR_EQ("ELLO ", model.GetSelectedText());
790
791   model.SelectSelectionModel(gfx::SelectionModel(gfx::Range(2, 1000),
792       gfx::CURSOR_BACKWARD));
793   EXPECT_STR_EQ("LLO WORLD", model.GetSelectedText());
794
795   model.SelectSelectionModel(gfx::SelectionModel(gfx::Range(1000, 3),
796       gfx::CURSOR_FORWARD));
797   EXPECT_STR_EQ("LO WORLD", model.GetSelectedText());
798
799   model.SelectSelectionModel(gfx::SelectionModel(0, gfx::CURSOR_FORWARD));
800   EXPECT_TRUE(model.GetSelectedText().empty());
801
802   model.SelectSelectionModel(gfx::SelectionModel(3, gfx::CURSOR_FORWARD));
803   EXPECT_TRUE(model.GetSelectedText().empty());
804
805   model.SelectSelectionModel(gfx::SelectionModel(gfx::Range(1000, 100),
806       gfx::CURSOR_FORWARD));
807   EXPECT_TRUE(model.GetSelectedText().empty());
808
809   model.SelectSelectionModel(gfx::SelectionModel(1000, gfx::CURSOR_BACKWARD));
810   EXPECT_TRUE(model.GetSelectedText().empty());
811 }
812
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());
819
820   gfx::Range range;
821   model.GetTextRange(&range);
822   EXPECT_EQ(gfx::Range(0, 7), range);
823
824   ui::CompositionText composition;
825   composition.text = base::ASCIIToUTF16("678");
826   composition.underlines.push_back(ui::CompositionUnderline(0, 3, 0, false));
827
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());
833
834   // Cancel the composition.
835   model.CancelCompositionText();
836   composition_text_confirmed_or_cleared_ = false;
837
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());
847
848   model.GetTextRange(&range);
849   EXPECT_EQ(10U, range.end());
850   EXPECT_STR_EQ("1234567890", model.text());
851
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());
857
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());
865
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);
872
873   model.SetCompositionText(composition);
874   EXPECT_STR_EQ("1234567890678", model.text());
875
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());
882
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());
887
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());
894
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());
900
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());
906
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());
912
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());
920
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());
927
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());
933
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;
939
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());
945
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());
951
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());
960
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());
966
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());
972
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());
978
979   model.SetCompositionText(composition);
980   model.ClearSelection();
981   EXPECT_TRUE(composition_text_confirmed_or_cleared_);
982   composition_text_confirmed_or_cleared_ = false;
983
984   model.SetCompositionText(composition);
985   EXPECT_FALSE(model.Cut());
986   EXPECT_FALSE(composition_text_confirmed_or_cleared_);
987 }
988
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());
997
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());
1008
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());
1015
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());
1023
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());
1048
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());
1055
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());
1084 }
1085
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());
1113
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());
1146 }
1147
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());
1170 }
1171
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());
1197
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());
1223
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());
1238
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());
1257
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());
1295
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());
1307 }
1308
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());
1326 }
1327
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());
1349 }
1350
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());
1373 }
1374
1375 TEST_F(TextfieldModelTest, UndoRedo_ReplaceTest) {
1376   {
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);
1382   }
1383   {
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);
1389   }
1390   {
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);
1396   }
1397   {
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);
1403   }
1404 }
1405
1406 TEST_F(TextfieldModelTest, UndoRedo_CompositionText) {
1407   TextfieldModel model(NULL);
1408
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);
1413
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());
1423
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());
1436
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());
1450
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());
1464
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());
1478
1479   // TODO(oshima): Test the behavior with an IME.
1480 }
1481
1482 }  // namespace views