| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 #import "ui/views/cocoa/bridged_native_widget.h" | 5 #import "ui/views/cocoa/bridged_native_widget.h" |
| 6 | 6 |
| 7 #import <Cocoa/Cocoa.h> | 7 #import <Cocoa/Cocoa.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 | 10 |
| 11 #import "base/mac/foundation_util.h" | 11 #import "base/mac/foundation_util.h" |
| 12 #import "base/mac/mac_util.h" | 12 #import "base/mac/mac_util.h" |
| 13 #import "base/mac/sdk_forward_declarations.h" | 13 #import "base/mac/sdk_forward_declarations.h" |
| 14 #include "base/macros.h" | 14 #include "base/macros.h" |
| 15 #include "base/message_loop/message_loop.h" | 15 #include "base/message_loop/message_loop.h" |
| 16 #include "base/strings/stringprintf.h" |
| 16 #include "base/strings/sys_string_conversions.h" | 17 #include "base/strings/sys_string_conversions.h" |
| 17 #include "base/strings/utf_string_conversions.h" | 18 #include "base/strings/utf_string_conversions.h" |
| 18 #import "testing/gtest_mac.h" | 19 #import "testing/gtest_mac.h" |
| 19 #import "ui/base/cocoa/window_size_constants.h" | 20 #import "ui/base/cocoa/window_size_constants.h" |
| 20 #include "ui/base/ime/input_method.h" | 21 #include "ui/base/ime/input_method.h" |
| 21 #import "ui/gfx/mac/coordinate_conversion.h" | 22 #import "ui/gfx/mac/coordinate_conversion.h" |
| 22 #import "ui/gfx/test/ui_cocoa_test_helper.h" | 23 #import "ui/gfx/test/ui_cocoa_test_helper.h" |
| 23 #import "ui/views/cocoa/bridged_content_view.h" | 24 #import "ui/views/cocoa/bridged_content_view.h" |
| 24 #import "ui/views/cocoa/native_widget_mac_nswindow.h" | 25 #import "ui/views/cocoa/native_widget_mac_nswindow.h" |
| 25 #import "ui/views/cocoa/views_nswindow_delegate.h" | 26 #import "ui/views/cocoa/views_nswindow_delegate.h" |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 Widget::InitParams init_params_; | 206 Widget::InitParams init_params_; |
| 206 }; | 207 }; |
| 207 | 208 |
| 208 class BridgedNativeWidgetTest : public BridgedNativeWidgetTestBase { | 209 class BridgedNativeWidgetTest : public BridgedNativeWidgetTestBase { |
| 209 public: | 210 public: |
| 210 BridgedNativeWidgetTest(); | 211 BridgedNativeWidgetTest(); |
| 211 ~BridgedNativeWidgetTest() override; | 212 ~BridgedNativeWidgetTest() override; |
| 212 | 213 |
| 213 // Install a textfield with input type |text_input_type| in the view hierarchy | 214 // Install a textfield with input type |text_input_type| in the view hierarchy |
| 214 // and make it the text input client. Also initializes |dummy_text_view_|. | 215 // and make it the text input client. Also initializes |dummy_text_view_|. |
| 215 void InstallTextField(const std::string& text, | 216 void InstallTextField(const base::string16& text, |
| 216 ui::TextInputType text_input_type); | 217 ui::TextInputType text_input_type); |
| 217 | 218 |
| 218 // Install a textfield with input type ui::TEXT_INPUT_TYPE_TEXT in the view | 219 // Install a textfield with input type ui::TEXT_INPUT_TYPE_TEXT in the view |
| 219 // hierarchy and make it the text input client. Also initializes | 220 // hierarchy and make it the text input client. Also initializes |
| 220 // |dummy_text_view_|. | 221 // |dummy_text_view_|. |
| 222 void InstallTextField(const base::string16& text); |
| 223 |
| 221 void InstallTextField(const std::string& text); | 224 void InstallTextField(const std::string& text); |
| 222 | 225 |
| 223 // Returns the actual current text for |ns_view_|. | 226 // Returns the actual current text for |ns_view_|. |
| 224 NSString* GetActualText(); | 227 NSString* GetActualText(); |
| 225 | 228 |
| 226 // Returns the expected current text from |dummy_text_view_|. | 229 // Returns the expected current text from |dummy_text_view_|. |
| 227 NSString* GetExpectedText(); | 230 NSString* GetExpectedText(); |
| 228 | 231 |
| 229 // Returns the actual selection range for |ns_view_|. | 232 // Returns the actual selection range for |ns_view_|. |
| 230 NSRange GetActualSelectionRange(); | 233 NSRange GetActualSelectionRange(); |
| 231 | 234 |
| 232 // Returns the expected selection range from |dummy_text_view_|. | 235 // Returns the expected selection range from |dummy_text_view_|. |
| 233 NSRange GetExpectedSelectionRange(); | 236 NSRange GetExpectedSelectionRange(); |
| 234 | 237 |
| 235 // Set the selection range for the installed textfield and |dummy_text_view_|. | 238 // Set the selection range for the installed textfield and |dummy_text_view_|. |
| 236 void SetSelectionRange(NSRange range); | 239 void SetSelectionRange(NSRange range); |
| 237 | 240 |
| 238 // Perform command |sel| on |ns_view_| and |dummy_text_view_|. | 241 // Perform command |sel| on |ns_view_| and |dummy_text_view_|. |
| 239 void PerformCommand(SEL sel); | 242 void PerformCommand(SEL sel); |
| 240 | 243 |
| 244 // Make selection from |start| to |end| on installed views::Textfield and |
| 245 // |dummy_text_view_|. If |start| > |end|, extend selection to left from |
| 246 // |start|. |
| 247 void MakeSelection(int start, int end); |
| 248 |
| 241 // testing::Test: | 249 // testing::Test: |
| 242 void SetUp() override; | 250 void SetUp() override; |
| 243 void TearDown() override; | 251 void TearDown() override; |
| 244 | 252 |
| 245 protected: | 253 protected: |
| 246 // Test delete to beginning of line or paragraph based on |sel|. |sel| can be | 254 // Test delete to beginning of line or paragraph based on |sel|. |sel| can be |
| 247 // either deleteToBeginningOfLine: or deleteToBeginningOfParagraph:. | 255 // either deleteToBeginningOfLine: or deleteToBeginningOfParagraph:. |
| 248 void TestDeleteBeginning(SEL sel); | 256 void TestDeleteBeginning(SEL sel); |
| 249 | 257 |
| 250 // Test delete to end of line or paragraph based on |sel|. |sel| can be | 258 // Test delete to end of line or paragraph based on |sel|. |sel| can be |
| 251 // either deleteToEndOfLine: or deleteToEndOfParagraph:. | 259 // either deleteToEndOfLine: or deleteToEndOfParagraph:. |
| 252 void TestDeleteEnd(SEL sel); | 260 void TestDeleteEnd(SEL sel); |
| 253 | 261 |
| 262 // Test editing commands in |selectors| against the expectations set by |
| 263 // |dummy_text_view_|. This is done by selecting every substring within a set |
| 264 // of test strings (both RTL and non-RTL) and performing every selector on |
| 265 // both the NSTextView and the BridgedContentView hosting a focused |
| 266 // views::TextField to ensure the resulting text and selection ranges match. |
| 267 // |selectors| is an NSArray of NSStrings. |
| 268 void TestEditingCommands(NSArray* selectors); |
| 269 |
| 254 std::unique_ptr<views::View> view_; | 270 std::unique_ptr<views::View> view_; |
| 255 | 271 |
| 256 // Weak. Owned by bridge(). | 272 // Weak. Owned by bridge(). |
| 257 BridgedContentView* ns_view_; | 273 BridgedContentView* ns_view_; |
| 258 | 274 |
| 259 // An NSTextView which helps set the expectations for our tests. | 275 // An NSTextView which helps set the expectations for our tests. |
| 260 base::scoped_nsobject<NSTextView> dummy_text_view_; | 276 base::scoped_nsobject<NSTextView> dummy_text_view_; |
| 261 | 277 |
| 262 base::MessageLoopForUI message_loop_; | 278 base::MessageLoopForUI message_loop_; |
| 263 | 279 |
| 264 private: | 280 private: |
| 265 DISALLOW_COPY_AND_ASSIGN(BridgedNativeWidgetTest); | 281 DISALLOW_COPY_AND_ASSIGN(BridgedNativeWidgetTest); |
| 266 }; | 282 }; |
| 267 | 283 |
| 268 BridgedNativeWidgetTest::BridgedNativeWidgetTest() { | 284 BridgedNativeWidgetTest::BridgedNativeWidgetTest() { |
| 269 } | 285 } |
| 270 | 286 |
| 271 BridgedNativeWidgetTest::~BridgedNativeWidgetTest() { | 287 BridgedNativeWidgetTest::~BridgedNativeWidgetTest() { |
| 272 } | 288 } |
| 273 | 289 |
| 274 void BridgedNativeWidgetTest::InstallTextField( | 290 void BridgedNativeWidgetTest::InstallTextField( |
| 275 const std::string& text, | 291 const base::string16& text, |
| 276 ui::TextInputType text_input_type) { | 292 ui::TextInputType text_input_type) { |
| 277 Textfield* textfield = new Textfield(); | 293 Textfield* textfield = new Textfield(); |
| 278 textfield->SetText(ASCIIToUTF16(text)); | 294 textfield->SetText(text); |
| 279 textfield->SetTextInputType(text_input_type); | 295 textfield->SetTextInputType(text_input_type); |
| 280 view_->RemoveAllChildViews(true); | 296 view_->RemoveAllChildViews(true); |
| 281 view_->AddChildView(textfield); | 297 view_->AddChildView(textfield); |
| 282 textfield->SetBoundsRect(init_params_.bounds); | 298 textfield->SetBoundsRect(init_params_.bounds); |
| 283 | 299 |
| 284 // Request focus so the InputMethod can dispatch events to the RootView, and | 300 // Request focus so the InputMethod can dispatch events to the RootView, and |
| 285 // have them delivered to the textfield. Note that focusing a textfield | 301 // have them delivered to the textfield. Note that focusing a textfield |
| 286 // schedules a task to flash the cursor, so this requires |message_loop_|. | 302 // schedules a task to flash the cursor, so this requires |message_loop_|. |
| 287 textfield->RequestFocus(); | 303 textfield->RequestFocus(); |
| 288 | 304 |
| 289 [ns_view_ setTextInputClient:textfield]; | 305 [ns_view_ setTextInputClient:textfield]; |
| 290 | 306 |
| 291 // Initialize the dummy text view. | 307 // Initialize the dummy text view. |
| 292 dummy_text_view_.reset([[NSTextView alloc] initWithFrame:NSZeroRect]); | 308 dummy_text_view_.reset([[NSTextView alloc] initWithFrame:NSZeroRect]); |
| 293 [dummy_text_view_ setString:SysUTF8ToNSString(text)]; | 309 [dummy_text_view_ setString:SysUTF16ToNSString(text)]; |
| 310 } |
| 311 |
| 312 void BridgedNativeWidgetTest::InstallTextField(const base::string16& text) { |
| 313 InstallTextField(text, ui::TEXT_INPUT_TYPE_TEXT); |
| 294 } | 314 } |
| 295 | 315 |
| 296 void BridgedNativeWidgetTest::InstallTextField(const std::string& text) { | 316 void BridgedNativeWidgetTest::InstallTextField(const std::string& text) { |
| 297 InstallTextField(text, ui::TEXT_INPUT_TYPE_TEXT); | 317 InstallTextField(base::ASCIIToUTF16(text), ui::TEXT_INPUT_TYPE_TEXT); |
| 298 } | 318 } |
| 299 | 319 |
| 300 NSString* BridgedNativeWidgetTest::GetActualText() { | 320 NSString* BridgedNativeWidgetTest::GetActualText() { |
| 301 NSRange range = NSMakeRange(0, NSUIntegerMax); | 321 NSRange range = NSMakeRange(0, NSUIntegerMax); |
| 302 return [[ns_view_ attributedSubstringForProposedRange:range | 322 return [[ns_view_ attributedSubstringForProposedRange:range |
| 303 actualRange:nullptr] string]; | 323 actualRange:nullptr] string]; |
| 304 } | 324 } |
| 305 | 325 |
| 306 NSString* BridgedNativeWidgetTest::GetExpectedText() { | 326 NSString* BridgedNativeWidgetTest::GetExpectedText() { |
| 307 NSRange range = NSMakeRange(0, NSUIntegerMax); | 327 NSRange range = NSMakeRange(0, NSUIntegerMax); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 323 client->SetSelectionRange(gfx::Range(range)); | 343 client->SetSelectionRange(gfx::Range(range)); |
| 324 | 344 |
| 325 [dummy_text_view_ setSelectedRange:range]; | 345 [dummy_text_view_ setSelectedRange:range]; |
| 326 } | 346 } |
| 327 | 347 |
| 328 void BridgedNativeWidgetTest::PerformCommand(SEL sel) { | 348 void BridgedNativeWidgetTest::PerformCommand(SEL sel) { |
| 329 [ns_view_ doCommandBySelector:sel]; | 349 [ns_view_ doCommandBySelector:sel]; |
| 330 [dummy_text_view_ doCommandBySelector:sel]; | 350 [dummy_text_view_ doCommandBySelector:sel]; |
| 331 } | 351 } |
| 332 | 352 |
| 353 void BridgedNativeWidgetTest::MakeSelection(int start, int end) { |
| 354 ui::TextInputClient* client = [ns_view_ textInputClient]; |
| 355 client->SetSelectionRange(gfx::Range(start, end)); |
| 356 |
| 357 // Though NSTextView has a selectionAffinity property, it does not seem to |
| 358 // correspond to the selection direction. Hence we extend the selection from |
| 359 //|start| to |end|. |
| 360 [dummy_text_view_ setSelectedRange:NSMakeRange(start, 0)]; |
| 361 SEL sel = start > end ? @selector(moveBackwardAndModifySelection:) |
| 362 : @selector(moveForwardAndModifySelection:); |
| 363 size_t delta = std::abs(end - start); |
| 364 |
| 365 for (size_t i = 0; i < delta; i++) |
| 366 [dummy_text_view_ doCommandBySelector:sel]; |
| 367 } |
| 368 |
| 333 void BridgedNativeWidgetTest::SetUp() { | 369 void BridgedNativeWidgetTest::SetUp() { |
| 334 BridgedNativeWidgetTestBase::SetUp(); | 370 BridgedNativeWidgetTestBase::SetUp(); |
| 335 | 371 |
| 336 view_.reset(new views::internal::RootView(widget_.get())); | 372 view_.reset(new views::internal::RootView(widget_.get())); |
| 337 base::scoped_nsobject<NSWindow> window([test_window() retain]); | 373 base::scoped_nsobject<NSWindow> window([test_window() retain]); |
| 338 | 374 |
| 339 // BridgedNativeWidget expects to be initialized with a hidden (deferred) | 375 // BridgedNativeWidget expects to be initialized with a hidden (deferred) |
| 340 // window. | 376 // window. |
| 341 [window orderOut:nil]; | 377 [window orderOut:nil]; |
| 342 EXPECT_FALSE([window delegate]); | 378 EXPECT_FALSE([window delegate]); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 | 446 |
| 411 // Make a selection as- "|foo |bar". | 447 // Make a selection as- "|foo |bar". |
| 412 SetSelectionRange(NSMakeRange(0, 4)); | 448 SetSelectionRange(NSMakeRange(0, 4)); |
| 413 PerformCommand(sel); | 449 PerformCommand(sel); |
| 414 // Verify only the selection is deleted so that the state is "|bar". | 450 // Verify only the selection is deleted so that the state is "|bar". |
| 415 EXPECT_NSEQ_3(@"bar", GetExpectedText(), GetActualText()); | 451 EXPECT_NSEQ_3(@"bar", GetExpectedText(), GetActualText()); |
| 416 EXPECT_EQ_RANGE_3(NSMakeRange(0, 0), GetExpectedSelectionRange(), | 452 EXPECT_EQ_RANGE_3(NSMakeRange(0, 0), GetExpectedSelectionRange(), |
| 417 GetActualSelectionRange()); | 453 GetActualSelectionRange()); |
| 418 } | 454 } |
| 419 | 455 |
| 456 void BridgedNativeWidgetTest::TestEditingCommands(NSArray* selectors) { |
| 457 const base::string16 test_strings[] = { |
| 458 base::WideToUTF16(L"ab c"), |
| 459 base::WideToUTF16(L"\x0634\x0632 \x064A") // RTL string. |
| 460 }; |
| 461 |
| 462 for (const base::string16& test_string : test_strings) { |
| 463 for (NSString* selector_string in selectors) { |
| 464 SEL sel = NSSelectorFromString(selector_string); |
| 465 const int len = test_string.length(); |
| 466 for (int i = 0; i <= len; i++) { |
| 467 for (int j = 0; j <= len; j++) { |
| 468 SCOPED_TRACE(base::StringPrintf( |
| 469 "Testing range [%d-%d] for case %s and selector %s\n", i, j, |
| 470 base::UTF16ToUTF8(test_string).c_str(), |
| 471 base::SysNSStringToUTF8(selector_string).c_str())); |
| 472 |
| 473 InstallTextField(test_string); |
| 474 MakeSelection(i, j); |
| 475 EXPECT_EQ_RANGE_3(NSMakeRange(std::min(i, j), std::abs(i - j)), |
| 476 GetExpectedSelectionRange(), |
| 477 GetActualSelectionRange()); |
| 478 |
| 479 PerformCommand(sel); |
| 480 EXPECT_NSEQ(GetExpectedText(), GetActualText()); |
| 481 EXPECT_EQ_RANGE(GetExpectedSelectionRange(), |
| 482 GetActualSelectionRange()); |
| 483 } |
| 484 } |
| 485 } |
| 486 } |
| 487 } |
| 488 |
| 420 // The TEST_VIEW macro expects the view it's testing to have a superview. In | 489 // The TEST_VIEW macro expects the view it's testing to have a superview. In |
| 421 // these tests, the NSView bridge is a contentView, at the root. These mimic | 490 // these tests, the NSView bridge is a contentView, at the root. These mimic |
| 422 // what TEST_VIEW usually does. | 491 // what TEST_VIEW usually does. |
| 423 TEST_F(BridgedNativeWidgetTest, BridgedNativeWidgetTest_TestViewAddRemove) { | 492 TEST_F(BridgedNativeWidgetTest, BridgedNativeWidgetTest_TestViewAddRemove) { |
| 424 base::scoped_nsobject<BridgedContentView> view([bridge()->ns_view() retain]); | 493 base::scoped_nsobject<BridgedContentView> view([bridge()->ns_view() retain]); |
| 425 EXPECT_NSEQ([test_window() contentView], view); | 494 EXPECT_NSEQ([test_window() contentView], view); |
| 426 EXPECT_NSEQ(test_window(), [view window]); | 495 EXPECT_NSEQ(test_window(), [view window]); |
| 427 | 496 |
| 428 // The superview of a contentView is an NSNextStepFrame. | 497 // The superview of a contentView is an NSNextStepFrame. |
| 429 EXPECT_TRUE([view superview]); | 498 EXPECT_TRUE([view superview]); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 543 PerformInit(); | 612 PerformInit(); |
| 544 EXPECT_TRUE([window_ hasShadow]); // Preserves shadow. | 613 EXPECT_TRUE([window_ hasShadow]); // Preserves shadow. |
| 545 | 614 |
| 546 window_.reset(); | 615 window_.reset(); |
| 547 widget_.reset(); | 616 widget_.reset(); |
| 548 } | 617 } |
| 549 | 618 |
| 550 // Ensure a nil NSTextInputContext is returned when the ui::TextInputClient is | 619 // Ensure a nil NSTextInputContext is returned when the ui::TextInputClient is |
| 551 // not editable, a password field, or unset. | 620 // not editable, a password field, or unset. |
| 552 TEST_F(BridgedNativeWidgetTest, InputContext) { | 621 TEST_F(BridgedNativeWidgetTest, InputContext) { |
| 553 const std::string test_string = "test_str"; | 622 const base::string16 test_string = base::ASCIIToUTF16("test_str"); |
| 554 InstallTextField(test_string, ui::TEXT_INPUT_TYPE_PASSWORD); | 623 InstallTextField(test_string, ui::TEXT_INPUT_TYPE_PASSWORD); |
| 555 EXPECT_FALSE([ns_view_ inputContext]); | 624 EXPECT_FALSE([ns_view_ inputContext]); |
| 556 InstallTextField(test_string, ui::TEXT_INPUT_TYPE_TEXT); | 625 InstallTextField(test_string, ui::TEXT_INPUT_TYPE_TEXT); |
| 557 EXPECT_TRUE([ns_view_ inputContext]); | 626 EXPECT_TRUE([ns_view_ inputContext]); |
| 558 [ns_view_ setTextInputClient:nil]; | 627 [ns_view_ setTextInputClient:nil]; |
| 559 EXPECT_FALSE([ns_view_ inputContext]); | 628 EXPECT_FALSE([ns_view_ inputContext]); |
| 560 InstallTextField(test_string, ui::TEXT_INPUT_TYPE_NONE); | 629 InstallTextField(test_string, ui::TEXT_INPUT_TYPE_NONE); |
| 561 EXPECT_FALSE([ns_view_ inputContext]); | 630 EXPECT_FALSE([ns_view_ inputContext]); |
| 562 } | 631 } |
| 563 | 632 |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 866 } | 935 } |
| 867 | 936 |
| 868 TEST_F(BridgedNativeWidgetTest, TextInput_DeleteToBeginningOfParagraph) { | 937 TEST_F(BridgedNativeWidgetTest, TextInput_DeleteToBeginningOfParagraph) { |
| 869 TestDeleteBeginning(@selector(deleteToBeginningOfParagraph:)); | 938 TestDeleteBeginning(@selector(deleteToBeginningOfParagraph:)); |
| 870 } | 939 } |
| 871 | 940 |
| 872 TEST_F(BridgedNativeWidgetTest, TextInput_DeleteToEndOfParagraph) { | 941 TEST_F(BridgedNativeWidgetTest, TextInput_DeleteToEndOfParagraph) { |
| 873 TestDeleteEnd(@selector(deleteToEndOfParagraph:)); | 942 TestDeleteEnd(@selector(deleteToEndOfParagraph:)); |
| 874 } | 943 } |
| 875 | 944 |
| 945 // Test move commands against expectations set by |dummy_text_view_|. |
| 946 TEST_F(BridgedNativeWidgetTest, TextInput_MoveEditingCommands) { |
| 947 NSArray* selectors = @[ |
| 948 @"moveForward:", |
| 949 @"moveRight:", |
| 950 @"moveBackward:", |
| 951 @"moveLeft:", |
| 952 @"moveUp:", |
| 953 @"moveDown:", |
| 954 @"moveWordForward:", |
| 955 @"moveWordBackward:", |
| 956 @"moveToBeginningOfLine:", |
| 957 @"moveToEndOfLine:", |
| 958 @"moveToBeginningOfParagraph:", |
| 959 @"moveToEndOfParagraph:", |
| 960 @"moveToEndOfDocument:", |
| 961 @"moveToBeginningOfDocument:", |
| 962 @"pageDown:", |
| 963 @"pageUp:", |
| 964 @"moveWordRight:", |
| 965 @"moveWordLeft:", |
| 966 @"moveToLeftEndOfLine:", |
| 967 @"moveToRightEndOfLine:" |
| 968 ]; |
| 969 TestEditingCommands(selectors); |
| 970 } |
| 971 |
| 972 // Todo(karandeepb): Enable this test once the behavior of all move and select |
| 973 // commands are fixed. |
| 974 // Test move and select commands against expectations set by |dummy_text_view_|. |
| 975 TEST_F(BridgedNativeWidgetTest, |
| 976 TextInput_MoveAndSelectEditingCommands_DISABLED) { |
| 977 NSArray* selectors = @[ |
| 978 @"moveBackwardAndModifySelection:", |
| 979 @"moveForwardAndModifySelection:", |
| 980 @"moveWordForwardAndModifySelection:", |
| 981 @"moveWordBackwardAndModifySelection:", |
| 982 @"moveUpAndModifySelection:", |
| 983 @"moveDownAndModifySelection:", |
| 984 @"moveToBeginningOfLineAndModifySelection:", |
| 985 @"moveToEndOfLineAndModifySelection:", |
| 986 @"moveToBeginningOfParagraphAndModifySelection:", |
| 987 @"moveToEndOfParagraphAndModifySelection:", |
| 988 @"moveToEndOfDocumentAndModifySelection:", |
| 989 @"moveToBeginningOfDocumentAndModifySelection:", |
| 990 @"pageDownAndModifySelection:", |
| 991 @"pageUpAndModifySelection:", |
| 992 @"moveParagraphForwardAndModifySelection:", |
| 993 @"moveParagraphBackwardAndModifySelection:", |
| 994 @"moveRightAndModifySelection:", |
| 995 @"moveLeftAndModifySelection:", |
| 996 @"moveWordRightAndModifySelection:", |
| 997 @"moveWordLeftAndModifySelection:", |
| 998 @"moveToLeftEndOfLineAndModifySelection:", |
| 999 @"moveToRightEndOfLineAndModifySelection:" |
| 1000 ]; |
| 1001 TestEditingCommands(selectors); |
| 1002 } |
| 1003 |
| 1004 // Test delete commands against expectations set by |dummy_text_view_|. |
| 1005 TEST_F(BridgedNativeWidgetTest, TextInput_DeleteCommands) { |
| 1006 NSArray* selectors = @[ |
| 1007 @"deleteForward:", @"deleteBackward:", @"deleteWordForward:", |
| 1008 @"deleteWordBackward:", @"deleteToBeginningOfLine:", @"deleteToEndOfLine:", |
| 1009 @"deleteToBeginningOfParagraph:", @"deleteToEndOfParagraph:" |
| 1010 ]; |
| 1011 TestEditingCommands(selectors); |
| 1012 } |
| 1013 |
| 876 // Test firstRectForCharacterRange:actualRange for cases where query range is | 1014 // Test firstRectForCharacterRange:actualRange for cases where query range is |
| 877 // empty or outside composition range. | 1015 // empty or outside composition range. |
| 878 TEST_F(BridgedNativeWidgetTest, TextInput_FirstRectForCharacterRange_Caret) { | 1016 TEST_F(BridgedNativeWidgetTest, TextInput_FirstRectForCharacterRange_Caret) { |
| 879 InstallTextField(""); | 1017 InstallTextField(""); |
| 880 ui::TextInputClient* client = [ns_view_ textInputClient]; | 1018 ui::TextInputClient* client = [ns_view_ textInputClient]; |
| 881 | 1019 |
| 882 // No composition. Ensure bounds and range corresponding to the current caret | 1020 // No composition. Ensure bounds and range corresponding to the current caret |
| 883 // position are returned. | 1021 // position are returned. |
| 884 // Initially selection range will be [0, 0]. | 1022 // Initially selection range will be [0, 0]. |
| 885 NSRange caret_range = NSMakeRange(0, 0); | 1023 NSRange caret_range = NSMakeRange(0, 0); |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1030 [center postNotificationName:NSWindowDidExitFullScreenNotification | 1168 [center postNotificationName:NSWindowDidExitFullScreenNotification |
| 1031 object:window]; | 1169 object:window]; |
| 1032 EXPECT_EQ(1, [window ignoredToggleFullScreenCount]); // No change. | 1170 EXPECT_EQ(1, [window ignoredToggleFullScreenCount]); // No change. |
| 1033 EXPECT_FALSE(bridge()->target_fullscreen_state()); | 1171 EXPECT_FALSE(bridge()->target_fullscreen_state()); |
| 1034 | 1172 |
| 1035 widget_->CloseNow(); | 1173 widget_->CloseNow(); |
| 1036 } | 1174 } |
| 1037 | 1175 |
| 1038 } // namespace test | 1176 } // namespace test |
| 1039 } // namespace views | 1177 } // namespace views |
| OLD | NEW |