Index: ui/gfx/render_text_unittest.cc |
=================================================================== |
--- ui/gfx/render_text_unittest.cc (revision 100777) |
+++ ui/gfx/render_text_unittest.cc (working copy) |
@@ -178,4 +178,169 @@ |
EXPECT_FALSE(render_text->style_ranges()[0].strike); |
} |
+// TODO(xji): Make these work on Windows. |
+#if defined(OS_LINUX) |
+void MoveLeftRightByWordVerifier(RenderText* render_text, |
+ const wchar_t* str) { |
+ render_text->SetText(WideToUTF16(str)); |
+ |
+ // Test moving by word from left ro right. |
+ render_text->MoveCursorLeft(LINE_BREAK, false); |
+ bool first_word = true; |
+ while (true) { |
+ // First, test moving by word from a word break position, such as from |
+ // "|abc def" to "abc| def". |
+ SelectionModel start = render_text->selection_model(); |
+ render_text->MoveCursorRight(WORD_BREAK, false); |
+ SelectionModel end = render_text->selection_model(); |
+ if (end.Equals(start)) // reach the end. |
+ break; |
+ |
+ // For testing simplicity, each word is a 3-character word. |
+ int num_of_character_moves = first_word ? 3 : 4; |
+ first_word = false; |
+ render_text->MoveCursorTo(start); |
+ for (int j = 0; j < num_of_character_moves; ++j) |
+ render_text->MoveCursorRight(CHARACTER_BREAK, false); |
+ EXPECT_TRUE(render_text->selection_model().Equals(end)); |
+ |
+ // Then, test moving by word from positions inside the word, such as from |
+ // "a|bc def" to "abc| def", and from "ab|c def" to "abc| def". |
+ for (int j = 1; j < num_of_character_moves; ++j) { |
+ render_text->MoveCursorTo(start); |
+ for (int k = 0; k < j; ++k) |
+ render_text->MoveCursorRight(CHARACTER_BREAK, false); |
+ render_text->MoveCursorRight(WORD_BREAK, false); |
+ EXPECT_TRUE(render_text->selection_model().Equals(end)); |
+ } |
+ } |
+ |
+ // Test moving by word from right to left. |
+ render_text->MoveCursorRight(LINE_BREAK, false); |
+ first_word = true; |
+ while (true) { |
+ SelectionModel start = render_text->selection_model(); |
+ render_text->MoveCursorLeft(WORD_BREAK, false); |
+ SelectionModel end = render_text->selection_model(); |
+ if (end.Equals(start)) // reach the end. |
+ break; |
+ |
+ int num_of_character_moves = first_word ? 3 : 4; |
+ first_word = false; |
+ render_text->MoveCursorTo(start); |
+ for (int j = 0; j < num_of_character_moves; ++j) |
+ render_text->MoveCursorLeft(CHARACTER_BREAK, false); |
+ EXPECT_TRUE(render_text->selection_model().Equals(end)); |
+ |
+ for (int j = 1; j < num_of_character_moves; ++j) { |
+ render_text->MoveCursorTo(start); |
+ for (int k = 0; k < j; ++k) |
+ render_text->MoveCursorLeft(CHARACTER_BREAK, false); |
+ render_text->MoveCursorLeft(WORD_BREAK, false); |
+ EXPECT_TRUE(render_text->selection_model().Equals(end)); |
+ } |
+ } |
+} |
+ |
+TEST_F(RenderTextTest, MoveLeftRightByWordInBidiText) { |
+ scoped_ptr<RenderText> render_text(RenderText::CreateRenderText()); |
+ |
+ // For testing simplicity, each word is a 3-character word. |
+ std::vector<const wchar_t*> test; |
+ test.push_back(L"abc"); |
+ test.push_back(L"abc def"); |
+ test.push_back(L"\x05E1\x05E2\x05E3"); |
+ test.push_back(L"\x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6"); |
+ test.push_back(L"abc \x05E1\x05E2\x05E3"); |
+ test.push_back(L"abc def \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6"); |
+ test.push_back(L"abc def hij \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6" |
+ L" \x05E7\x05E8\x05E9"); |
+ |
+ test.push_back(L"abc \x05E1\x05E2\x05E3 hij"); |
+ test.push_back(L"abc def \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6 hij opq"); |
+ test.push_back(L"abc def hij \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6" |
+ L" \x05E7\x05E8\x05E9"L" opq rst uvw"); |
+ |
+ test.push_back(L"\x05E1\x05E2\x05E3 abc"); |
+ test.push_back(L"\x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6 abc def"); |
+ test.push_back(L"\x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6 \x05E7\x05E8\x05E9" |
+ L" abc def hij"); |
+ |
+ test.push_back(L"\x05D1\x05D2\x05D3 abc \x05E1\x05E2\x05E3"); |
+ test.push_back(L"\x05D1\x05D2\x05D3 \x05D4\x05D5\x05D6 abc def" |
+ L" \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6"); |
+ test.push_back(L"\x05D1\x05D2\x05D3 \x05D4\x05D5\x05D6 \x05D7\x05D8\x05D9" |
+ L" abc def hij \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6" |
+ L" \x05E7\x05E8\x05E9"); |
+ |
+ for (size_t i = 0; i < test.size(); ++i) |
+ MoveLeftRightByWordVerifier(render_text.get(), test[i]); |
+} |
+ |
+TEST_F(RenderTextTest, MoveLeftRightByWordInBidiText_TestEndOfText) { |
+ scoped_ptr<RenderText> render_text(RenderText::CreateRenderText()); |
+ |
+ render_text->SetText(WideToUTF16(L"ab\x05E1")); |
+ // Moving cursor by word from "abC|" to left should return "|abC". |
msw
2011/09/17 00:27:10
"Moving *the* cursor"... "to *the* left"
Same corr
|
+ // But since end of text is always treated as a word breaker, it returns |
+ // position "ab|C". |
+ // TODO(xji): Need to make it work as expected. |
+ render_text->MoveCursorRight(LINE_BREAK, false); |
+ render_text->MoveCursorLeft(WORD_BREAK, false); |
+ // EXPECT_TRUE(render_text->selection_model().Equals(SelectionModel(0))); |
+ |
+ // Moving cursor by word from "|abC" to right returns "abC|". |
msw
2011/09/17 00:27:10
"Moving *the* cursor"... "to *the* right"
|
+ render_text->MoveCursorLeft(LINE_BREAK, false); |
+ render_text->MoveCursorRight(WORD_BREAK, false); |
+ EXPECT_TRUE(render_text->selection_model().Equals( |
+ SelectionModel(3, 2, SelectionModel::LEADING))); |
+ |
+ render_text->SetText(WideToUTF16(L"\x05E1\x05E2"L"a")); |
+ // For logical text "BCa", moving cursor by word from "aCB|" to left returns |
msw
2011/09/17 00:27:10
"moving *the* cursor"... "to *the* left"
|
+ // "|aCB". |
+ render_text->MoveCursorRight(LINE_BREAK, false); |
+ render_text->MoveCursorLeft(WORD_BREAK, false); |
+ EXPECT_TRUE(render_text->selection_model().Equals( |
+ SelectionModel(3, 2, SelectionModel::LEADING))); |
+ |
+ // Moving cursor by word from "|aCB" to right should return "returns "aCB|". |
msw
2011/09/17 00:27:10
You have a stray bit of text ("returns)...
"*the*
|
+ // But since end of text is always treated as a word breaker, it returns |
msw
2011/09/17 00:27:11
"word break" I don't think 'breaker' is correct.
|
+ // position "a|CB". |
+ // TODO(xji): Need to make it work as expected. |
+ render_text->MoveCursorLeft(LINE_BREAK, false); |
+ render_text->MoveCursorRight(WORD_BREAK, false); |
+ // EXPECT_TRUE(render_text->selection_model().Equals(SelectionModel(0))); |
+} |
+ |
+TEST_F(RenderTextTest, MoveLeftRightByWordInTextWithMultiSpaces) { |
+ scoped_ptr<RenderText> render_text(RenderText::CreateRenderText()); |
+ render_text->SetText(WideToUTF16(L"abc def")); |
+ render_text->MoveCursorTo(SelectionModel(5)); |
+ render_text->MoveCursorRight(WORD_BREAK, false); |
+ EXPECT_EQ(11U, render_text->GetCursorPosition()); |
+ |
+ render_text->MoveCursorTo(SelectionModel(5)); |
+ render_text->MoveCursorLeft(WORD_BREAK, false); |
+ EXPECT_EQ(0U, render_text->GetCursorPosition()); |
+} |
+ |
+TEST_F(RenderTextTest, MoveLeftRightByWordInChineseText) { |
+ scoped_ptr<RenderText> render_text(RenderText::CreateRenderText()); |
+ render_text->SetText(WideToUTF16(L"\x6211\x4EEC\x53BB\x516C\x56ED\x73A9")); |
+ render_text->MoveCursorLeft(LINE_BREAK, false); |
+ EXPECT_EQ(0U, render_text->GetCursorPosition()); |
+ render_text->MoveCursorRight(WORD_BREAK, false); |
+ EXPECT_EQ(2U, render_text->GetCursorPosition()); |
+ render_text->MoveCursorRight(WORD_BREAK, false); |
+ EXPECT_EQ(3U, render_text->GetCursorPosition()); |
+ render_text->MoveCursorRight(WORD_BREAK, false); |
+ EXPECT_EQ(5U, render_text->GetCursorPosition()); |
+ render_text->MoveCursorRight(WORD_BREAK, false); |
+ EXPECT_EQ(6U, render_text->GetCursorPosition()); |
+ render_text->MoveCursorRight(WORD_BREAK, false); |
+ EXPECT_EQ(6U, render_text->GetCursorPosition()); |
+} |
+ |
+#endif |
+ |
} // namespace gfx |