Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(220)

Side by Side Diff: views/controls/textfield/textfield_views_model_unittest.cc

Issue 7841056: fix know issues in RenderText (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698