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

Side by Side Diff: ui/views/cocoa/bridged_native_widget_unittest.mm

Issue 1912993002: MacViews: Implement NSResponder deletion action messages. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Change "Depends on Patchset". 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 unified diff | Download patch
« no previous file with comments | « ui/views/cocoa/bridged_content_view.mm ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 void InstallTextField(const std::string& text, 200 void InstallTextField(const std::string& text,
201 ui::TextInputType text_input_type); 201 ui::TextInputType text_input_type);
202 202
203 // Install a textfield with input type ui::TEXT_INPUT_TYPE_TEXT in the view 203 // Install a textfield with input type ui::TEXT_INPUT_TYPE_TEXT in the view
204 // hierarchy and make it the text input client. 204 // hierarchy and make it the text input client.
205 void InstallTextField(const std::string& text); 205 void InstallTextField(const std::string& text);
206 206
207 // Returns the current text as std::string. 207 // Returns the current text as std::string.
208 std::string GetText(); 208 std::string GetText();
209 209
210 // Set the selection range for the installed textfield.
211 void SetSelectionRange(const gfx::Range& range);
212
210 // testing::Test: 213 // testing::Test:
211 void SetUp() override; 214 void SetUp() override;
212 void TearDown() override; 215 void TearDown() override;
213 216
214 protected: 217 protected:
218 // Test delete to beginning of line or paragraph based on |sel|. |sel| can be
219 // either deleteToBeginningOfLine: or deleteToBeginningOfParagraph:.
220 void TestDeleteBeginning(SEL sel);
221
222 // Test delete to end of line or paragraph based on |sel|. |sel| can be
223 // either deleteToEndOfLine: or deleteToEndOfParagraph:.
224 void TestDeleteEnd(SEL sel);
225
215 std::unique_ptr<views::View> view_; 226 std::unique_ptr<views::View> view_;
216 BridgedContentView* ns_view_; // Weak. Owned by bridge(). 227 BridgedContentView* ns_view_; // Weak. Owned by bridge().
217 base::MessageLoopForUI message_loop_; 228 base::MessageLoopForUI message_loop_;
218 229
219 private: 230 private:
220 DISALLOW_COPY_AND_ASSIGN(BridgedNativeWidgetTest); 231 DISALLOW_COPY_AND_ASSIGN(BridgedNativeWidgetTest);
221 }; 232 };
222 233
223 BridgedNativeWidgetTest::BridgedNativeWidgetTest() { 234 BridgedNativeWidgetTest::BridgedNativeWidgetTest() {
224 } 235 }
(...skipping 23 matching lines...) Expand all
248 InstallTextField(text, ui::TEXT_INPUT_TYPE_TEXT); 259 InstallTextField(text, ui::TEXT_INPUT_TYPE_TEXT);
249 } 260 }
250 261
251 std::string BridgedNativeWidgetTest::GetText() { 262 std::string BridgedNativeWidgetTest::GetText() {
252 NSRange range = NSMakeRange(0, NSUIntegerMax); 263 NSRange range = NSMakeRange(0, NSUIntegerMax);
253 NSAttributedString* text = 264 NSAttributedString* text =
254 [ns_view_ attributedSubstringForProposedRange:range actualRange:NULL]; 265 [ns_view_ attributedSubstringForProposedRange:range actualRange:NULL];
255 return SysNSStringToUTF8([text string]); 266 return SysNSStringToUTF8([text string]);
256 } 267 }
257 268
269 void BridgedNativeWidgetTest::SetSelectionRange(const gfx::Range& range) {
270 ui::TextInputClient* client = [ns_view_ textInputClient];
271 client->SetSelectionRange(range);
272 }
273
258 void BridgedNativeWidgetTest::SetUp() { 274 void BridgedNativeWidgetTest::SetUp() {
259 BridgedNativeWidgetTestBase::SetUp(); 275 BridgedNativeWidgetTestBase::SetUp();
260 276
261 view_.reset(new views::internal::RootView(widget_.get())); 277 view_.reset(new views::internal::RootView(widget_.get()));
262 base::scoped_nsobject<NSWindow> window([test_window() retain]); 278 base::scoped_nsobject<NSWindow> window([test_window() retain]);
263 279
264 // BridgedNativeWidget expects to be initialized with a hidden (deferred) 280 // BridgedNativeWidget expects to be initialized with a hidden (deferred)
265 // window. 281 // window.
266 [window orderOut:nil]; 282 [window orderOut:nil];
267 EXPECT_FALSE([window delegate]); 283 EXPECT_FALSE([window delegate]);
268 bridge()->Init(window, init_params_); 284 bridge()->Init(window, init_params_);
269 285
270 // The delegate should exist before setting the root view. 286 // The delegate should exist before setting the root view.
271 EXPECT_TRUE([window delegate]); 287 EXPECT_TRUE([window delegate]);
272 bridge()->SetRootView(view_.get()); 288 bridge()->SetRootView(view_.get());
273 ns_view_ = bridge()->ns_view(); 289 ns_view_ = bridge()->ns_view();
274 290
275 // Pretend it has been shown via NativeWidgetMac::Show(). 291 // Pretend it has been shown via NativeWidgetMac::Show().
276 [window orderFront:nil]; 292 [window orderFront:nil];
277 [test_window() makePretendKeyWindowAndSetFirstResponder:bridge()->ns_view()]; 293 [test_window() makePretendKeyWindowAndSetFirstResponder:bridge()->ns_view()];
278 } 294 }
279 295
280 void BridgedNativeWidgetTest::TearDown() { 296 void BridgedNativeWidgetTest::TearDown() {
281 if (bridge()) 297 if (bridge())
282 bridge()->SetRootView(nullptr); 298 bridge()->SetRootView(nullptr);
283 view_.reset(); 299 view_.reset();
284 BridgedNativeWidgetTestBase::TearDown(); 300 BridgedNativeWidgetTestBase::TearDown();
285 } 301 }
286 302
303 void BridgedNativeWidgetTest::TestDeleteBeginning(SEL sel) {
304 InstallTextField("foo bar baz");
305 EXPECT_EQ_RANGE(NSMakeRange(11, 0), [ns_view_ selectedRange]);
306
307 // Move the caret to the beginning of the line.
308 SetSelectionRange(gfx::Range(0));
309 // Verify no deletion takes place.
310 [ns_view_ doCommandBySelector:sel];
311 EXPECT_EQ("foo bar baz", GetText());
312 EXPECT_EQ_RANGE(NSMakeRange(0, 0), [ns_view_ selectedRange]);
313
314 // Move the caret as- "foo| bar baz".
315 SetSelectionRange(gfx::Range(3, 3));
316 [ns_view_ doCommandBySelector:sel];
317 // Verify state is "| bar baz".
318 EXPECT_EQ(" bar baz", GetText());
319 EXPECT_EQ_RANGE(NSMakeRange(0, 0), [ns_view_ selectedRange]);
320
321 // Make a selection as- " bar |baz|".
322 SetSelectionRange(gfx::Range(5, 8));
323 [ns_view_ doCommandBySelector:sel];
324 // Verify only the selection is deleted so that the state is " bar |".
325 EXPECT_EQ(" bar ", GetText());
326 EXPECT_EQ_RANGE(NSMakeRange(5, 0), [ns_view_ selectedRange]);
327 }
328
329 void BridgedNativeWidgetTest::TestDeleteEnd(SEL sel) {
330 InstallTextField("foo bar baz");
331 EXPECT_EQ_RANGE(NSMakeRange(11, 0), [ns_view_ selectedRange]);
332
333 // Caret is at the end of the line. Verify no deletion takes place.
334 [ns_view_ doCommandBySelector:sel];
335 EXPECT_EQ("foo bar baz", GetText());
336 EXPECT_EQ_RANGE(NSMakeRange(11, 0), [ns_view_ selectedRange]);
337
338 // Move the caret as- "foo bar| baz".
339 SetSelectionRange(gfx::Range(7, 7));
340 [ns_view_ doCommandBySelector:sel];
341 // Verify state is "foo bar|".
342 EXPECT_EQ("foo bar", GetText());
343 EXPECT_EQ_RANGE(NSMakeRange(7, 0), [ns_view_ selectedRange]);
344
345 // Make a selection as- "|foo |bar".
346 SetSelectionRange(gfx::Range(0, 4));
347 [ns_view_ doCommandBySelector:sel];
348 // Verify only the selection is deleted so that the state is "|bar".
349 EXPECT_EQ("bar", GetText());
350 EXPECT_EQ_RANGE(NSMakeRange(0, 0), [ns_view_ selectedRange]);
351 }
352
287 // The TEST_VIEW macro expects the view it's testing to have a superview. In 353 // The TEST_VIEW macro expects the view it's testing to have a superview. In
288 // these tests, the NSView bridge is a contentView, at the root. These mimic 354 // these tests, the NSView bridge is a contentView, at the root. These mimic
289 // what TEST_VIEW usually does. 355 // what TEST_VIEW usually does.
290 TEST_F(BridgedNativeWidgetTest, BridgedNativeWidgetTest_TestViewAddRemove) { 356 TEST_F(BridgedNativeWidgetTest, BridgedNativeWidgetTest_TestViewAddRemove) {
291 base::scoped_nsobject<BridgedContentView> view([bridge()->ns_view() retain]); 357 base::scoped_nsobject<BridgedContentView> view([bridge()->ns_view() retain]);
292 EXPECT_NSEQ([test_window() contentView], view); 358 EXPECT_NSEQ([test_window() contentView], view);
293 EXPECT_NSEQ(test_window(), [view window]); 359 EXPECT_NSEQ(test_window(), [view window]);
294 360
295 // The superview of a contentView is an NSNextStepFrame. 361 // The superview of a contentView is an NSNextStepFrame.
296 EXPECT_TRUE([view superview]); 362 EXPECT_TRUE([view superview]);
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 EXPECT_EQ("a", GetText()); 644 EXPECT_EQ("a", GetText());
579 EXPECT_EQ_RANGE(NSMakeRange(1, 0), [ns_view_ selectedRange]); 645 EXPECT_EQ_RANGE(NSMakeRange(1, 0), [ns_view_ selectedRange]);
580 646
581 // Should succeed after moving left first. 647 // Should succeed after moving left first.
582 [ns_view_ doCommandBySelector:@selector(moveLeft:)]; 648 [ns_view_ doCommandBySelector:@selector(moveLeft:)];
583 [ns_view_ doCommandBySelector:@selector(deleteForward:)]; 649 [ns_view_ doCommandBySelector:@selector(deleteForward:)];
584 EXPECT_EQ("", GetText()); 650 EXPECT_EQ("", GetText());
585 EXPECT_EQ_RANGE(NSMakeRange(0, 0), [ns_view_ selectedRange]); 651 EXPECT_EQ_RANGE(NSMakeRange(0, 0), [ns_view_ selectedRange]);
586 } 652 }
587 653
654 // Test forward word deletion using text input protocol.
655 TEST_F(BridgedNativeWidgetTest, TextInput_DeleteWordForward) {
656 InstallTextField("foo bar baz");
657 EXPECT_EQ_RANGE(NSMakeRange(11, 0), [ns_view_ selectedRange]);
658
659 // Caret is at the end of the line. Verify no deletion takes place.
660 [ns_view_ doCommandBySelector:@selector(deleteWordForward:)];
661 EXPECT_EQ("foo bar baz", GetText());
662 EXPECT_EQ_RANGE(NSMakeRange(11, 0), [ns_view_ selectedRange]);
663
664 // Move the caret as- "foo b|ar baz".
665 SetSelectionRange(gfx::Range(5, 5));
666 [ns_view_ doCommandBySelector:@selector(deleteWordForward:)];
667 // Verify state is "foo b| baz"
668 EXPECT_EQ("foo b baz", GetText());
669 EXPECT_EQ_RANGE(NSMakeRange(5, 0), [ns_view_ selectedRange]);
670
671 // Make a selection as- "|fo|o b baz".
672 SetSelectionRange(gfx::Range(0, 2));
673 [ns_view_ doCommandBySelector:@selector(deleteWordForward:)];
674 // Verify only the selection is deleted and state is "|o b baz".
675 EXPECT_EQ("o b baz", GetText());
676 EXPECT_EQ_RANGE(NSMakeRange(0, 0), [ns_view_ selectedRange]);
677 }
678
679 // Test backward word deletion using text input protocol.
680 TEST_F(BridgedNativeWidgetTest, TextInput_DeleteWordBackward) {
681 InstallTextField("foo bar baz");
682 EXPECT_EQ_RANGE(NSMakeRange(11, 0), [ns_view_ selectedRange]);
683
684 // Move the caret to the beginning of the line.
685 SetSelectionRange(gfx::Range(0));
686 // Verify no deletion takes place.
687 [ns_view_ doCommandBySelector:@selector(deleteWordBackward:)];
688 EXPECT_EQ("foo bar baz", GetText());
689 EXPECT_EQ_RANGE(NSMakeRange(0, 0), [ns_view_ selectedRange]);
690
691 // Move the caret as- "foo ba|r baz".
692 SetSelectionRange(gfx::Range(6, 6));
693 [ns_view_ doCommandBySelector:@selector(deleteWordBackward:)];
694 // Verify state is "foo |r baz".
695 EXPECT_EQ("foo r baz", GetText());
696 EXPECT_EQ_RANGE(NSMakeRange(4, 0), [ns_view_ selectedRange]);
697
698 // Make a selection as- "f|oo r b|az".
699 SetSelectionRange(gfx::Range(1, 7));
700 [ns_view_ doCommandBySelector:@selector(deleteWordBackward:)];
701 // Verify only the selection is deleted and state is "f|az"
702 EXPECT_EQ("faz", GetText());
703 EXPECT_EQ_RANGE(NSMakeRange(1, 0), [ns_view_ selectedRange]);
704 }
705
706 // Test deleting to beginning/end of line/paragraph using text input protocol.
707
708 TEST_F(BridgedNativeWidgetTest, TextInput_DeleteToBeginningOfLine) {
709 TestDeleteBeginning(@selector(deleteToBeginningOfLine:));
710 }
711
712 TEST_F(BridgedNativeWidgetTest, TextInput_DeleteToEndOfLine) {
713 TestDeleteEnd(@selector(deleteToEndOfLine:));
714 }
715
716 TEST_F(BridgedNativeWidgetTest, TextInput_DeleteToBeginningOfParagraph) {
717 TestDeleteBeginning(@selector(deleteToBeginningOfParagraph:));
718 }
719
720 TEST_F(BridgedNativeWidgetTest, TextInput_DeleteToEndOfParagraph) {
721 TestDeleteEnd(@selector(deleteToEndOfParagraph:));
722 }
723
588 // Test firstRectForCharacterRange:actualRange for cases where query range is 724 // Test firstRectForCharacterRange:actualRange for cases where query range is
589 // empty or outside composition range. 725 // empty or outside composition range.
590 TEST_F(BridgedNativeWidgetTest, TextInput_FirstRectForCharacterRange_Caret) { 726 TEST_F(BridgedNativeWidgetTest, TextInput_FirstRectForCharacterRange_Caret) {
591 InstallTextField(""); 727 InstallTextField("");
592 ui::TextInputClient* client = [ns_view_ textInputClient]; 728 ui::TextInputClient* client = [ns_view_ textInputClient];
593 729
594 // No composition. Ensure bounds and range corresponding to the current caret 730 // No composition. Ensure bounds and range corresponding to the current caret
595 // position are returned. 731 // position are returned.
596 // Initially selection range will be [0, 0]. 732 // Initially selection range will be [0, 0].
597 NSRange caret_range = NSMakeRange(0, 0); 733 NSRange caret_range = NSMakeRange(0, 0);
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 [center postNotificationName:NSWindowDidExitFullScreenNotification 878 [center postNotificationName:NSWindowDidExitFullScreenNotification
743 object:window]; 879 object:window];
744 EXPECT_EQ(1, [window ignoredToggleFullScreenCount]); // No change. 880 EXPECT_EQ(1, [window ignoredToggleFullScreenCount]); // No change.
745 EXPECT_FALSE(bridge()->target_fullscreen_state()); 881 EXPECT_FALSE(bridge()->target_fullscreen_state());
746 882
747 widget_->CloseNow(); 883 widget_->CloseNow();
748 } 884 }
749 885
750 } // namespace test 886 } // namespace test
751 } // namespace views 887 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/cocoa/bridged_content_view.mm ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698