Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/auto_reset.h" | 5 #include "base/auto_reset.h" |
| 6 #include "base/memory/scoped_ptr.h" | 6 #include "base/memory/scoped_ptr.h" |
| 7 #include "base/message_loop.h" | 7 #include "base/message_loop.h" |
| 8 #include "base/utf_string_conversions.h" | 8 #include "base/utf_string_conversions.h" |
| 9 #include "testing/gtest/include/gtest/gtest.h" | 9 #include "testing/gtest/include/gtest/gtest.h" |
| 10 #include "ui/base/clipboard/clipboard.h" | 10 #include "ui/base/clipboard/clipboard.h" |
| 11 #include "ui/base/clipboard/scoped_clipboard_writer.h" | 11 #include "ui/base/clipboard/scoped_clipboard_writer.h" |
| 12 #include "ui/base/range/range.h" | 12 #include "ui/base/range/range.h" |
| 13 #include "ui/gfx/render_text.h" | 13 #include "ui/gfx/render_text.h" |
| 14 #include "views/controls/textfield/textfield.h" | 14 #include "views/controls/textfield/textfield.h" |
| 15 #include "views/controls/textfield/textfield_views_model.h" | 15 #include "views/controls/textfield/textfield_views_model.h" |
| 16 #include "views/test/test_views_delegate.h" | 16 #include "views/test/test_views_delegate.h" |
| 17 #include "views/test/views_test_base.h" | 17 #include "views/test/views_test_base.h" |
| 18 #include "views/views_delegate.h" | 18 #include "views/views_delegate.h" |
| 19 | 19 |
| 20 namespace { | |
| 21 | |
| 22 struct Selection { | |
| 23 size_t cursor; | |
| 24 size_t caret; | |
| 25 gfx::SelectionModel::CaretPlacement placement; | |
| 26 }; | |
| 27 | |
| 28 } // namespace | |
| 29 | |
| 20 namespace views { | 30 namespace views { |
| 21 | 31 |
| 22 class TextfieldViewsModelTest : public ViewsTestBase, | 32 class TextfieldViewsModelTest : public ViewsTestBase, |
| 23 public TextfieldViewsModel::Delegate { | 33 public TextfieldViewsModel::Delegate { |
| 24 public: | 34 public: |
| 25 TextfieldViewsModelTest() | 35 TextfieldViewsModelTest() |
| 26 : ViewsTestBase(), | 36 : ViewsTestBase(), |
| 27 composition_text_confirmed_or_cleared_(false) { | 37 composition_text_confirmed_or_cleared_(false) { |
| 28 } | 38 } |
| 29 | 39 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 76 model.MoveCursorLeft(gfx::LINE_BREAK, false); | 86 model.MoveCursorLeft(gfx::LINE_BREAK, false); |
| 77 EXPECT_FALSE(model.Backspace()); | 87 EXPECT_FALSE(model.Backspace()); |
| 78 EXPECT_STR_EQ("HELLORLD", model.GetText()); | 88 EXPECT_STR_EQ("HELLORLD", model.GetText()); |
| 79 // Move the cursor to the end. delete should fail. | 89 // Move the cursor to the end. delete should fail. |
| 80 model.MoveCursorRight(gfx::LINE_BREAK, false); | 90 model.MoveCursorRight(gfx::LINE_BREAK, false); |
| 81 EXPECT_FALSE(model.Delete()); | 91 EXPECT_FALSE(model.Delete()); |
| 82 EXPECT_STR_EQ("HELLORLD", model.GetText()); | 92 EXPECT_STR_EQ("HELLORLD", model.GetText()); |
| 83 // but backspace should work. | 93 // but backspace should work. |
| 84 EXPECT_TRUE(model.Backspace()); | 94 EXPECT_TRUE(model.Backspace()); |
| 85 EXPECT_STR_EQ("HELLORL", model.GetText()); | 95 EXPECT_STR_EQ("HELLORL", model.GetText()); |
| 96 | |
| 97 model.MoveCursorTo(gfx::SelectionModel(5)); | |
| 98 model.ReplaceText(ASCIIToUTF16(" WOR")); | |
| 99 EXPECT_STR_EQ("HELLO WORL", model.GetText()); | |
| 100 } | |
| 101 | |
| 102 TEST_F(TextfieldViewsModelTest, EditString_SimpleRTL) { | |
| 103 TextfieldViewsModel model(NULL); | |
| 104 // Append two strings. | |
| 105 model.Append(WideToUTF16(L"\x05d0\x05d1\x05d2")); | |
| 106 EXPECT_EQ(WideToUTF16(L"\x05d0\x05d1\x05d2"), model.GetText()); | |
| 107 model.Append(WideToUTF16(L"\x05e0\x05e1\x05e2")); | |
|
msw
2011/09/09 23:03:24
Perhaps make the second string different than the
xji
2011/09/12 21:31:48
they are different.
msw
2011/09/14 02:43:48
doh! you are right.
| |
| 108 EXPECT_EQ(WideToUTF16(L"\x05d0\x05d1\x05d2\x05e0\x05e1\x05e2"), | |
| 109 model.GetText()); | |
| 110 | |
| 111 // Insert 0x05f0. | |
| 112 model.MoveCursorTo(gfx::SelectionModel(1U)); | |
| 113 model.InsertChar(0x05f0); | |
| 114 EXPECT_EQ(WideToUTF16(L"\x05d0\x05f0\x05d1\x05d2\x05e0\x05e1\x05e2"), | |
| 115 model.GetText()); | |
| 116 | |
| 117 // Replace "\x05d1" with "\x05f1". | |
| 118 model.ReplaceChar(0x05f1); | |
| 119 EXPECT_EQ(WideToUTF16(L"\x05d0\x05f0\x5f1\x05d2\x05e0\x05e1\x05e2"), | |
| 120 model.GetText()); | |
| 121 | |
| 122 // Delete and backspace. | |
| 123 EXPECT_EQ(3U, model.GetCursorPosition()); | |
| 124 EXPECT_TRUE(model.Delete()); | |
| 125 EXPECT_EQ(WideToUTF16(L"\x05d0\x05f0\x5f1\x05e0\x05e1\x05e2"), | |
| 126 model.GetText()); | |
| 127 EXPECT_TRUE(model.Backspace()); | |
| 128 EXPECT_EQ(2U, model.GetCursorPosition()); | |
| 129 EXPECT_EQ(WideToUTF16(L"\x05d0\x05f0\x05e0\x05e1\x05e2"), model.GetText()); | |
| 130 } | |
| 131 | |
| 132 TEST_F(TextfieldViewsModelTest, EditString_ComplexScript) { | |
| 133 TextfieldViewsModel model(NULL); | |
| 134 // Append two Hindi strings. | |
| 135 model.Append(WideToUTF16(L"\x0915\x093f\x0915\x094d\x0915")); | |
| 136 EXPECT_EQ(WideToUTF16(L"\x0915\x093f\x0915\x094d\x0915"), | |
| 137 model.GetText()); | |
| 138 model.Append(WideToUTF16(L"\x0915\x094d\x092e\x094d")); | |
| 139 EXPECT_EQ(WideToUTF16( | |
| 140 L"\x0915\x093f\x0915\x094d\x0915\x0915\x094d\x092e\x094d"), | |
| 141 model.GetText()); | |
| 142 | |
| 143 // Check it is not able to place cursor in middle of a grapheme. | |
| 144 model.MoveCursorTo(gfx::SelectionModel(1U)); | |
| 145 EXPECT_EQ(0U, model.GetCursorPosition()); | |
| 146 | |
| 147 model.MoveCursorTo(gfx::SelectionModel(2U)); | |
| 148 EXPECT_EQ(2U, model.GetCursorPosition()); | |
| 149 model.InsertChar('a'); | |
| 150 EXPECT_EQ(WideToUTF16( | |
| 151 L"\x0915\x093f\x0061\x0915\x094d\x0915\x0915\x094d\x092e\x094d"), | |
| 152 model.GetText()); | |
| 153 | |
| 154 // ReplaceChar will replace the whole grapheme. | |
| 155 model.ReplaceChar('b'); | |
| 156 EXPECT_EQ(WideToUTF16( | |
| 157 L"\x0915\x093f\x0061\x0062\x0915\x0915\x094d\x092e\x094d"), | |
| 158 model.GetText()); | |
| 159 EXPECT_EQ(4U, model.GetCursorPosition()); | |
| 160 | |
| 161 // DELETE should delte the whole grapheme. | |
|
msw
2011/09/09 23:03:24
"Delete" isn't all-caps and "del*e*te".
xji
2011/09/12 21:31:48
Done.
| |
| 162 model.MoveCursorTo(gfx::SelectionModel(0U)); | |
| 163 EXPECT_TRUE(model.Delete()); | |
| 164 EXPECT_EQ(WideToUTF16(L"\x0061\x0062\x0915\x0915\x094d\x092e\x094d"), | |
| 165 model.GetText()); | |
| 166 model.MoveCursorTo(gfx::SelectionModel(model.GetText().length())); | |
| 167 EXPECT_TRUE(model.Backspace()); | |
| 168 EXPECT_EQ(WideToUTF16(L"\x0061\x0062\x0915\x0915\x094d\x092e"), | |
| 169 model.GetText()); | |
| 170 | |
| 171 // Test cursor position and deletion for Hindi VIRAMA. | |
|
msw
2011/09/09 23:03:24
Virama isn't all-caps.
xji
2011/09/12 21:31:48
Done.
| |
| 172 model.SetText(WideToUTF16(L"\x0D38\x0D4D\x0D15\x0D16\x0D2E")); | |
| 173 model.MoveCursorTo(gfx::SelectionModel(0)); | |
| 174 EXPECT_EQ(0U, model.GetCursorPosition()); | |
| 175 | |
| 176 model.MoveCursorTo(gfx::SelectionModel(1)); | |
| 177 EXPECT_EQ(0U, model.GetCursorPosition()); | |
| 178 | |
| 179 model.MoveCursorTo(gfx::SelectionModel(2)); | |
| 180 EXPECT_EQ(2U, model.GetCursorPosition()); | |
| 181 | |
| 182 model.MoveCursorTo(gfx::SelectionModel(3)); | |
| 183 EXPECT_EQ(3U, model.GetCursorPosition()); | |
| 184 | |
| 185 model.MoveCursorTo(gfx::SelectionModel(2)); | |
| 186 | |
| 187 EXPECT_TRUE(model.Backspace()); | |
| 188 EXPECT_EQ(WideToUTF16(L"\x0D38\x0D15\x0D16\x0D2E"), model.GetText()); | |
| 189 | |
| 190 // Test DELETE/BACKSPACE on Hebrew with non-spacing marks. | |
|
msw
2011/09/09 23:03:24
Delete and Backspace are not all-caps.
xji
2011/09/12 21:31:48
Done.
| |
| 191 model.SetText(WideToUTF16(L"\x05d5\x05b7\x05D9\x05B0\x05D4\x05B4\x05D9")); | |
| 192 model.MoveCursorTo(gfx::SelectionModel(0)); | |
| 193 EXPECT_TRUE(model.Delete()); | |
| 194 EXPECT_TRUE(model.Delete()); | |
| 195 EXPECT_TRUE(model.Delete()); | |
| 196 EXPECT_TRUE(model.Delete()); | |
| 197 EXPECT_EQ(WideToUTF16(L""), model.GetText()); | |
| 198 | |
| 199 model.SetText(WideToUTF16(L"\x002C\x0020\x05D1\x05BC\x05B7\x05E9\x05BC")); | |
| 200 model.MoveCursorLeft(gfx::LINE_BREAK, false); | |
|
msw
2011/09/09 23:03:24
Won't this fail on windows if the UI mode isn't RT
xji
2011/09/12 21:31:48
add #if defined and use move to right line end for
| |
| 201 EXPECT_TRUE(model.Backspace()); | |
| 202 EXPECT_EQ(WideToUTF16(L"\x002C\x0020\x05D1\x05BC\x05B7\x05E9"), | |
| 203 model.GetText()); | |
| 204 } | |
| 205 | |
| 206 void RunMoveCursorLeftRightTest(TextfieldViewsModel* model, | |
| 207 struct Selection* expected, | |
| 208 int num_of_selection_entry, | |
| 209 bool move_right) { | |
| 210 for (int i = 0; i <= num_of_selection_entry + 1; ++i) { | |
|
msw
2011/09/09 23:03:24
Why are you looping i from 0 to n+1 but then clamp
xji
2011/09/12 21:31:48
It is to test when cursor is at the HOME/END, pres
| |
| 211 int index = std::min(i, num_of_selection_entry - 1); | |
| 212 struct Selection sel = expected[index]; | |
|
msw
2011/09/09 23:03:24
I don't believe 'struct' is needed here and elsewh
xji
2011/09/12 21:31:48
removed struct.
| |
| 213 EXPECT_TRUE(model->render_text()->selection_model().Equals( | |
| 214 gfx::SelectionModel(sel.cursor, sel.caret, sel.placement))); | |
| 215 | |
| 216 if (move_right) | |
| 217 model->MoveCursorRight(gfx::CHARACTER_BREAK, false); | |
| 218 else | |
| 219 model->MoveCursorLeft(gfx::CHARACTER_BREAK, false); | |
| 220 } | |
| 221 | |
| 222 struct Selection sel = expected[num_of_selection_entry - 1]; | |
| 223 if (move_right) | |
| 224 model->MoveCursorRight(gfx::LINE_BREAK, false); | |
| 225 else | |
| 226 model->MoveCursorLeft(gfx::LINE_BREAK, false); | |
| 227 EXPECT_TRUE(model->render_text()->selection_model().Equals( | |
| 228 gfx::SelectionModel(sel.cursor, sel.caret, sel.placement))); | |
| 229 } | |
| 230 | |
| 231 TEST_F(TextfieldViewsModelTest, MoveCursorLeftRight) { | |
| 232 TextfieldViewsModel model(NULL); | |
| 233 | |
| 234 // Pure LTR. | |
| 235 model.SetText(ASCIIToUTF16("abc")); | |
| 236 // left_to_right saves the expected (cursor, caret, caret_placement) triplet | |
| 237 // when moving cursor from left to right. | |
| 238 struct Selection left_to_right[] = { | |
|
msw
2011/09/09 23:03:24
Use std::vector<gfx::SelectionModel> instead here
xji
2011/09/12 21:31:48
Done.
| |
| 239 {0, 0, gfx::SelectionModel::LEADING}, | |
| 240 {1, 0, gfx::SelectionModel::TRAILING}, | |
| 241 {2, 1, gfx::SelectionModel::TRAILING}, | |
| 242 {3, 2, gfx::SelectionModel::TRAILING}, | |
| 243 }; | |
| 244 RunMoveCursorLeftRightTest(&model, left_to_right, | |
| 245 sizeof(left_to_right)/sizeof(struct Selection), true); | |
| 246 | |
| 247 struct Selection right_to_left[] = { | |
| 248 {3, 2, gfx::SelectionModel::TRAILING}, | |
| 249 {2, 2, gfx::SelectionModel::LEADING}, | |
| 250 {1, 1, gfx::SelectionModel::LEADING}, | |
| 251 {0, 0, gfx::SelectionModel::LEADING}, | |
| 252 }; | |
| 253 RunMoveCursorLeftRightTest(&model, right_to_left, | |
| 254 sizeof(right_to_left)/sizeof(struct Selection), false); | |
| 255 | |
| 256 // Pure RTL. | |
| 257 model.SetText(WideToUTF16(L"\x05d0\x05d1\x05d2")); | |
| 258 struct Selection right_to_left_h[] = { | |
| 259 {0, 0, gfx::SelectionModel::LEADING}, | |
| 260 {1, 0, gfx::SelectionModel::TRAILING}, | |
| 261 {2, 1, gfx::SelectionModel::TRAILING}, | |
| 262 {3, 2, gfx::SelectionModel::TRAILING}, | |
| 263 }; | |
| 264 RunMoveCursorLeftRightTest(&model, right_to_left_h, | |
| 265 sizeof(right_to_left_h)/sizeof(struct Selection), false); | |
| 266 | |
| 267 struct Selection left_to_right_h[] = { | |
| 268 {3, 2, gfx::SelectionModel::TRAILING}, | |
| 269 {2, 2, gfx::SelectionModel::LEADING}, | |
| 270 {1, 1, gfx::SelectionModel::LEADING}, | |
| 271 {0, 0, gfx::SelectionModel::LEADING}, | |
| 272 }; | |
| 273 RunMoveCursorLeftRightTest(&model, left_to_right_h, | |
| 274 sizeof(left_to_right_h)/sizeof(struct Selection), true); | |
| 275 | |
| 276 // LTR-RTL | |
| 277 model.SetText(WideToUTF16(L"abc\x05d0\x05d1\x05d2")); | |
| 278 // The last one is the expected END position. | |
| 279 struct Selection right_to_left_eh[] = { | |
| 280 {0, 0, gfx::SelectionModel::LEADING}, | |
| 281 {1, 0, gfx::SelectionModel::TRAILING}, | |
| 282 {2, 1, gfx::SelectionModel::TRAILING}, | |
| 283 {3, 2, gfx::SelectionModel::TRAILING}, | |
| 284 {5, 5, gfx::SelectionModel::LEADING}, | |
| 285 {4, 4, gfx::SelectionModel::LEADING}, | |
| 286 {3, 3, gfx::SelectionModel::LEADING}, | |
| 287 {6, 3, gfx::SelectionModel::LEADING}, | |
| 288 }; | |
| 289 RunMoveCursorLeftRightTest(&model, right_to_left_eh, | |
| 290 sizeof(right_to_left_eh)/sizeof(struct Selection), true); | |
| 291 | |
| 292 struct Selection left_to_right_eh[] = { | |
| 293 {6, 3, gfx::SelectionModel::LEADING}, | |
| 294 {4, 3, gfx::SelectionModel::TRAILING}, | |
| 295 {5, 4, gfx::SelectionModel::TRAILING}, | |
| 296 {6, 5, gfx::SelectionModel::TRAILING}, | |
| 297 {2, 2, gfx::SelectionModel::LEADING}, | |
| 298 {1, 1, gfx::SelectionModel::LEADING}, | |
| 299 {0, 0, gfx::SelectionModel::LEADING}, | |
| 300 }; | |
| 301 RunMoveCursorLeftRightTest(&model, left_to_right_eh, | |
| 302 sizeof(left_to_right_eh)/sizeof(struct Selection), false); | |
| 303 | |
| 304 // RTL-LTR | |
| 305 model.SetText(WideToUTF16(L"\x05d0\x05d1\x05d2"L"abc")); | |
| 306 struct Selection right_to_left_he[] = { | |
| 307 {0, 0, gfx::SelectionModel::LEADING}, | |
| 308 {1, 0, gfx::SelectionModel::TRAILING}, | |
| 309 {2, 1, gfx::SelectionModel::TRAILING}, | |
| 310 {3, 2, gfx::SelectionModel::TRAILING}, | |
| 311 {5, 5, gfx::SelectionModel::LEADING}, | |
| 312 {4, 4, gfx::SelectionModel::LEADING}, | |
| 313 {3, 3, gfx::SelectionModel::LEADING}, | |
| 314 {6, 3, gfx::SelectionModel::LEADING}, | |
| 315 }; | |
| 316 RunMoveCursorLeftRightTest(&model, right_to_left_he, | |
| 317 sizeof(right_to_left_he)/sizeof(struct Selection), false); | |
| 318 | |
| 319 struct Selection left_to_right_he[] = { | |
| 320 {6, 3, gfx::SelectionModel::LEADING}, | |
| 321 {4, 3, gfx::SelectionModel::TRAILING}, | |
| 322 {5, 4, gfx::SelectionModel::TRAILING}, | |
| 323 {6, 5, gfx::SelectionModel::TRAILING}, | |
| 324 {2, 2, gfx::SelectionModel::LEADING}, | |
| 325 {1, 1, gfx::SelectionModel::LEADING}, | |
| 326 {0, 0, gfx::SelectionModel::LEADING}, | |
| 327 }; | |
| 328 RunMoveCursorLeftRightTest(&model, left_to_right_he, | |
| 329 sizeof(left_to_right_he)/sizeof(struct Selection), true); | |
| 330 | |
| 331 // LTR-RTL-LTR. | |
| 332 model.SetText(WideToUTF16(L"a"L"\x05d1"L"b")); | |
| 333 struct Selection left_to_right_ehe[] = { | |
| 334 {0, 0, gfx::SelectionModel::LEADING}, | |
| 335 {1, 0, gfx::SelectionModel::TRAILING}, | |
| 336 {1, 1, gfx::SelectionModel::LEADING}, | |
| 337 {3, 2, gfx::SelectionModel::TRAILING}, | |
| 338 }; | |
| 339 RunMoveCursorLeftRightTest(&model, left_to_right_ehe, | |
| 340 sizeof(left_to_right_ehe)/sizeof(struct Selection), true); | |
| 341 | |
| 342 struct Selection right_to_left_ehe[] = { | |
| 343 {3, 2, gfx::SelectionModel::TRAILING}, | |
| 344 {2, 2, gfx::SelectionModel::LEADING}, | |
| 345 {2, 1, gfx::SelectionModel::TRAILING}, | |
| 346 {0, 0, gfx::SelectionModel::LEADING}, | |
| 347 }; | |
| 348 RunMoveCursorLeftRightTest(&model, right_to_left_ehe, | |
| 349 sizeof(right_to_left_ehe)/sizeof(struct Selection), false); | |
| 350 | |
| 351 // RTL-LTR-RTL. | |
| 352 model.SetText(WideToUTF16(L"\x05d0"L"a"L"\x05d1")); | |
| 353 struct Selection right_to_left_heh[] = { | |
| 354 {0, 0, gfx::SelectionModel::LEADING}, | |
| 355 {1, 0, gfx::SelectionModel::TRAILING}, | |
| 356 {1, 1, gfx::SelectionModel::LEADING}, | |
| 357 {3, 2, gfx::SelectionModel::TRAILING}, | |
| 358 }; | |
| 359 RunMoveCursorLeftRightTest(&model, right_to_left_heh, | |
| 360 sizeof(right_to_left_heh)/sizeof(struct Selection), false); | |
| 361 | |
| 362 struct Selection left_to_right_heh[] = { | |
| 363 {3, 2, gfx::SelectionModel::TRAILING}, | |
| 364 {2, 2, gfx::SelectionModel::LEADING}, | |
| 365 {2, 1, gfx::SelectionModel::TRAILING}, | |
| 366 {0, 0, gfx::SelectionModel::LEADING}, | |
| 367 }; | |
| 368 RunMoveCursorLeftRightTest(&model, left_to_right_heh, | |
| 369 sizeof(left_to_right_heh)/sizeof(struct Selection), true); | |
| 370 } | |
| 371 | |
| 372 TEST_F(TextfieldViewsModelTest, MoveCursorLeftRight_ComplexScript) { | |
| 373 TextfieldViewsModel model(NULL); | |
| 374 | |
| 375 model.Append(WideToUTF16(L"\x0915\x093f\x0915\x094d\x0915")); | |
|
msw
2011/09/09 23:03:24
Any reason you chose not to use RunMoveCursorLeftR
xji
2011/09/12 21:31:48
since this is uni-directional text, I am not testi
| |
| 376 EXPECT_EQ(0U, model.GetCursorPosition()); | |
| 377 model.MoveCursorRight(gfx::CHARACTER_BREAK, false); | |
| 378 EXPECT_EQ(2U, model.GetCursorPosition()); | |
| 379 model.MoveCursorRight(gfx::CHARACTER_BREAK, false); | |
| 380 EXPECT_EQ(4U, model.GetCursorPosition()); | |
| 381 model.MoveCursorRight(gfx::CHARACTER_BREAK, false); | |
| 382 EXPECT_EQ(5U, model.GetCursorPosition()); | |
| 383 model.MoveCursorRight(gfx::CHARACTER_BREAK, false); | |
| 384 EXPECT_EQ(5U, model.GetCursorPosition()); | |
| 385 | |
| 386 model.MoveCursorLeft(gfx::CHARACTER_BREAK, false); | |
| 387 EXPECT_EQ(4U, model.GetCursorPosition()); | |
| 388 model.MoveCursorLeft(gfx::CHARACTER_BREAK, false); | |
| 389 EXPECT_EQ(2U, model.GetCursorPosition()); | |
| 390 model.MoveCursorLeft(gfx::CHARACTER_BREAK, false); | |
| 391 EXPECT_EQ(0U, model.GetCursorPosition()); | |
| 392 model.MoveCursorLeft(gfx::CHARACTER_BREAK, false); | |
| 393 EXPECT_EQ(0U, model.GetCursorPosition()); | |
| 86 } | 394 } |
| 87 | 395 |
| 88 TEST_F(TextfieldViewsModelTest, EmptyString) { | 396 TEST_F(TextfieldViewsModelTest, EmptyString) { |
| 89 TextfieldViewsModel model(NULL); | 397 TextfieldViewsModel model(NULL); |
| 90 EXPECT_EQ(string16(), model.GetText()); | 398 EXPECT_EQ(string16(), model.GetText()); |
| 91 EXPECT_EQ(string16(), model.GetSelectedText()); | 399 EXPECT_EQ(string16(), model.GetSelectedText()); |
| 92 EXPECT_EQ(string16(), model.GetVisibleText()); | 400 EXPECT_EQ(string16(), model.GetVisibleText()); |
| 93 | 401 |
| 94 model.MoveCursorLeft(gfx::CHARACTER_BREAK, true); | 402 model.MoveCursorLeft(gfx::CHARACTER_BREAK, true); |
| 95 EXPECT_EQ(0U, model.GetCursorPosition()); | 403 EXPECT_EQ(0U, model.GetCursorPosition()); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 136 | 444 |
| 137 // Select all and move cursor | 445 // Select all and move cursor |
| 138 model.SelectAll(); | 446 model.SelectAll(); |
| 139 model.MoveCursorLeft(gfx::CHARACTER_BREAK, false); | 447 model.MoveCursorLeft(gfx::CHARACTER_BREAK, false); |
| 140 EXPECT_EQ(0U, model.GetCursorPosition()); | 448 EXPECT_EQ(0U, model.GetCursorPosition()); |
| 141 model.SelectAll(); | 449 model.SelectAll(); |
| 142 model.MoveCursorRight(gfx::CHARACTER_BREAK, false); | 450 model.MoveCursorRight(gfx::CHARACTER_BREAK, false); |
| 143 EXPECT_EQ(5U, model.GetCursorPosition()); | 451 EXPECT_EQ(5U, model.GetCursorPosition()); |
| 144 } | 452 } |
| 145 | 453 |
| 454 TEST_F(TextfieldViewsModelTest, Selection_BidiWithNonSpacingMarks) { | |
| 455 TextfieldViewsModel model(NULL); | |
| 456 model.Append(WideToUTF16( | |
| 457 L"abc\x05E9\x05BC\x05C1\x05B8\x05E0\x05B8"L"def")); | |
| 458 model.MoveCursorRight(gfx::CHARACTER_BREAK, false); | |
| 459 model.MoveCursorRight(gfx::CHARACTER_BREAK, false); | |
| 460 | |
| 461 model.MoveCursorRight(gfx::CHARACTER_BREAK, true); | |
| 462 EXPECT_EQ(WideToUTF16(L"c"), model.GetSelectedText()); | |
| 463 | |
| 464 model.MoveCursorRight(gfx::CHARACTER_BREAK, true); | |
| 465 EXPECT_EQ(WideToUTF16(L"c\x05E9\x05BC\x05C1\x05B8"), | |
| 466 model.GetSelectedText()); | |
| 467 | |
| 468 model.MoveCursorRight(gfx::CHARACTER_BREAK, true); | |
| 469 EXPECT_EQ(WideToUTF16(L"c"), model.GetSelectedText()); | |
|
msw
2011/09/09 23:03:24
This is the spec'ed behavior, but it might confuse
xji
2011/09/12 21:31:48
added comments and selection_start/end expected re
| |
| 470 | |
| 471 model.MoveCursorRight(gfx::CHARACTER_BREAK, true); | |
| 472 EXPECT_EQ(WideToUTF16(L"c\x05E9\x05BC\x05C1\x05B8\x05E0\x05B8"L"d"), | |
| 473 model.GetSelectedText()); | |
| 474 | |
| 475 model.ClearSelection(); | |
| 476 EXPECT_EQ(string16(), model.GetSelectedText()); | |
| 477 model.SelectAll(); | |
| 478 EXPECT_EQ(WideToUTF16(L"abc\x05E9\x05BC\x05C1\x05B8\x05E0\x05B8"L"def"), | |
| 479 model.GetSelectedText()); | |
| 480 | |
| 481 // In case of "aBc", this test shows how to select "aB" or "Bc", assume 'B' is | |
| 482 // an RTL character. | |
| 483 model.SetText(WideToUTF16(L"a\x05E9"L"b")); | |
| 484 model.MoveCursorTo(gfx::SelectionModel(0)); | |
| 485 model.MoveCursorRight(gfx::CHARACTER_BREAK, true); | |
| 486 EXPECT_EQ(WideToUTF16(L"a"), model.GetSelectedText()); | |
| 487 | |
| 488 model.MoveCursorRight(gfx::CHARACTER_BREAK, true); | |
| 489 EXPECT_EQ(WideToUTF16(L"a"), model.GetSelectedText()); | |
| 490 | |
| 491 model.MoveCursorRight(gfx::CHARACTER_BREAK, true); | |
| 492 EXPECT_EQ(WideToUTF16(L"a\x05E9"L"b"), model.GetSelectedText()); | |
| 493 | |
| 494 model.MoveCursorRight(gfx::CHARACTER_BREAK, false); | |
| 495 EXPECT_EQ(3U, model.GetCursorPosition()); | |
| 496 model.MoveCursorLeft(gfx::CHARACTER_BREAK, true); | |
| 497 EXPECT_EQ(WideToUTF16(L"b"), model.GetSelectedText()); | |
| 498 | |
| 499 model.MoveCursorLeft(gfx::CHARACTER_BREAK, true); | |
| 500 EXPECT_EQ(WideToUTF16(L"b"), model.GetSelectedText()); | |
| 501 | |
| 502 model.MoveCursorLeft(gfx::CHARACTER_BREAK, true); | |
| 503 EXPECT_EQ(WideToUTF16(L"a\x05E9"L"b"), model.GetSelectedText()); | |
| 504 | |
| 505 model.MoveCursorLeft(gfx::LINE_BREAK, false); | |
| 506 model.MoveCursorRight(gfx::CHARACTER_BREAK, true); | |
| 507 model.MoveCursorRight(gfx::CHARACTER_BREAK, true); | |
| 508 model.MoveCursorLeft(gfx::CHARACTER_BREAK, true); | |
| 509 EXPECT_EQ(WideToUTF16(L"a\x05E9"), model.GetSelectedText()); | |
| 510 | |
| 511 model.MoveCursorRight(gfx::LINE_BREAK, false); | |
| 512 model.MoveCursorLeft(gfx::CHARACTER_BREAK, true); | |
| 513 model.MoveCursorLeft(gfx::CHARACTER_BREAK, true); | |
| 514 model.MoveCursorRight(gfx::CHARACTER_BREAK, true); | |
| 515 EXPECT_EQ(WideToUTF16(L"\x05E9"L"b"), model.GetSelectedText()); | |
| 516 | |
| 517 model.ClearSelection(); | |
| 518 EXPECT_EQ(string16(), model.GetSelectedText()); | |
| 519 model.SelectAll(); | |
| 520 EXPECT_EQ(WideToUTF16(L"a\x05E9"L"b"), model.GetSelectedText()); | |
| 521 } | |
| 522 | |
| 523 TEST_F(TextfieldViewsModelTest, MoveCursorLeftRightWithSelection) { | |
| 524 TextfieldViewsModel model(NULL); | |
| 525 model.SetText(WideToUTF16(L"abc\x05d0\x05d1\x05d2")); | |
|
msw
2011/09/09 23:03:24
Please add EXPECT_EQs for model.GetCursorPosition
xji
2011/09/12 21:31:48
Done.
| |
| 526 model.MoveCursorRight(gfx::LINE_BREAK, false); | |
| 527 model.MoveCursorLeft(gfx::CHARACTER_BREAK, false); | |
| 528 model.MoveCursorLeft(gfx::CHARACTER_BREAK, false); | |
| 529 model.MoveCursorLeft(gfx::CHARACTER_BREAK, false); | |
| 530 model.MoveCursorRight(gfx::CHARACTER_BREAK, true); | |
| 531 model.MoveCursorRight(gfx::CHARACTER_BREAK, true); | |
| 532 model.MoveCursorLeft(gfx::CHARACTER_BREAK, false); | |
| 533 EXPECT_EQ(6U, model.GetCursorPosition()); | |
| 534 | |
| 535 model.MoveCursorLeft(gfx::LINE_BREAK, false); | |
| 536 model.MoveCursorRight(gfx::CHARACTER_BREAK, false); | |
| 537 model.MoveCursorRight(gfx::CHARACTER_BREAK, false); | |
| 538 model.MoveCursorRight(gfx::CHARACTER_BREAK, false); | |
| 539 model.MoveCursorRight(gfx::CHARACTER_BREAK, false); | |
| 540 model.MoveCursorRight(gfx::CHARACTER_BREAK, false); | |
| 541 | |
|
msw
2011/09/09 23:03:24
nit: The very similar block above doesn't have a b
xji
2011/09/12 21:31:48
removed blank line.
| |
| 542 model.MoveCursorLeft(gfx::CHARACTER_BREAK, true); | |
| 543 model.MoveCursorLeft(gfx::CHARACTER_BREAK, true); | |
| 544 model.MoveCursorRight(gfx::CHARACTER_BREAK, false); | |
| 545 EXPECT_EQ(4U, model.GetCursorPosition()); | |
| 546 } | |
| 547 | |
| 146 TEST_F(TextfieldViewsModelTest, SelectionAndEdit) { | 548 TEST_F(TextfieldViewsModelTest, SelectionAndEdit) { |
| 147 TextfieldViewsModel model(NULL); | 549 TextfieldViewsModel model(NULL); |
| 148 model.Append(ASCIIToUTF16("HELLO")); | 550 model.Append(ASCIIToUTF16("HELLO")); |
| 149 model.MoveCursorRight(gfx::CHARACTER_BREAK, false); | 551 model.MoveCursorRight(gfx::CHARACTER_BREAK, false); |
| 150 model.MoveCursorRight(gfx::CHARACTER_BREAK, true); | 552 model.MoveCursorRight(gfx::CHARACTER_BREAK, true); |
| 151 model.MoveCursorRight(gfx::CHARACTER_BREAK, true); // select "EL" | 553 model.MoveCursorRight(gfx::CHARACTER_BREAK, true); // select "EL" |
| 152 EXPECT_TRUE(model.Backspace()); | 554 EXPECT_TRUE(model.Backspace()); |
| 153 EXPECT_STR_EQ("HLO", model.GetText()); | 555 EXPECT_STR_EQ("HLO", model.GetText()); |
| 154 | 556 |
| 155 model.Append(ASCIIToUTF16("ILL")); | 557 model.Append(ASCIIToUTF16("ILL")); |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 307 model.MoveCursorRight(gfx::LINE_BREAK, false); | 709 model.MoveCursorRight(gfx::LINE_BREAK, false); |
| 308 model.MoveCursorLeft(gfx::WORD_BREAK, true); | 710 model.MoveCursorLeft(gfx::WORD_BREAK, true); |
| 309 EXPECT_TRUE(model.Paste()); | 711 EXPECT_TRUE(model.Paste()); |
| 310 clipboard->ReadText(ui::Clipboard::BUFFER_STANDARD, &clipboard_text); | 712 clipboard->ReadText(ui::Clipboard::BUFFER_STANDARD, &clipboard_text); |
| 311 EXPECT_STR_EQ("HELLO HELLO WORLD", clipboard_text); | 713 EXPECT_STR_EQ("HELLO HELLO WORLD", clipboard_text); |
| 312 EXPECT_STR_EQ("HELLO HELLO HELLO HELLO WORLD", model.GetText()); | 714 EXPECT_STR_EQ("HELLO HELLO HELLO HELLO WORLD", model.GetText()); |
| 313 EXPECT_EQ(29U, model.GetCursorPosition()); | 715 EXPECT_EQ(29U, model.GetCursorPosition()); |
| 314 } | 716 } |
| 315 | 717 |
| 316 void SelectWordTestVerifier(TextfieldViewsModel &model, | 718 void SelectWordTestVerifier(TextfieldViewsModel &model, |
| 317 const std::string &expected_selected_string, size_t expected_cursor_pos) { | 719 const string16 &expected_selected_string, size_t expected_cursor_pos) { |
| 318 EXPECT_STR_EQ(expected_selected_string, model.GetSelectedText()); | 720 EXPECT_EQ(expected_selected_string, model.GetSelectedText()); |
| 319 EXPECT_EQ(expected_cursor_pos, model.GetCursorPosition()); | 721 EXPECT_EQ(expected_cursor_pos, model.GetCursorPosition()); |
| 320 } | 722 } |
| 321 | 723 |
| 322 TEST_F(TextfieldViewsModelTest, SelectWordTest) { | 724 TEST_F(TextfieldViewsModelTest, SelectWordTest) { |
| 323 TextfieldViewsModel model(NULL); | 725 TextfieldViewsModel model(NULL); |
| 324 model.Append(ASCIIToUTF16(" HELLO !! WO RLD ")); | 726 model.Append(ASCIIToUTF16(" HELLO !! WO RLD ")); |
| 325 | 727 |
| 326 // Test when cursor is at the beginning. | 728 // Test when cursor is at the beginning. |
| 327 model.MoveCursorLeft(gfx::LINE_BREAK, false); | 729 model.MoveCursorLeft(gfx::LINE_BREAK, false); |
| 328 model.SelectWord(); | 730 model.SelectWord(); |
| 329 SelectWordTestVerifier(model, " ", 2U); | 731 SelectWordTestVerifier(model, ASCIIToUTF16(" "), 2U); |
| 330 | 732 |
| 331 // Test when cursor is at the beginning of a word. | 733 // Test when cursor is at the beginning of a word. |
| 332 gfx::SelectionModel selection(2U); | 734 gfx::SelectionModel selection(2U); |
| 333 model.MoveCursorTo(selection); | 735 model.MoveCursorTo(selection); |
| 334 model.SelectWord(); | 736 model.SelectWord(); |
| 335 SelectWordTestVerifier(model, "HELLO", 7U); | 737 SelectWordTestVerifier(model, ASCIIToUTF16("HELLO"), 7U); |
| 336 | 738 |
| 337 // Test when cursor is at the end of a word. | 739 // Test when cursor is at the end of a word. |
| 338 selection = gfx::SelectionModel(15U); | 740 selection = gfx::SelectionModel(15U); |
| 339 model.MoveCursorTo(selection); | 741 model.MoveCursorTo(selection); |
| 340 model.SelectWord(); | 742 model.SelectWord(); |
| 341 SelectWordTestVerifier(model, "WO", 15U); | 743 SelectWordTestVerifier(model, ASCIIToUTF16(" "), 20U); |
| 342 | 744 |
| 343 // Test when cursor is somewhere in a non-alph-numeric fragment. | 745 // Test when cursor is somewhere in a non-alph-numeric fragment. |
|
msw
2011/09/09 23:03:24
nit: mind fixing "alph*a*"?
xji
2011/09/12 21:31:48
Done.
| |
| 344 for (size_t cursor_pos = 8; cursor_pos < 13U; cursor_pos++) { | 746 for (size_t cursor_pos = 8; cursor_pos < 13U; cursor_pos++) { |
| 345 selection = gfx::SelectionModel(cursor_pos); | 747 selection = gfx::SelectionModel(cursor_pos); |
| 346 model.MoveCursorTo(selection); | 748 model.MoveCursorTo(selection); |
| 347 model.SelectWord(); | 749 model.SelectWord(); |
| 348 SelectWordTestVerifier(model, " !! ", 13U); | 750 SelectWordTestVerifier(model, ASCIIToUTF16(" !! "), 13U); |
| 349 } | 751 } |
| 350 | 752 |
| 351 // Test when cursor is somewhere in a whitespace fragment. | 753 // Test when cursor is somewhere in a whitespace fragment. |
| 352 selection = gfx::SelectionModel(17U); | 754 selection = gfx::SelectionModel(17U); |
| 353 model.MoveCursorTo(selection); | 755 model.MoveCursorTo(selection); |
| 354 model.SelectWord(); | 756 model.SelectWord(); |
| 355 SelectWordTestVerifier(model, " ", 20U); | 757 SelectWordTestVerifier(model, ASCIIToUTF16(" "), 20U); |
| 356 | 758 |
| 357 // Test when cursor is at the end. | 759 // Test when cursor is at the end. |
| 358 model.MoveCursorRight(gfx::LINE_BREAK, false); | 760 model.MoveCursorRight(gfx::LINE_BREAK, false); |
| 359 model.SelectWord(); | 761 model.SelectWord(); |
| 360 SelectWordTestVerifier(model, " ", 24U); | 762 SelectWordTestVerifier(model, ASCIIToUTF16(" "), 24U); |
| 763 } | |
| 764 | |
| 765 TEST_F(TextfieldViewsModelTest, SelectWordTest_MixScripts) { | |
| 766 TextfieldViewsModel model(NULL); | |
| 767 const struct WordAndCursor { | |
| 768 const wchar_t* word; | |
| 769 size_t cursor; | |
| 770 } words_and_cursor[] = { | |
|
msw
2011/09/09 23:03:24
I suppose this works, but would you mind splitting
xji
2011/09/12 21:31:48
Done.
| |
| 771 {L"a\x05d0", 2}, | |
| 772 {L"a\x05d0", 2}, | |
| 773 {L"\x05d1\x05d2", 5}, | |
| 774 {L"\x05d1\x05d2", 5}, | |
| 775 {L" ", 3}, | |
| 776 {L"a\x05d0", 2}, | |
| 777 {L"\x0915\x094d\x0915", 9}, | |
| 778 {L"\x0915\x094d\x0915", 9}, | |
| 779 {L" ", 10}, | |
| 780 {L"\x4E2D\x56FD", 12}, | |
| 781 {L"\x4E2D\x56FD", 12}, | |
| 782 {L"\x82B1", 13}, | |
| 783 {L"\x5929", 14}, | |
| 784 }; | |
| 785 // The text consists of Ascii, Hebrew, Hindi with Virama sign, and Chinese. | |
|
msw
2011/09/09 23:03:24
Extra space in "with * *Virama"
xji
2011/09/12 21:31:48
Done.
| |
| 786 model.SetText(WideToUTF16(L"a\x05d0 \x05d1\x05d2 \x0915\x094d\x0915 " | |
| 787 L"\x4E2D\x56FD\x82B1\x5929")); | |
| 788 for (size_t i = 0; i < sizeof(words_and_cursor)/sizeof(WordAndCursor); | |
|
msw
2011/09/09 23:03:24
Wouldn't it be a bit clearer to remove the WordAnd
xji
2011/09/12 21:31:48
that is true. But the current one also tests the s
| |
| 789 ++i) { | |
| 790 model.MoveCursorLeft(gfx::LINE_BREAK, false); | |
| 791 for (size_t j = 0; j < i; ++j) | |
| 792 model.MoveCursorRight(gfx::CHARACTER_BREAK, false); | |
| 793 model.SelectWord(); | |
| 794 SelectWordTestVerifier(model, WideToUTF16(words_and_cursor[i].word), | |
| 795 words_and_cursor[i].cursor); | |
| 796 } | |
| 361 } | 797 } |
| 362 | 798 |
| 363 TEST_F(TextfieldViewsModelTest, RangeTest) { | 799 TEST_F(TextfieldViewsModelTest, RangeTest) { |
| 364 TextfieldViewsModel model(NULL); | 800 TextfieldViewsModel model(NULL); |
| 365 model.Append(ASCIIToUTF16("HELLO WORLD")); | 801 model.Append(ASCIIToUTF16("HELLO WORLD")); |
| 366 model.MoveCursorLeft(gfx::LINE_BREAK, false); | 802 model.MoveCursorLeft(gfx::LINE_BREAK, false); |
| 367 ui::Range range; | 803 ui::Range range; |
| 368 model.GetSelectedRange(&range); | 804 model.GetSelectedRange(&range); |
| 369 EXPECT_TRUE(range.is_empty()); | 805 EXPECT_TRUE(range.is_empty()); |
| 370 EXPECT_EQ(0U, range.start()); | 806 EXPECT_EQ(0U, range.start()); |
| (...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1135 EXPECT_TRUE(model.Undo()); | 1571 EXPECT_TRUE(model.Undo()); |
| 1136 EXPECT_STR_EQ("ABCDE", model.GetText()); | 1572 EXPECT_STR_EQ("ABCDE", model.GetText()); |
| 1137 EXPECT_TRUE(model.Redo()); | 1573 EXPECT_TRUE(model.Redo()); |
| 1138 EXPECT_STR_EQ("1234", model.GetText()); | 1574 EXPECT_STR_EQ("1234", model.GetText()); |
| 1139 EXPECT_FALSE(model.Redo()); | 1575 EXPECT_FALSE(model.Redo()); |
| 1140 | 1576 |
| 1141 // TODO(oshima): We need MockInputMethod to test the behavior with IME. | 1577 // TODO(oshima): We need MockInputMethod to test the behavior with IME. |
| 1142 } | 1578 } |
| 1143 | 1579 |
| 1144 } // namespace views | 1580 } // namespace views |
| OLD | NEW |