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

Unified Diff: ui/views/cocoa/bridged_native_widget_unittest.mm

Issue 1907253002: MacViews: Implement move and move*AndModifySelection commands. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 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: ui/views/cocoa/bridged_native_widget_unittest.mm
diff --git a/ui/views/cocoa/bridged_native_widget_unittest.mm b/ui/views/cocoa/bridged_native_widget_unittest.mm
index fcc59453bb04c61438eaa0224c4c5316ac387753..80f0bd8b6da9030846417db7f7e65f5a2afac526 100644
--- a/ui/views/cocoa/bridged_native_widget_unittest.mm
+++ b/ui/views/cocoa/bridged_native_widget_unittest.mm
@@ -13,6 +13,7 @@
#import "base/mac/sdk_forward_declarations.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
+#include "base/strings/stringprintf.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#import "testing/gtest_mac.h"
@@ -212,12 +213,14 @@ class BridgedNativeWidgetTest : public BridgedNativeWidgetTestBase {
// Install a textfield with input type |text_input_type| in the view hierarchy
// and make it the text input client. Also initializes |dummy_text_view_|.
- void InstallTextField(const std::string& text,
+ void InstallTextField(const base::string16& text,
ui::TextInputType text_input_type);
// Install a textfield with input type ui::TEXT_INPUT_TYPE_TEXT in the view
// hierarchy and make it the text input client. Also initializes
// |dummy_text_view_|.
+ void InstallTextField(const base::string16& text);
+
void InstallTextField(const std::string& text);
// Returns the actual current text for |ns_view_|.
@@ -238,6 +241,11 @@ class BridgedNativeWidgetTest : public BridgedNativeWidgetTestBase {
// Perform command |sel| on |ns_view_| and |dummy_text_view_|.
void PerformCommand(SEL sel);
+ // Make selection from |start| to |end| on installed textfield and
+ // |dummy_text_view_|. If |start| > |end|, extend selection to left from
+ // |start|.
+ void MakeSelection(int start, int end);
+
// testing::Test:
void SetUp() override;
void TearDown() override;
@@ -271,11 +279,19 @@ BridgedNativeWidgetTest::BridgedNativeWidgetTest() {
BridgedNativeWidgetTest::~BridgedNativeWidgetTest() {
}
+void BridgedNativeWidgetTest::InstallTextField(const base::string16& text) {
+ InstallTextField(text, ui::TEXT_INPUT_TYPE_TEXT);
+}
+
+void BridgedNativeWidgetTest::InstallTextField(const std::string& text) {
+ InstallTextField(base::ASCIIToUTF16(text), ui::TEXT_INPUT_TYPE_TEXT);
+}
+
void BridgedNativeWidgetTest::InstallTextField(
- const std::string& text,
+ const base::string16& text,
ui::TextInputType text_input_type) {
Textfield* textfield = new Textfield();
- textfield->SetText(ASCIIToUTF16(text));
+ textfield->SetText(text);
textfield->SetTextInputType(text_input_type);
view_->RemoveAllChildViews(true);
view_->AddChildView(textfield);
@@ -290,11 +306,7 @@ void BridgedNativeWidgetTest::InstallTextField(
// Initialize the dummy text view.
dummy_text_view_.reset([[NSTextView alloc] initWithFrame:NSZeroRect]);
- [dummy_text_view_ setString:SysUTF8ToNSString(text)];
-}
-
-void BridgedNativeWidgetTest::InstallTextField(const std::string& text) {
- InstallTextField(text, ui::TEXT_INPUT_TYPE_TEXT);
+ [dummy_text_view_ setString:SysUTF16ToNSString(text)];
}
NSString* BridgedNativeWidgetTest::GetActualText() {
@@ -330,6 +342,22 @@ void BridgedNativeWidgetTest::PerformCommand(SEL sel) {
[dummy_text_view_ doCommandBySelector:sel];
}
+void BridgedNativeWidgetTest::MakeSelection(int start, int end) {
+ ui::TextInputClient* client = [ns_view_ textInputClient];
+ client->SetSelectionRange(gfx::Range(start, end));
+
+ // NSTextView does not support specifying the selection "direction" i.e. the
+ // leading edge of selection. Hence we extend the selection from |start| to
+ // |end|.
+ [dummy_text_view_ setSelectedRange:NSMakeRange(start, 0)];
+ SEL sel = start > end ? @selector(moveBackwardAndModifySelection:)
+ : @selector(moveForwardAndModifySelection:);
+ size_t delta = std::abs(end - start);
+
+ for (size_t i = 0; i < delta; i++)
+ [dummy_text_view_ doCommandBySelector:sel];
+}
+
void BridgedNativeWidgetTest::SetUp() {
BridgedNativeWidgetTestBase::SetUp();
@@ -550,7 +578,7 @@ TEST_F(BridgedNativeWidgetInitTest, ShadowType) {
// Ensure a nil NSTextInputContext is returned when the ui::TextInputClient is
// not editable, a password field, or unset.
TEST_F(BridgedNativeWidgetTest, InputContext) {
- const std::string test_string = "test_str";
+ const base::string16 test_string = base::ASCIIToUTF16("test_str");
InstallTextField(test_string, ui::TEXT_INPUT_TYPE_PASSWORD);
EXPECT_FALSE([ns_view_ inputContext]);
InstallTextField(test_string, ui::TEXT_INPUT_TYPE_TEXT);
@@ -873,6 +901,89 @@ TEST_F(BridgedNativeWidgetTest, TextInput_DeleteToEndOfParagraph) {
TestDeleteEnd(@selector(deleteToEndOfParagraph:));
}
+TEST_F(BridgedNativeWidgetTest, EditingCommands) {
+ NSArray* selectors = @[
+ @"moveForward:", @"moveRight:", @"moveBackward:", @"moveLeft:", @"moveUp:",
+ @"moveDown:", @"moveWordForward:", @"moveWordBackward:",
+ @"moveToBeginningOfLine:", @"moveToEndOfLine:",
+ @"moveToBeginningOfParagraph:", @"moveToEndOfParagraph:",
+ @"moveToEndOfDocument:", @"moveToBeginningOfDocument:", @"pageDown:",
+ @"pageUp:", @"moveBackwardAndModifySelection:",
+ @"moveForwardAndModifySelection:",
+ // @"moveWordForwardAndModifySelection:",
+ // @"moveWordBackwardAndModifySelection:",
+ @"moveUpAndModifySelection:", @"moveDownAndModifySelection:",
+ // @"moveToBeginningOfLineAndModifySelection:",
+ // @"moveToEndOfLineAndModifySelection:",
+ // @"moveToBeginningOfParagraphAndModifySelection:",
+ // @"moveToEndOfParagraphAndModifySelection:",
+ // @"moveToEndOfDocumentAndModifySelection:",
+ // @"moveToBeginningOfDocumentAndModifySelection:",
+ @"pageDownAndModifySelection:", @"pageUpAndModifySelection:",
+ // @"moveParagraphForwardAndModifySelection:",
+ // @"moveParagraphBackwardAndModifySelection:",
+ @"moveWordRight:", @"moveWordLeft:", @"moveRightAndModifySelection:",
+ @"moveLeftAndModifySelection:",
+ // @"moveWordRightAndModifySelection:",
+ // @"moveWordLeftAndModifySelection:",
+ @"moveToLeftEndOfLine:", @"moveToRightEndOfLine:",
+ // @"moveToLeftEndOfLineAndModifySelection:",
+ // @"moveToRightEndOfLineAndModifySelection:",
+ @"deleteForward:", @"deleteBackward:", @"deleteWordForward:",
+ @"deleteWordBackward:", @"deleteToBeginningOfLine:", @"deleteToEndOfLine:",
+ @"deleteToBeginningOfParagraph:", @"deleteToEndOfParagraph:",
+ @"cancelOperation:"
+ ];
+
+ struct {
+ const std::wstring test_string;
+ bool rtl;
+ } cases[] =
+ {{L"abc def", false},
+ {L"\x0634\x0632\x0630 \x064A\x062B\x0628", true}};
+
+ for (auto test_case : cases) {
+ for (NSString* selector_string in selectors) {
+ SEL sel = NSSelectorFromString(selector_string);
+ const int len = test_case.test_string.length();
+ for (int i = 0; i <= len; i++) {
+ for (int j = 0; j <= len; j++) {
+ SCOPED_TRACE(base::StringPrintf(
+ "Testing range [%d-%d] for case %s and selector %s\n", i, j,
+ base::WideToUTF8(test_case.test_string).c_str(),
+ base::SysNSStringToUTF8(selector_string).c_str()));
+
+ InstallTextField(base::WideToUTF16(test_case.test_string));
+ MakeSelection(i, j);
+ EXPECT_EQ_RANGE_3(NSMakeRange(std::min(i, j), std::abs(i - j)),
+ GetExpectedSelectionRange(),
+ GetActualSelectionRange());
+
+ PerformCommand(sel);
+ EXPECT_NSEQ(GetExpectedText(), GetActualText());
+
+ // This is another case where NSTextView behaves a bit weirdly. Turns
+ // out for RTL text, move[Left/Right]AndModifySelection and
+ // move[Forward/Backward]AndModifySelection do not share selection
+ // "direction". For eg say current rtl text is "abc|". On doing
+ // moveForwardAndModifySelection: twice, text becomes "a|bc|". Now if
+ // we do moveLeftAndModifySelection, text should become "|abc|" but
+ // instead it becomes "a|b|c". Blink also behaves similarly to our
+ // implementation in this case.
+ if (!(test_case.rtl &&
+ ([selector_string
+ isEqualToString:@"moveRightAndModifySelection:"] ||
+ [selector_string
+ isEqualToString:@"moveLeftAndModifySelection:"]))) {
+ EXPECT_EQ_RANGE(GetExpectedSelectionRange(),
+ GetActualSelectionRange());
+ }
+ }
+ }
+ }
+ }
+}
+
// Test firstRectForCharacterRange:actualRange for cases where query range is
// empty or outside composition range.
TEST_F(BridgedNativeWidgetTest, TextInput_FirstRectForCharacterRange_Caret) {

Powered by Google App Engine
This is Rietveld 408576698