Home | History | Annotate | Download | only in textfield
      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   virtual 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
   1483