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

Side by Side Diff: ui/gfx/render_text_unittest.cc

Issue 17745005: Clamp RenderTextWin layout length to 10,000 code points. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Resolve string formatting; you just can't please some compilers. Created 7 years, 5 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/strings/stringprintf.h"
8 #include "base/strings/utf_string_conversions.h" 9 #include "base/strings/utf_string_conversions.h"
9 #include "testing/gtest/include/gtest/gtest.h" 10 #include "testing/gtest/include/gtest/gtest.h"
10 #include "ui/gfx/break_list.h" 11 #include "ui/gfx/break_list.h"
11 12
12 #if defined(OS_WIN) 13 #if defined(OS_WIN)
13 #include "base/win/windows_version.h" 14 #include "base/win/windows_version.h"
14 #endif 15 #endif
15 16
16 #if defined(OS_LINUX) 17 #if defined(OS_LINUX)
17 #include "ui/gfx/render_text_linux.h" 18 #include "ui/gfx/render_text_linux.h"
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 void SetRTL(bool rtl) { 51 void SetRTL(bool rtl) {
51 // Override the current locale/direction. 52 // Override the current locale/direction.
52 base::i18n::SetICUDefaultLocale(rtl ? "he" : "en"); 53 base::i18n::SetICUDefaultLocale(rtl ? "he" : "en");
53 #if defined(TOOLKIT_GTK) 54 #if defined(TOOLKIT_GTK)
54 // Do the same for GTK, which does not rely on the ICU default locale. 55 // Do the same for GTK, which does not rely on the ICU default locale.
55 gtk_widget_set_default_direction(rtl ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR); 56 gtk_widget_set_default_direction(rtl ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
56 #endif 57 #endif
57 EXPECT_EQ(rtl, base::i18n::IsRTL()); 58 EXPECT_EQ(rtl, base::i18n::IsRTL());
58 } 59 }
59 60
61 // Ensure cursor movement in the specified |direction| yields |expected| values.
62 void RunMoveCursorLeftRightTest(RenderText* render_text,
63 const std::vector<SelectionModel>& expected,
64 VisualCursorDirection direction) {
65 for (size_t i = 0; i < expected.size(); ++i) {
66 SCOPED_TRACE(base::StringPrintf("Going %s; expected value index %d.",
67 direction == CURSOR_LEFT ? "left" : "right", static_cast<int>(i)));
68 EXPECT_EQ(expected[i], render_text->selection_model());
69 render_text->MoveCursor(CHARACTER_BREAK, direction, false);
70 }
71 // Check that cursoring is clamped at the line edge.
72 EXPECT_EQ(expected.back(), render_text->selection_model());
73 // Check that it is the line edge.
74 render_text->MoveCursor(LINE_BREAK, direction, false);
75 EXPECT_EQ(expected.back(), render_text->selection_model());
76 }
77
60 } // namespace 78 } // namespace
61 79
62 class RenderTextTest : public testing::Test { 80 class RenderTextTest : public testing::Test {
63 }; 81 };
64 82
65 TEST_F(RenderTextTest, DefaultStyle) { 83 TEST_F(RenderTextTest, DefaultStyle) {
66 // Check the default styles applied to new instances and adjusted text. 84 // Check the default styles applied to new instances and adjusted text.
67 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 85 scoped_ptr<RenderText> render_text(RenderText::CreateInstance());
68 EXPECT_TRUE(render_text->text().empty()); 86 EXPECT_TRUE(render_text->text().empty());
69 const wchar_t* const cases[] = { kWeak, kLtr, L"Hello", kRtl, L"", L"" }; 87 const wchar_t* const cases[] = { kWeak, kLtr, L"Hello", kRtl, L"", L"" };
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 EXPECT_EQ(valid_expect_0_and_1, render_text->GetLayoutText()); 384 EXPECT_EQ(valid_expect_0_and_1, render_text->GetLayoutText());
367 render_text->RenderText::SetObscuredRevealIndex(2); 385 render_text->RenderText::SetObscuredRevealIndex(2);
368 EXPECT_EQ(ASCIIToUTF16("*h***"), render_text->GetLayoutText()); 386 EXPECT_EQ(ASCIIToUTF16("*h***"), render_text->GetLayoutText());
369 render_text->RenderText::SetObscuredRevealIndex(5); 387 render_text->RenderText::SetObscuredRevealIndex(5);
370 const char16 valid_expect_5_and_6[] = {'*', '*', '*', '*', 0xD800, 0xDC00, 0}; 388 const char16 valid_expect_5_and_6[] = {'*', '*', '*', '*', 0xD800, 0xDC00, 0};
371 EXPECT_EQ(valid_expect_5_and_6, render_text->GetLayoutText()); 389 EXPECT_EQ(valid_expect_5_and_6, render_text->GetLayoutText());
372 render_text->RenderText::SetObscuredRevealIndex(6); 390 render_text->RenderText::SetObscuredRevealIndex(6);
373 EXPECT_EQ(valid_expect_5_and_6, render_text->GetLayoutText()); 391 EXPECT_EQ(valid_expect_5_and_6, render_text->GetLayoutText());
374 } 392 }
375 393
394 TEST_F(RenderTextTest, TruncatedText) {
395 struct {
396 const wchar_t* text;
397 const wchar_t* layout_text;
398 } cases[] = {
399 // Strings shorter than the truncation length should be laid out in full.
400 { L"", L"" },
401 { kWeak, kWeak },
402 { kLtr, kLtr },
403 { kLtrRtl, kLtrRtl },
404 { kLtrRtlLtr, kLtrRtlLtr },
405 { kRtl, kRtl },
406 { kRtlLtr, kRtlLtr },
407 { kRtlLtrRtl, kRtlLtrRtl },
408 // Strings as long as the truncation length should be laid out in full.
409 { L"01234", L"01234" },
410 // Long strings should be truncated with an ellipsis appended at the end.
411 { L"012345", L"0123\x2026" },
412 { L"012"L" . ", L"012 \x2026" },
413 { L"012"L"abc", L"012a\x2026" },
414 { L"012"L"a"L"\x5d0\x5d1", L"012a\x2026" },
415 { L"012"L"a"L"\x5d1"L"b", L"012a\x2026" },
416 { L"012"L"\x5d0\x5d1\x5d2", L"012\x5d0\x2026" },
417 { L"012"L"\x5d0\x5d1"L"a", L"012\x5d0\x2026" },
418 { L"012"L"\x5d0"L"a"L"\x5d1", L"012\x5d0\x2026" },
419 // Surrogate pairs should be truncated reasonably enough.
420 { L"0123\x0915\x093f", L"0123\x2026" },
421 { L"0\x05e9\x05bc\x05c1\x05b8", L"0\x05e9\x05bc\x05c1\x05b8" },
422 { L"01\x05e9\x05bc\x05c1\x05b8", L"01\x05e9\x05bc\x2026" },
423 { L"012\x05e9\x05bc\x05c1\x05b8", L"012\x05e9\x2026" },
424 { L"0123\x05e9\x05bc\x05c1\x05b8", L"0123\x2026" },
425 { L"01234\x05e9\x05bc\x05c1\x05b8", L"0123\x2026" },
426 { L"012\xF0\x9D\x84\x9E", L"012\xF0\x2026" },
427 };
428
429 scoped_ptr<RenderText> render_text(RenderText::CreateInstance());
430 render_text->set_truncate_length(5);
431 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); i++) {
432 render_text->SetText(WideToUTF16(cases[i].text));
433 EXPECT_EQ(WideToUTF16(cases[i].text), render_text->text());
434 EXPECT_EQ(WideToUTF16(cases[i].layout_text), render_text->GetLayoutText())
435 << "For case " << i << ": " << cases[i].text;
436 }
437 }
438
439 TEST_F(RenderTextTest, TruncatedObscuredText) {
440 scoped_ptr<RenderText> render_text(RenderText::CreateInstance());
441 render_text->set_truncate_length(3);
442 render_text->SetObscured(true);
443 render_text->SetText(WideToUTF16(L"abcdef"));
444 EXPECT_EQ(WideToUTF16(L"abcdef"), render_text->text());
445 EXPECT_EQ(WideToUTF16(L"**\x2026"), render_text->GetLayoutText());
446 }
447
448 TEST_F(RenderTextTest, TruncatedCursorMovementLTR) {
449 scoped_ptr<RenderText> render_text(RenderText::CreateInstance());
450 render_text->set_truncate_length(2);
451 render_text->SetText(WideToUTF16(L"abcd"));
452
453 EXPECT_EQ(SelectionModel(0, CURSOR_BACKWARD), render_text->selection_model());
454 render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, false);
455 EXPECT_EQ(SelectionModel(4, CURSOR_FORWARD), render_text->selection_model());
456 render_text->MoveCursor(LINE_BREAK, CURSOR_LEFT, false);
457 EXPECT_EQ(SelectionModel(0, CURSOR_BACKWARD), render_text->selection_model());
458
459 std::vector<SelectionModel> expected;
460 expected.push_back(SelectionModel(0, CURSOR_BACKWARD));
461 expected.push_back(SelectionModel(1, CURSOR_BACKWARD));
462 expected.push_back(SelectionModel(2, CURSOR_BACKWARD));
463 // The cursor hops over the elided text to the line end.
464 expected.push_back(SelectionModel(4, CURSOR_FORWARD));
465 expected.push_back(SelectionModel(4, CURSOR_FORWARD));
466 RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_RIGHT);
467
468 expected.clear();
469 expected.push_back(SelectionModel(4, CURSOR_FORWARD));
470 // The cursor hops over the elided text to preceeding text.
471 expected.push_back(SelectionModel(1, CURSOR_FORWARD));
472 expected.push_back(SelectionModel(0, CURSOR_FORWARD));
473 expected.push_back(SelectionModel(0, CURSOR_BACKWARD));
474 RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_LEFT);
475 }
476
477 TEST_F(RenderTextTest, TruncatedCursorMovementRTL) {
478 scoped_ptr<RenderText> render_text(RenderText::CreateInstance());
479 render_text->set_truncate_length(2);
480 render_text->SetText(WideToUTF16(L"\x5d0\x5d1\x5d2\x5d3"));
481
482 EXPECT_EQ(SelectionModel(0, CURSOR_BACKWARD), render_text->selection_model());
483 render_text->MoveCursor(LINE_BREAK, CURSOR_LEFT, false);
484 EXPECT_EQ(SelectionModel(4, CURSOR_FORWARD), render_text->selection_model());
485 render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, false);
486 EXPECT_EQ(SelectionModel(0, CURSOR_BACKWARD), render_text->selection_model());
487
488 std::vector<SelectionModel> expected;
489 expected.push_back(SelectionModel(0, CURSOR_BACKWARD));
490 expected.push_back(SelectionModel(1, CURSOR_BACKWARD));
491 expected.push_back(SelectionModel(2, CURSOR_BACKWARD));
492 // The cursor hops over the elided text to the line end.
493 expected.push_back(SelectionModel(4, CURSOR_FORWARD));
494 expected.push_back(SelectionModel(4, CURSOR_FORWARD));
495 RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_LEFT);
496
497 expected.clear();
498 expected.push_back(SelectionModel(4, CURSOR_FORWARD));
499 // The cursor hops over the elided text to preceeding text.
500 expected.push_back(SelectionModel(1, CURSOR_FORWARD));
501 expected.push_back(SelectionModel(0, CURSOR_FORWARD));
502 expected.push_back(SelectionModel(0, CURSOR_BACKWARD));
503 RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_RIGHT);
504 }
505
376 TEST_F(RenderTextTest, GetTextDirection) { 506 TEST_F(RenderTextTest, GetTextDirection) {
377 struct { 507 struct {
378 const wchar_t* text; 508 const wchar_t* text;
379 const base::i18n::TextDirection text_direction; 509 const base::i18n::TextDirection text_direction;
380 } cases[] = { 510 } cases[] = {
381 // Blank strings and those with no/weak directionality default to LTR. 511 // Blank strings and those with no/weak directionality default to LTR.
382 { L"", base::i18n::LEFT_TO_RIGHT }, 512 { L"", base::i18n::LEFT_TO_RIGHT },
383 { kWeak, base::i18n::LEFT_TO_RIGHT }, 513 { kWeak, base::i18n::LEFT_TO_RIGHT },
384 // Strings that begin with strong LTR characters. 514 // Strings that begin with strong LTR characters.
385 { kLtr, base::i18n::LEFT_TO_RIGHT }, 515 { kLtr, base::i18n::LEFT_TO_RIGHT },
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 EXPECT_EQ(was_rtl, base::i18n::IsRTL()); 547 EXPECT_EQ(was_rtl, base::i18n::IsRTL());
418 548
419 // Ensure that text changes update the direction for DIRECTIONALITY_FROM_TEXT. 549 // Ensure that text changes update the direction for DIRECTIONALITY_FROM_TEXT.
420 render_text->SetDirectionalityMode(DIRECTIONALITY_FROM_TEXT); 550 render_text->SetDirectionalityMode(DIRECTIONALITY_FROM_TEXT);
421 render_text->SetText(WideToUTF16(kLtr)); 551 render_text->SetText(WideToUTF16(kLtr));
422 EXPECT_EQ(render_text->GetTextDirection(), base::i18n::LEFT_TO_RIGHT); 552 EXPECT_EQ(render_text->GetTextDirection(), base::i18n::LEFT_TO_RIGHT);
423 render_text->SetText(WideToUTF16(kRtl)); 553 render_text->SetText(WideToUTF16(kRtl));
424 EXPECT_EQ(render_text->GetTextDirection(), base::i18n::RIGHT_TO_LEFT); 554 EXPECT_EQ(render_text->GetTextDirection(), base::i18n::RIGHT_TO_LEFT);
425 } 555 }
426 556
427 void RunMoveCursorLeftRightTest(RenderText* render_text,
428 const std::vector<SelectionModel>& expected,
429 VisualCursorDirection direction) {
430 for (size_t i = 0; i < expected.size(); ++i) {
431 EXPECT_EQ(expected[i], render_text->selection_model());
432 render_text->MoveCursor(CHARACTER_BREAK, direction, false);
433 }
434 // Check that cursoring is clamped at the line edge.
435 EXPECT_EQ(expected.back(), render_text->selection_model());
436 // Check that it is the line edge.
437 render_text->MoveCursor(LINE_BREAK, direction, false);
438 EXPECT_EQ(expected.back(), render_text->selection_model());
439 }
440
441 TEST_F(RenderTextTest, MoveCursorLeftRightInLtr) { 557 TEST_F(RenderTextTest, MoveCursorLeftRightInLtr) {
442 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 558 scoped_ptr<RenderText> render_text(RenderText::CreateInstance());
443 559
444 // Pure LTR. 560 // Pure LTR.
445 render_text->SetText(ASCIIToUTF16("abc")); 561 render_text->SetText(ASCIIToUTF16("abc"));
446 // |expected| saves the expected SelectionModel when moving cursor from left 562 // |expected| saves the expected SelectionModel when moving cursor from left
447 // to right. 563 // to right.
448 std::vector<SelectionModel> expected; 564 std::vector<SelectionModel> expected;
449 expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 565 expected.push_back(SelectionModel(0, CURSOR_BACKWARD));
450 expected.push_back(SelectionModel(1, CURSOR_BACKWARD)); 566 expected.push_back(SelectionModel(1, CURSOR_BACKWARD));
(...skipping 944 matching lines...) Expand 10 before | Expand all | Expand 10 after
1395 EXPECT_EQ(render_text->display_rect().width() - width - 1, 1511 EXPECT_EQ(render_text->display_rect().width() - width - 1,
1396 render_text->GetUpdatedCursorBounds().x()); 1512 render_text->GetUpdatedCursorBounds().x());
1397 1513
1398 // Reset the application default text direction to LTR. 1514 // Reset the application default text direction to LTR.
1399 SetRTL(was_rtl); 1515 SetRTL(was_rtl);
1400 EXPECT_EQ(was_rtl, base::i18n::IsRTL()); 1516 EXPECT_EQ(was_rtl, base::i18n::IsRTL());
1401 } 1517 }
1402 #endif // !defined(OS_MACOSX) 1518 #endif // !defined(OS_MACOSX)
1403 1519
1404 } // namespace gfx 1520 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698