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 "ui/gfx/render_text.h" | 5 #include "ui/gfx/render_text.h" |
6 | 6 |
7 #include "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.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 | 10 |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 EXPECT_EQ(ui::Range(0, 2), render_text->style_ranges()[0].range); | 171 EXPECT_EQ(ui::Range(0, 2), render_text->style_ranges()[0].range); |
172 EXPECT_FALSE(render_text->style_ranges()[0].strike); | 172 EXPECT_FALSE(render_text->style_ranges()[0].strike); |
173 | 173 |
174 // Test that previously removed ranges don't return. | 174 // Test that previously removed ranges don't return. |
175 render_text->SetText(ASCIIToUTF16("abcdef")); | 175 render_text->SetText(ASCIIToUTF16("abcdef")); |
176 EXPECT_EQ(1U, render_text->style_ranges().size()); | 176 EXPECT_EQ(1U, render_text->style_ranges().size()); |
177 EXPECT_EQ(ui::Range(0, 6), render_text->style_ranges()[0].range); | 177 EXPECT_EQ(ui::Range(0, 6), render_text->style_ranges()[0].range); |
178 EXPECT_FALSE(render_text->style_ranges()[0].strike); | 178 EXPECT_FALSE(render_text->style_ranges()[0].strike); |
179 } | 179 } |
180 | 180 |
| 181 // TODO(xji): Make these work on Windows. |
| 182 #if defined(OS_LINUX) |
| 183 void MoveLeftRightByWordVerifier(RenderText* render_text, |
| 184 const wchar_t* str) { |
| 185 render_text->SetText(WideToUTF16(str)); |
| 186 |
| 187 // Test moving by word from left ro right. |
| 188 render_text->MoveCursorLeft(LINE_BREAK, false); |
| 189 bool first_word = true; |
| 190 while (true) { |
| 191 // First, test moving by word from a word break position, such as from |
| 192 // "|abc def" to "abc| def". |
| 193 SelectionModel start = render_text->selection_model(); |
| 194 render_text->MoveCursorRight(WORD_BREAK, false); |
| 195 SelectionModel end = render_text->selection_model(); |
| 196 if (end.Equals(start)) // reach the end. |
| 197 break; |
| 198 |
| 199 // For testing simplicity, each word is a 3-character word. |
| 200 int num_of_character_moves = first_word ? 3 : 4; |
| 201 first_word = false; |
| 202 render_text->MoveCursorTo(start); |
| 203 for (int j = 0; j < num_of_character_moves; ++j) |
| 204 render_text->MoveCursorRight(CHARACTER_BREAK, false); |
| 205 EXPECT_TRUE(render_text->selection_model().Equals(end)); |
| 206 |
| 207 // Then, test moving by word from positions inside the word, such as from |
| 208 // "a|bc def" to "abc| def", and from "ab|c def" to "abc| def". |
| 209 for (int j = 1; j < num_of_character_moves; ++j) { |
| 210 render_text->MoveCursorTo(start); |
| 211 for (int k = 0; k < j; ++k) |
| 212 render_text->MoveCursorRight(CHARACTER_BREAK, false); |
| 213 render_text->MoveCursorRight(WORD_BREAK, false); |
| 214 EXPECT_TRUE(render_text->selection_model().Equals(end)); |
| 215 } |
| 216 } |
| 217 |
| 218 // Test moving by word from right to left. |
| 219 render_text->MoveCursorRight(LINE_BREAK, false); |
| 220 first_word = true; |
| 221 while (true) { |
| 222 SelectionModel start = render_text->selection_model(); |
| 223 render_text->MoveCursorLeft(WORD_BREAK, false); |
| 224 SelectionModel end = render_text->selection_model(); |
| 225 if (end.Equals(start)) // reach the end. |
| 226 break; |
| 227 |
| 228 int num_of_character_moves = first_word ? 3 : 4; |
| 229 first_word = false; |
| 230 render_text->MoveCursorTo(start); |
| 231 for (int j = 0; j < num_of_character_moves; ++j) |
| 232 render_text->MoveCursorLeft(CHARACTER_BREAK, false); |
| 233 EXPECT_TRUE(render_text->selection_model().Equals(end)); |
| 234 |
| 235 for (int j = 1; j < num_of_character_moves; ++j) { |
| 236 render_text->MoveCursorTo(start); |
| 237 for (int k = 0; k < j; ++k) |
| 238 render_text->MoveCursorLeft(CHARACTER_BREAK, false); |
| 239 render_text->MoveCursorLeft(WORD_BREAK, false); |
| 240 EXPECT_TRUE(render_text->selection_model().Equals(end)); |
| 241 } |
| 242 } |
| 243 } |
| 244 |
| 245 TEST_F(RenderTextTest, MoveLeftRightByWordInBidiText) { |
| 246 scoped_ptr<RenderText> render_text(RenderText::CreateRenderText()); |
| 247 |
| 248 // For testing simplicity, each word is a 3-character word. |
| 249 std::vector<const wchar_t*> test; |
| 250 test.push_back(L"abc"); |
| 251 test.push_back(L"abc def"); |
| 252 test.push_back(L"\x05E1\x05E2\x05E3"); |
| 253 test.push_back(L"\x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6"); |
| 254 test.push_back(L"abc \x05E1\x05E2\x05E3"); |
| 255 test.push_back(L"abc def \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6"); |
| 256 test.push_back(L"abc def hij \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6" |
| 257 L" \x05E7\x05E8\x05E9"); |
| 258 |
| 259 test.push_back(L"abc \x05E1\x05E2\x05E3 hij"); |
| 260 test.push_back(L"abc def \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6 hij opq"); |
| 261 test.push_back(L"abc def hij \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6" |
| 262 L" \x05E7\x05E8\x05E9"L" opq rst uvw"); |
| 263 |
| 264 test.push_back(L"\x05E1\x05E2\x05E3 abc"); |
| 265 test.push_back(L"\x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6 abc def"); |
| 266 test.push_back(L"\x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6 \x05E7\x05E8\x05E9" |
| 267 L" abc def hij"); |
| 268 |
| 269 test.push_back(L"\x05D1\x05D2\x05D3 abc \x05E1\x05E2\x05E3"); |
| 270 test.push_back(L"\x05D1\x05D2\x05D3 \x05D4\x05D5\x05D6 abc def" |
| 271 L" \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6"); |
| 272 test.push_back(L"\x05D1\x05D2\x05D3 \x05D4\x05D5\x05D6 \x05D7\x05D8\x05D9" |
| 273 L" abc def hij \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6" |
| 274 L" \x05E7\x05E8\x05E9"); |
| 275 |
| 276 for (size_t i = 0; i < test.size(); ++i) |
| 277 MoveLeftRightByWordVerifier(render_text.get(), test[i]); |
| 278 } |
| 279 |
| 280 TEST_F(RenderTextTest, MoveLeftRightByWordInBidiText_TestEndOfText) { |
| 281 scoped_ptr<RenderText> render_text(RenderText::CreateRenderText()); |
| 282 |
| 283 render_text->SetText(WideToUTF16(L"ab\x05E1")); |
| 284 // Moving the cursor by word from "abC|" to the left should return "|abC". |
| 285 // But since end of text is always treated as a word break, it returns |
| 286 // position "ab|C". |
| 287 // TODO(xji): Need to make it work as expected. |
| 288 render_text->MoveCursorRight(LINE_BREAK, false); |
| 289 render_text->MoveCursorLeft(WORD_BREAK, false); |
| 290 // EXPECT_TRUE(render_text->selection_model().Equals(SelectionModel(0))); |
| 291 |
| 292 // Moving the cursor by word from "|abC" to the right returns "abC|". |
| 293 render_text->MoveCursorLeft(LINE_BREAK, false); |
| 294 render_text->MoveCursorRight(WORD_BREAK, false); |
| 295 EXPECT_TRUE(render_text->selection_model().Equals( |
| 296 SelectionModel(3, 2, SelectionModel::LEADING))); |
| 297 |
| 298 render_text->SetText(WideToUTF16(L"\x05E1\x05E2"L"a")); |
| 299 // For logical text "BCa", moving the cursor by word from "aCB|" to the left |
| 300 // returns "|aCB". |
| 301 render_text->MoveCursorRight(LINE_BREAK, false); |
| 302 render_text->MoveCursorLeft(WORD_BREAK, false); |
| 303 EXPECT_TRUE(render_text->selection_model().Equals( |
| 304 SelectionModel(3, 2, SelectionModel::LEADING))); |
| 305 |
| 306 // Moving the cursor by word from "|aCB" to the right should return "aCB|". |
| 307 // But since end of text is always treated as a word break, it returns |
| 308 // position "a|CB". |
| 309 // TODO(xji): Need to make it work as expected. |
| 310 render_text->MoveCursorLeft(LINE_BREAK, false); |
| 311 render_text->MoveCursorRight(WORD_BREAK, false); |
| 312 // EXPECT_TRUE(render_text->selection_model().Equals(SelectionModel(0))); |
| 313 } |
| 314 |
| 315 TEST_F(RenderTextTest, MoveLeftRightByWordInTextWithMultiSpaces) { |
| 316 scoped_ptr<RenderText> render_text(RenderText::CreateRenderText()); |
| 317 render_text->SetText(WideToUTF16(L"abc def")); |
| 318 render_text->MoveCursorTo(SelectionModel(5)); |
| 319 render_text->MoveCursorRight(WORD_BREAK, false); |
| 320 EXPECT_EQ(11U, render_text->GetCursorPosition()); |
| 321 |
| 322 render_text->MoveCursorTo(SelectionModel(5)); |
| 323 render_text->MoveCursorLeft(WORD_BREAK, false); |
| 324 EXPECT_EQ(0U, render_text->GetCursorPosition()); |
| 325 } |
| 326 |
| 327 TEST_F(RenderTextTest, MoveLeftRightByWordInChineseText) { |
| 328 scoped_ptr<RenderText> render_text(RenderText::CreateRenderText()); |
| 329 render_text->SetText(WideToUTF16(L"\x6211\x4EEC\x53BB\x516C\x56ED\x73A9")); |
| 330 render_text->MoveCursorLeft(LINE_BREAK, false); |
| 331 EXPECT_EQ(0U, render_text->GetCursorPosition()); |
| 332 render_text->MoveCursorRight(WORD_BREAK, false); |
| 333 EXPECT_EQ(2U, render_text->GetCursorPosition()); |
| 334 render_text->MoveCursorRight(WORD_BREAK, false); |
| 335 EXPECT_EQ(3U, render_text->GetCursorPosition()); |
| 336 render_text->MoveCursorRight(WORD_BREAK, false); |
| 337 EXPECT_EQ(5U, render_text->GetCursorPosition()); |
| 338 render_text->MoveCursorRight(WORD_BREAK, false); |
| 339 EXPECT_EQ(6U, render_text->GetCursorPosition()); |
| 340 render_text->MoveCursorRight(WORD_BREAK, false); |
| 341 EXPECT_EQ(6U, render_text->GetCursorPosition()); |
| 342 } |
| 343 |
| 344 #endif |
| 345 |
181 void RunMoveCursorLeftRightTest(RenderText* render_text, | 346 void RunMoveCursorLeftRightTest(RenderText* render_text, |
182 const std::vector<SelectionModel>& expected, | 347 const std::vector<SelectionModel>& expected, |
183 bool move_right) { | 348 bool move_right) { |
184 for (int i = 0; i < static_cast<int>(expected.size()); ++i) { | 349 for (int i = 0; i < static_cast<int>(expected.size()); ++i) { |
185 SelectionModel sel = expected[i]; | 350 SelectionModel sel = expected[i]; |
186 EXPECT_TRUE(render_text->selection_model().Equals(sel)); | 351 EXPECT_TRUE(render_text->selection_model().Equals(sel)); |
187 if (move_right) | 352 if (move_right) |
188 render_text->MoveCursorRight(CHARACTER_BREAK, false); | 353 render_text->MoveCursorRight(CHARACTER_BREAK, false); |
189 else | 354 else |
190 render_text->MoveCursorLeft(CHARACTER_BREAK, false); | 355 render_text->MoveCursorLeft(CHARACTER_BREAK, false); |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
481 EXPECT_EQ(4U, render_text->GetSelectionStart()); | 646 EXPECT_EQ(4U, render_text->GetSelectionStart()); |
482 EXPECT_EQ(5U, render_text->GetCursorPosition()); | 647 EXPECT_EQ(5U, render_text->GetCursorPosition()); |
483 render_text->MoveCursorLeft(CHARACTER_BREAK, true); | 648 render_text->MoveCursorLeft(CHARACTER_BREAK, true); |
484 EXPECT_EQ(4U, render_text->GetSelectionStart()); | 649 EXPECT_EQ(4U, render_text->GetSelectionStart()); |
485 EXPECT_EQ(6U, render_text->GetCursorPosition()); | 650 EXPECT_EQ(6U, render_text->GetCursorPosition()); |
486 render_text->MoveCursorRight(CHARACTER_BREAK, false); | 651 render_text->MoveCursorRight(CHARACTER_BREAK, false); |
487 EXPECT_EQ(4U, render_text->GetCursorPosition()); | 652 EXPECT_EQ(4U, render_text->GetCursorPosition()); |
488 } | 653 } |
489 | 654 |
490 } // namespace gfx | 655 } // namespace gfx |
OLD | NEW |