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