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

Unified Diff: views/controls/textfield/native_textfield_views_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 side-by-side diff with in-line comments
Download patch
Index: views/controls/textfield/native_textfield_views_unittest.cc
===================================================================
--- views/controls/textfield/native_textfield_views_unittest.cc (revision 100008)
+++ views/controls/textfield/native_textfield_views_unittest.cc (working copy)
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <string>
+#include <vector>
+
#include "base/auto_reset.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
@@ -15,6 +18,7 @@
#include "ui/base/clipboard/scoped_clipboard_writer.h"
#include "ui/base/dragdrop/drag_drop_types.h"
#include "ui/base/keycodes/keyboard_codes.h"
+#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/render_text.h"
#include "views/controls/textfield/native_textfield_views.h"
#include "views/controls/textfield/textfield.h"
@@ -215,6 +219,19 @@
SendKeyEvent(key_code, false, false);
}
+ void SendKeyEvent(char16 ch) {
+ if (ch < 0x80) {
+ ui::KeyboardCode code =
+ ch == ' ' ? ui::VKEY_SPACE :
+ static_cast<ui::KeyboardCode>(ui::VKEY_A + ch - 'a');
+ SendKeyEvent(code);
+ } else {
+ KeyEvent event(ui::ET_KEY_PRESSED, ui::VKEY_UNKNOWN, 0);
+ event.set_character(ch);
+ input_method_->DispatchKeyEvent(event);
+ }
+ }
+
View* GetFocusedView() {
return widget_->GetFocusManager()->GetFocusedView();
}
@@ -225,6 +242,44 @@
gfx::SelectionModel(cursor_pos), false).x();
}
+ // Get the current cursor bounds.
+ gfx::Rect GetCursorBounds() {
+ gfx::RenderText* render_text = textfield_view_->GetRenderText();
+ gfx::Rect bounds = render_text->GetUpdatedCursorBounds();
+ return bounds;
+ }
+
+ // Get the cursor bounds of |sel|.
+ gfx::Rect GetCursorBounds(const gfx::SelectionModel& sel) {
+ gfx::RenderText* render_text = textfield_view_->GetRenderText();
+ gfx::Rect bounds = render_text->GetCursorBounds(sel, true);
+ return bounds;
+ }
+
+ gfx::Rect GetDisplayRect() {
+ return textfield_view_->GetRenderText()->display_rect();
+ }
+
+ // Mouse click on the point whose x-axis is |bound|'s x plus |x_offset| and
+ // y-axis is in the middle of |bound|'s vertical range.
+ void MouseClick(const gfx::Rect bound, int x_offset) {
msw 2011/09/09 23:03:24 Why not use a Point instead of a Rect? Use Rect::o
xji 2011/09/12 21:31:48 I need rect.height() as well.
+ int x = bound.x() + x_offset;
+ int y = bound.y() + bound.height() / 2;
+ MouseEvent click(ui::ET_MOUSE_PRESSED, x, y, ui::EF_LEFT_BUTTON_DOWN);
+ textfield_view_->OnMousePressed(click);
+ MouseEvent release(ui::ET_MOUSE_RELEASED, 0, 0, ui::EF_LEFT_BUTTON_DOWN);
msw 2011/09/09 23:03:24 The release event should probably be at the same x
xji 2011/09/12 21:31:48 Done.
+ textfield_view_->OnMouseReleased(release);
+ }
+
+ void NonClientMouseClick() {
msw 2011/09/09 23:03:24 Using this to avoid double/triple click is pretty
xji 2011/09/12 21:31:48 Done.
+ MouseEvent click(ui::ET_MOUSE_PRESSED, 0, 0,
+ ui::EF_LEFT_BUTTON_DOWN | ui::EF_IS_NON_CLIENT);
+ textfield_view_->OnMousePressed(click);
+ MouseEvent release(ui::ET_MOUSE_RELEASED, 0, 0,
+ ui::EF_LEFT_BUTTON_DOWN | ui::EF_IS_NON_CLIENT);
+ textfield_view_->OnMouseReleased(release);
+ }
+
// Wrap for visibility in test classes.
ui::TextInputType GetTextInputType() {
return textfield_view_->GetTextInputType();
@@ -1141,4 +1196,323 @@
EXPECT_STR_EQ("ab3", textfield_->text());
}
+TEST_F(NativeTextfieldViewsTest, TextCursorDisplayTest) {
msw 2011/09/09 23:03:24 Some of these tests might be better suited as Rend
xji 2011/09/12 21:31:48 Looking at those tests again, I think in NativeTex
+ InitTextfield(Textfield::STYLE_DEFAULT);
+ // LTR-RTL string in LTR context.
+ SendKeyEvent('a');
+ EXPECT_STR_EQ("a", textfield_->text());
+ int x = GetCursorBounds().x();
+ int prev_x = x;
+
+ SendKeyEvent('b');
+ EXPECT_STR_EQ("ab", textfield_->text());
+ x = GetCursorBounds().x();
+ EXPECT_LT(prev_x, x);
+ prev_x = x;
+
+ SendKeyEvent(0x05E1);
msw 2011/09/09 23:03:24 Defining constants (if none exist) would be prefer
xji 2011/09/12 21:31:48 Hm... I tried that. But that makes the subsequent
+ EXPECT_EQ(WideToUTF16(L"ab\x05E1"), textfield_->text());
+ x = GetCursorBounds().x();
+ EXPECT_EQ(prev_x, x);
+
+ SendKeyEvent(0x05E2);
+ EXPECT_EQ(WideToUTF16(L"ab\x05E1\x5E2"), textfield_->text());
+ x = GetCursorBounds().x();
+ EXPECT_EQ(prev_x, x);
+
+ // Clear text.
+ SendKeyEvent(ui::VKEY_A, false, true);
msw 2011/09/09 23:03:24 You can just call SetText here and elsewhere that
xji 2011/09/12 21:31:48 I am trying to emulate the real UI operations. May
+ SendKeyEvent('\n');
+
+ // RTL-LTR string in LTR context.
+ SendKeyEvent(0x05E1);
+ EXPECT_EQ(WideToUTF16(L"\x05E1"), textfield_->text());
+ x = GetCursorBounds().x();
+ EXPECT_EQ(GetDisplayRect().x(), x);
+ prev_x = x;
+
+ SendKeyEvent(0x05E2);
+ EXPECT_EQ(WideToUTF16(L"\x05E1\x05E2"), textfield_->text());
+ x = GetCursorBounds().x();
+ EXPECT_EQ(prev_x, x);
+
+ SendKeyEvent('a');
+ EXPECT_EQ(WideToUTF16(L"\x05E1\x5E2"L"a"), textfield_->text());
+ x = GetCursorBounds().x();
+ EXPECT_LT(prev_x, x);
+ prev_x = x;
+
+ SendKeyEvent('b');
+ EXPECT_EQ(WideToUTF16(L"\x05E1\x5E2"L"ab"), textfield_->text());
+ x = GetCursorBounds().x();
+ EXPECT_LT(prev_x, x);
+}
+
+TEST_F(NativeTextfieldViewsTest, TextCursorDisplayInRTLTest) {
+ std::string locale = l10n_util::GetApplicationLocale("");
+ base::i18n::SetICUDefaultLocale("he");
+
+ InitTextfield(Textfield::STYLE_DEFAULT);
+ // LTR-RTL string in RTL context.
+ SendKeyEvent('a');
+ EXPECT_STR_EQ("a", textfield_->text());
+ int x = GetCursorBounds().x();
+ EXPECT_EQ(GetDisplayRect().right() - 1, x);
+ int prev_x = x;
+
+ SendKeyEvent('b');
+ EXPECT_STR_EQ("ab", textfield_->text());
+ x = GetCursorBounds().x();
+ EXPECT_EQ(prev_x, x);
+
+ SendKeyEvent(0x05E1);
+ EXPECT_EQ(WideToUTF16(L"ab\x05E1"), textfield_->text());
+ x = GetCursorBounds().x();
+ EXPECT_GT(prev_x, x);
+ prev_x = x;
+
+ SendKeyEvent(0x05E2);
+ EXPECT_EQ(WideToUTF16(L"ab\x05E1\x5E2"), textfield_->text());
+ x = GetCursorBounds().x();
+ EXPECT_GT(prev_x, x);
+
+ SendKeyEvent(ui::VKEY_A, false, true);
msw 2011/09/09 23:03:24 SetText
+ SendKeyEvent('\n');
+
+ // RTL-LTR string in RTL context.
+ SendKeyEvent(0x05E1);
+ EXPECT_EQ(WideToUTF16(L"\x05E1"), textfield_->text());
+ x = GetCursorBounds().x();
+ prev_x = x;
+
+ SendKeyEvent(0x05E2);
+ EXPECT_EQ(WideToUTF16(L"\x05E1\x05E2"), textfield_->text());
+ x = GetCursorBounds().x();
+ EXPECT_GT(prev_x, x);
+ prev_x = x;
+
+ SendKeyEvent('a');
+ EXPECT_EQ(WideToUTF16(L"\x05E1\x5E2"L"a"), textfield_->text());
+ x = GetCursorBounds().x();
+ EXPECT_EQ(prev_x, x);
+
+ SendKeyEvent('b');
+ EXPECT_EQ(WideToUTF16(L"\x05E1\x5E2"L"ab"), textfield_->text());
+ x = GetCursorBounds().x();
+ EXPECT_EQ(prev_x, x);
+
+ // Reset locale.
+ base::i18n::SetICUDefaultLocale(locale);
+}
+
+TEST_F(NativeTextfieldViewsTest, HitInsideTextAreaTest) {
+ InitTextfield(Textfield::STYLE_DEFAULT);
+ textfield_->SetText(WideToUTF16(L"ab\x05E1\x5E2"));
+ std::vector<gfx::Rect> cursor_bounds;
+
+ // Save each cursor bound.
+ gfx::SelectionModel sel(0, 0, gfx::SelectionModel::LEADING);
+ cursor_bounds.push_back(GetCursorBounds(sel));
+
+ sel = gfx::SelectionModel(1, 0, gfx::SelectionModel::TRAILING);
+ gfx::Rect bound = GetCursorBounds(sel);
+ sel = gfx::SelectionModel(1, 1, gfx::SelectionModel::LEADING);
+ EXPECT_EQ(bound, GetCursorBounds(sel));
+ cursor_bounds.push_back(bound);
+
+ sel = gfx::SelectionModel(2, 1, gfx::SelectionModel::TRAILING);
+ bound = GetCursorBounds(sel);
+ sel = gfx::SelectionModel(4, 3, gfx::SelectionModel::TRAILING);
+ EXPECT_EQ(bound, GetCursorBounds(sel));
+ cursor_bounds.push_back(bound);
+
+ sel = gfx::SelectionModel(3, 2, gfx::SelectionModel::TRAILING);
+ bound = GetCursorBounds(sel);
+ sel = gfx::SelectionModel(3, 3, gfx::SelectionModel::LEADING);
+ EXPECT_EQ(bound, GetCursorBounds(sel));
+ cursor_bounds.push_back(bound);
+
+ sel = gfx::SelectionModel(2, 2, gfx::SelectionModel::LEADING);
+ bound = GetCursorBounds(sel);
+ sel = gfx::SelectionModel(4, 2, gfx::SelectionModel::LEADING);
+ EXPECT_EQ(bound, GetCursorBounds(sel));
+ cursor_bounds.push_back(bound);
+
+ // Expected cursor position when clicking left and right of each character.
+ size_t cursor_pos_expected[] = {0, 1, 1, 2, 4, 3, 3, 2};
+
+ int index = 0;
+ for (int i = 0; i < static_cast<int>(cursor_bounds.size() - 1); ++i) {
+ int half_width = (cursor_bounds[i + 1].x() - cursor_bounds[i].x()) / 2;
+ MouseClick(cursor_bounds[i], half_width / 2);
+ EXPECT_EQ(cursor_pos_expected[index++], textfield_->GetCursorPosition());
+
+ // To avoid trigger double click. Not using sleep() since it takes longer
+ // for the test to run if using sleep().
+ NonClientMouseClick();
+
+ MouseClick(cursor_bounds[i + 1], -(half_width / 2));
msw 2011/09/09 23:03:24 space between '-' and '('
xji 2011/09/12 21:31:48 Done.
+ EXPECT_EQ(cursor_pos_expected[index++], textfield_->GetCursorPosition());
+
+ NonClientMouseClick();
+ }
+}
+
+TEST_F(NativeTextfieldViewsTest, HitOutsideTextAreaTest) {
+ InitTextfield(Textfield::STYLE_DEFAULT);
+
+ // LTR-RTL string in LTR context.
+ textfield_->SetText(WideToUTF16(L"ab\x05E1\x5E2"));
+
+ SendKeyEvent(ui::VKEY_HOME);
+ gfx::Rect bound = GetCursorBounds();
+ MouseClick(bound, -10);
+ EXPECT_EQ(bound, GetCursorBounds());
+
+ SendKeyEvent(ui::VKEY_END);
+ bound = GetCursorBounds();
+ MouseClick(bound, 10);
msw 2011/09/09 23:03:24 Is 10 pixels really longer than the text width? Us
xji 2011/09/12 21:31:48 10 pixel is the x_offset from END position's x-axi
+ EXPECT_EQ(bound, GetCursorBounds());
+
+ NonClientMouseClick();
+
+ // RTL-LTR string in LTR context.
+ textfield_->SetText(WideToUTF16(L"\x05E1\x5E2"L"ab"));
+
+ SendKeyEvent(ui::VKEY_HOME);
+ bound = GetCursorBounds();
+#if defined(OS_WIN)
+ MouseClick(bound, -10);
+#else
+ MouseClick(bound, 10);
+#endif
+ EXPECT_EQ(bound, GetCursorBounds());
+
+ SendKeyEvent(ui::VKEY_END);
+ bound = GetCursorBounds();
+#if defined(OS_WIN)
+ MouseClick(bound, 10);
+#else
+ MouseClick(bound, -10);
+#endif
+ EXPECT_EQ(bound, GetCursorBounds());
+}
+
+TEST_F(NativeTextfieldViewsTest, HitOutsideTextAreaInRTLTest) {
+ std::string locale = l10n_util::GetApplicationLocale("");
+ base::i18n::SetICUDefaultLocale("he");
+
+ InitTextfield(Textfield::STYLE_DEFAULT);
+
+ // RTL-LTR string in RTL context.
+ textfield_->SetText(WideToUTF16(L"\x05E1\x5E2"L"ab"));
+ SendKeyEvent(ui::VKEY_HOME);
+ gfx::Rect bound = GetCursorBounds();
+ MouseClick(bound, 10);
+ EXPECT_EQ(bound, GetCursorBounds());
+
+ SendKeyEvent(ui::VKEY_END);
+ bound = GetCursorBounds();
+ MouseClick(bound, -10);
+ EXPECT_EQ(bound, GetCursorBounds());
+
+ NonClientMouseClick();
+
+ // LTR-RTL string in RTL context.
+ textfield_->SetText(WideToUTF16(L"ab\x05E1\x5E2"));
+ SendKeyEvent(ui::VKEY_HOME);
+ bound = GetCursorBounds();
+#if defined(OS_WIN)
+ MouseClick(bound, 10);
+#else
+ MouseClick(bound, -10);
+#endif
+ EXPECT_EQ(bound, GetCursorBounds());
+
+ SendKeyEvent(ui::VKEY_END);
+ bound = GetCursorBounds();
+#if defined(OS_WIN)
+ MouseClick(bound, -10);
+#else
+ MouseClick(bound, 10);
+#endif
+ EXPECT_EQ(bound, GetCursorBounds());
+
+ // Reset locale.
+ base::i18n::SetICUDefaultLocale(locale);
+}
+
+void OverflowCursorBoundTestVerifier(const gfx::Rect& display,
msw 2011/09/09 23:03:24 A comment would be appreciated: This verifies that
xji 2011/09/12 21:31:48 Done.
+ const gfx::Rect& bound) {
msw 2011/09/09 23:03:24 Indent this line to match the line above.
xji 2011/09/12 21:31:48 Done.
+ EXPECT_LE(display.x(), bound.x());
+ EXPECT_GT(display.right(), bound.right());
+ EXPECT_LE(display.y(), bound.y());
+ EXPECT_GE(display.bottom(), bound.bottom());
+}
+
+TEST_F(NativeTextfieldViewsTest, OverflowTest) {
+ InitTextfield(Textfield::STYLE_DEFAULT);
+
+ string16 str;
+ for (int i = 0; i < 500; ++i)
+ SendKeyEvent('a');
+ SendKeyEvent(0x05E1);
msw 2011/09/09 23:03:24 Don't we have a bug where on overflow from LTR tex
xji 2011/09/12 21:31:48 Yes we do have that bug. This test does not test w
+ gfx::Rect bound = GetCursorBounds();
+ gfx::Rect display = GetDisplayRect();
+ OverflowCursorBoundTestVerifier(display, bound);
+
+ // Test mouse pointing.
+ MouseClick(bound, -1);
+ EXPECT_EQ(500U, textfield_->GetCursorPosition());
+
+ // Clear text.
+ SendKeyEvent(ui::VKEY_A, false, true);
msw 2011/09/09 23:03:24 SetText
+ SendKeyEvent('\n');
+
+ for (int i = 0; i < 500; ++i)
+ SendKeyEvent(0x05E1);
+ SendKeyEvent('a');
+ bound = GetCursorBounds();
+ display = GetDisplayRect();
+ OverflowCursorBoundTestVerifier(display, bound);
+
+ MouseClick(bound, -1);
+ EXPECT_EQ(501U, textfield_->GetCursorPosition());
+}
+
+TEST_F(NativeTextfieldViewsTest, OverflowInRTLTest) {
+ std::string locale = l10n_util::GetApplicationLocale("");
+ base::i18n::SetICUDefaultLocale("he");
+
+ InitTextfield(Textfield::STYLE_DEFAULT);
+
+ string16 str;
+ for (int i = 0; i < 500; ++i)
+ SendKeyEvent('a');
+ SendKeyEvent(0x05E1);
+ gfx::Rect bound = GetCursorBounds();
+ gfx::Rect display = GetDisplayRect();
+ OverflowCursorBoundTestVerifier(display, bound);
+
+ MouseClick(bound, 1);
+ EXPECT_EQ(501U, textfield_->GetCursorPosition());
+
+ // Clear text.
+ SendKeyEvent(ui::VKEY_A, false, true);
msw 2011/09/09 23:03:24 SetText
+ SendKeyEvent('\n');
+
+ for (int i = 0; i < 500; ++i)
+ SendKeyEvent(0x05E1);
+ SendKeyEvent('a');
+ bound = GetCursorBounds();
+ display = GetDisplayRect();
+ OverflowCursorBoundTestVerifier(display, bound);
+
+ MouseClick(bound, 1);
+ EXPECT_EQ(500U, textfield_->GetCursorPosition());
+
+ // Reset locale.
+ base::i18n::SetICUDefaultLocale(locale);
+}
+
} // namespace views

Powered by Google App Engine
This is Rietveld 408576698