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

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

Issue 1531213002: Mac: Implement firstRectForCharacterRange:actualRange in BridgedContentView. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Corrected comment formatting Created 5 years 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
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 #import "base/mac/foundation_util.h" 9 #import "base/mac/foundation_util.h"
10 #import "base/mac/mac_util.h" 10 #import "base/mac/mac_util.h"
11 #import "base/mac/sdk_forward_declarations.h" 11 #import "base/mac/sdk_forward_declarations.h"
12 #include "base/memory/scoped_ptr.h" 12 #include "base/memory/scoped_ptr.h"
13 #include "base/message_loop/message_loop.h" 13 #include "base/message_loop/message_loop.h"
14 #include "base/strings/sys_string_conversions.h" 14 #include "base/strings/sys_string_conversions.h"
15 #include "base/strings/utf_string_conversions.h" 15 #include "base/strings/utf_string_conversions.h"
16 #import "testing/gtest_mac.h" 16 #import "testing/gtest_mac.h"
17 #import "ui/base/cocoa/window_size_constants.h" 17 #import "ui/base/cocoa/window_size_constants.h"
18 #include "ui/base/ime/input_method.h" 18 #include "ui/base/ime/input_method.h"
19 #import "ui/gfx/test/ui_cocoa_test_helper.h" 19 #import "ui/gfx/test/ui_cocoa_test_helper.h"
20 #include "ui/gfx/mac/coordinate_conversion.h"
20 #import "ui/views/cocoa/bridged_content_view.h" 21 #import "ui/views/cocoa/bridged_content_view.h"
21 #import "ui/views/cocoa/native_widget_mac_nswindow.h" 22 #import "ui/views/cocoa/native_widget_mac_nswindow.h"
22 #import "ui/views/cocoa/views_nswindow_delegate.h" 23 #import "ui/views/cocoa/views_nswindow_delegate.h"
23 #include "ui/views/controls/textfield/textfield.h" 24 #include "ui/views/controls/textfield/textfield.h"
24 #include "ui/views/view.h" 25 #include "ui/views/view.h"
25 #include "ui/views/widget/native_widget_mac.h" 26 #include "ui/views/widget/native_widget_mac.h"
26 #include "ui/views/widget/root_view.h" 27 #include "ui/views/widget/root_view.h"
27 #include "ui/views/widget/widget.h" 28 #include "ui/views/widget/widget.h"
28 #include "ui/views/widget/widget_observer.h" 29 #include "ui/views/widget/widget_observer.h"
29 30
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 // before the tests covering the Init() flow are ready to do that. 122 // before the tests covering the Init() flow are ready to do that.
122 init_params_.type = Widget::InitParams::TYPE_WINDOW_FRAMELESS; 123 init_params_.type = Widget::InitParams::TYPE_WINDOW_FRAMELESS;
123 124
124 // To control the lifetime without an actual window that must be closed, 125 // To control the lifetime without an actual window that must be closed,
125 // tests in this file need to use WIDGET_OWNS_NATIVE_WIDGET. 126 // tests in this file need to use WIDGET_OWNS_NATIVE_WIDGET.
126 init_params_.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 127 init_params_.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
127 128
128 // Opacity defaults to "infer" which is usually updated by ViewsDelegate. 129 // Opacity defaults to "infer" which is usually updated by ViewsDelegate.
129 init_params_.opacity = Widget::InitParams::OPAQUE_WINDOW; 130 init_params_.opacity = Widget::InitParams::OPAQUE_WINDOW;
130 131
132 init_params_.bounds = gfx::Rect(100, 100, 100, 100);
133
131 native_widget_mac_->GetWidget()->Init(init_params_); 134 native_widget_mac_->GetWidget()->Init(init_params_);
132 } 135 }
133 136
134 protected: 137 protected:
135 scoped_ptr<Widget> widget_; 138 scoped_ptr<Widget> widget_;
136 MockNativeWidgetMac* native_widget_mac_; // Weak. Owned by |widget_|. 139 MockNativeWidgetMac* native_widget_mac_; // Weak. Owned by |widget_|.
137 140
138 // Make the InitParams available to tests to cover initialization codepaths. 141 // Make the InitParams available to tests to cover initialization codepaths.
139 Widget::InitParams init_params_; 142 Widget::InitParams init_params_;
140 }; 143 };
(...skipping 26 matching lines...) Expand all
167 170
168 BridgedNativeWidgetTest::BridgedNativeWidgetTest() { 171 BridgedNativeWidgetTest::BridgedNativeWidgetTest() {
169 } 172 }
170 173
171 BridgedNativeWidgetTest::~BridgedNativeWidgetTest() { 174 BridgedNativeWidgetTest::~BridgedNativeWidgetTest() {
172 } 175 }
173 176
174 void BridgedNativeWidgetTest::InstallTextField(const std::string& text) { 177 void BridgedNativeWidgetTest::InstallTextField(const std::string& text) {
175 Textfield* textfield = new Textfield(); 178 Textfield* textfield = new Textfield();
176 textfield->SetText(ASCIIToUTF16(text)); 179 textfield->SetText(ASCIIToUTF16(text));
180 textfield->SetBoundsRect(init_params_.bounds);
177 view_->AddChildView(textfield); 181 view_->AddChildView(textfield);
178 182
179 // Request focus so the InputMethod can dispatch events to the RootView, and 183 // Request focus so the InputMethod can dispatch events to the RootView, and
180 // have them delivered to the textfield. Note that focusing a textfield 184 // have them delivered to the textfield. Note that focusing a textfield
181 // schedules a task to flash the cursor, so this requires |message_loop_|. 185 // schedules a task to flash the cursor, so this requires |message_loop_|.
182 textfield->RequestFocus(); 186 textfield->RequestFocus();
183 187
184 [ns_view_ setTextInputClient:textfield]; 188 [ns_view_ setTextInputClient:textfield];
185 } 189 }
186 190
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 EXPECT_EQ("a", GetText()); 502 EXPECT_EQ("a", GetText());
499 EXPECT_EQ_RANGE(NSMakeRange(1, 0), [ns_view_ selectedRange]); 503 EXPECT_EQ_RANGE(NSMakeRange(1, 0), [ns_view_ selectedRange]);
500 504
501 // Should succeed after moving left first. 505 // Should succeed after moving left first.
502 [ns_view_ doCommandBySelector:@selector(moveLeft:)]; 506 [ns_view_ doCommandBySelector:@selector(moveLeft:)];
503 [ns_view_ doCommandBySelector:@selector(deleteForward:)]; 507 [ns_view_ doCommandBySelector:@selector(deleteForward:)];
504 EXPECT_EQ("", GetText()); 508 EXPECT_EQ("", GetText());
505 EXPECT_EQ_RANGE(NSMakeRange(0, 0), [ns_view_ selectedRange]); 509 EXPECT_EQ_RANGE(NSMakeRange(0, 0), [ns_view_ selectedRange]);
506 } 510 }
507 511
512 TEST_F(BridgedNativeWidgetTest, TextInput_FirstRectForCharacterRange) {
tapted 2015/12/22 02:33:58 nit: brief comment summarising what's being tested
karandeepb 2015/12/29 07:21:16 Done.
513 InstallTextField("");
514 ui::TextInputClient* client = [ns_view_ textInputClient];
515 NSRange range;
tapted 2015/12/22 02:33:58 move declarations closer to first use. Typically i
karandeepb 2015/12/29 07:21:15 Done.
516 NSRange actual_range = NSMakeRange(-1, -1);
tapted 2015/12/22 02:33:58 NSMakeRange takes unsigned integers. An invalid ra
karandeepb 2015/12/29 07:21:16 Done.
517 NSRect rect;
518 gfx::Rect bounds;
519
520 // Empty composition.
521 rect = [ns_view_ firstRectForCharacterRange:NSMakeRange(0, 0)
522 actualRange:&actual_range];
523 bounds = client->GetCaretBounds();
tapted 2015/12/22 02:33:58 Can this be a constant in the test? (if it depends
karandeepb 2015/12/29 07:21:16 Not quite sure how to make this a constant, since
524 bounds.set_width(0);
525 EXPECT_TRUE(gfx::ScreenRectFromNSRect(rect) == bounds);
tapted 2015/12/22 02:33:58 EXPECT_EQ should work for gfx::Bounds, and give be
karandeepb 2015/12/29 07:21:16 Done.
526 EXPECT_TRUE(NSEqualRanges(NSMakeRange(0, 0), actual_range));
tapted 2015/12/22 02:33:58 EXPECT_EQ_RANGE. More below
karandeepb 2015/12/29 07:21:15 Done.
527
528 rect = [ns_view_ firstRectForCharacterRange:NSMakeRange(1, 1)
529 actualRange:&actual_range];
530 EXPECT_TRUE(gfx::ScreenRectFromNSRect(rect) == bounds);
531 EXPECT_TRUE(NSEqualRanges(NSMakeRange(1, 0), actual_range));
532
tapted 2015/12/22 02:33:58 It might be good to split up the test here into se
karandeepb 2015/12/29 07:21:15 Done.
533 // Set composition with caret before second character('e').
tapted 2015/12/22 02:33:58 nit: space before open paren
karandeepb 2015/12/29 07:21:16 Done.
534 ui::CompositionText composition;
535 composition.selection = gfx::Range(1);
536 composition.text = base::UTF8ToUTF16("test_str");
tapted 2015/12/22 02:33:58 nit: ASCIIToUTF16 is what usually gets used for st
karandeepb 2015/12/29 07:21:16 Done.
537 size_t count = composition.text.length();
tapted 2015/12/22 02:33:58 `count` is pretty vague here. It also breaks the l
karandeepb 2015/12/29 07:21:15 Done.
538 client->SetCompositionText(composition);
539 bounds = client->GetCaretBounds();
540 bounds.set_width(0);
541
542 range = NSMakeRange(1, 0);
543 rect = [ns_view_ firstRectForCharacterRange:range actualRange:&actual_range];
544 EXPECT_TRUE(gfx::ScreenRectFromNSRect(rect) == bounds);
545 EXPECT_TRUE(NSEqualRanges(range, actual_range));
546
547 range = NSMakeRange(2, 0);
548 rect = [ns_view_ firstRectForCharacterRange:range actualRange:&actual_range];
549 EXPECT_FALSE(gfx::ScreenRectFromNSRect(rect) == bounds);
tapted 2015/12/22 02:33:58 comment about this? (what's it testing, and why is
karandeepb 2015/12/29 07:21:16 Done.
550 EXPECT_TRUE(NSEqualRanges(range, actual_range));
551
552 // Query outside composition range.
553 range = NSMakeRange(count + 1, 0);
554 rect = [ns_view_ firstRectForCharacterRange:range actualRange:&actual_range];
555 EXPECT_TRUE(gfx::ScreenRectFromNSRect(rect) == bounds);
556 EXPECT_TRUE(NSEqualRanges(range, actual_range));
557
558 // Set composition with caret after last character.
559 composition.selection = gfx::Range(count);
560 client->SetCompositionText(composition);
561 bounds = client->GetCaretBounds();
562 bounds.set_width(0);
563
564 range = NSMakeRange(count, 0);
565 rect = [ns_view_ firstRectForCharacterRange:range actualRange:&actual_range];
566 EXPECT_TRUE(gfx::ScreenRectFromNSRect(rect) == bounds);
567 EXPECT_TRUE(NSEqualRanges(range, actual_range));
568
569 range = NSMakeRange(count - 1, 1);
570 rect = [ns_view_ firstRectForCharacterRange:range actualRange:&actual_range];
571 EXPECT_FALSE(gfx::ScreenRectFromNSRect(rect) == bounds);
572 EXPECT_TRUE(NSEqualRanges(range, actual_range));
573
574 // Query outside composition range.
tapted 2015/12/22 02:33:58 These all need a bit more commentary. I.e. say why
karandeepb 2015/12/29 07:21:15 Done.
575 range = NSMakeRange(count - 1, 2);
576 rect = [ns_view_ firstRectForCharacterRange:range actualRange:&actual_range];
577 EXPECT_TRUE(gfx::ScreenRectFromNSRect(rect) == bounds);
578 EXPECT_TRUE(NSEqualRanges(NSMakeRange(count - 1, 0), actual_range));
579
580 std::vector<gfx::Rect> char_bounds(count);
tapted 2015/12/22 02:33:58 It's unusual to see exhaustive testing like this:
karandeepb 2015/12/29 07:21:15 That would turn out to be a bit messy, since we wi
581 std::vector<gfx::Rect> caret_bounds(count + 1);
582
583 // Generate caret_bounds between different characters.
584 for (size_t i = 0; i <= count; i++) {
585 composition.selection = gfx::Range(i);
586 client->SetCompositionText(composition);
587 caret_bounds[i] = client->GetCaretBounds();
588 }
589
590 // Generate individual character bounds from caret positions.
591 for (size_t i = 0; i < count; i++) {
592 char_bounds[i].set_origin(caret_bounds[i].origin());
593 char_bounds[i].set_width(caret_bounds[i + 1].x() - caret_bounds[i].x());
594 char_bounds[i].set_height(
595 std::max(caret_bounds[i].height(), caret_bounds[i + 1].height()));
596 }
597
598 // Verify bounds for all valid ranges.
599 for (size_t i = 0; i < count; i++) {
600 for (size_t j = i + 1; j <= count; j++) {
601 range = NSMakeRange(i, j - i);
602 rect =
603 [ns_view_ firstRectForCharacterRange:range actualRange:&actual_range];
604
605 bounds = gfx::Rect();
606 for (size_t k = i; k < j; k++)
607 bounds.Union(char_bounds[k]);
608
609 EXPECT_TRUE(gfx::ScreenRectFromNSRect(rect) == bounds);
610 EXPECT_TRUE(NSEqualRanges(range, actual_range));
611 }
612 }
613 }
614
508 typedef BridgedNativeWidgetTestBase BridgedNativeWidgetSimulateFullscreenTest; 615 typedef BridgedNativeWidgetTestBase BridgedNativeWidgetSimulateFullscreenTest;
509 616
510 // Simulate the notifications that AppKit would send out if a fullscreen 617 // Simulate the notifications that AppKit would send out if a fullscreen
511 // operation begins, and then fails and must abort. This notification sequence 618 // operation begins, and then fails and must abort. This notification sequence
512 // was determined by posting delayed tasks to toggle fullscreen state and then 619 // was determined by posting delayed tasks to toggle fullscreen state and then
513 // mashing Ctrl+Left/Right to keep OSX in a transition between Spaces to cause 620 // mashing Ctrl+Left/Right to keep OSX in a transition between Spaces to cause
514 // the fullscreen transition to fail. 621 // the fullscreen transition to fail.
515 TEST_F(BridgedNativeWidgetSimulateFullscreenTest, FailToEnterAndExit) { 622 TEST_F(BridgedNativeWidgetSimulateFullscreenTest, FailToEnterAndExit) {
516 if (base::mac::IsOSSnowLeopard()) 623 if (base::mac::IsOSSnowLeopard())
517 return; 624 return;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 [center postNotificationName:NSWindowDidExitFullScreenNotification 683 [center postNotificationName:NSWindowDidExitFullScreenNotification
577 object:window]; 684 object:window];
578 EXPECT_EQ(1, [window ignoredToggleFullScreenCount]); // No change. 685 EXPECT_EQ(1, [window ignoredToggleFullScreenCount]); // No change.
579 EXPECT_FALSE(bridge()->target_fullscreen_state()); 686 EXPECT_FALSE(bridge()->target_fullscreen_state());
580 687
581 widget_->CloseNow(); 688 widget_->CloseNow();
582 } 689 }
583 690
584 } // namespace test 691 } // namespace test
585 } // namespace views 692 } // namespace views
OLDNEW
« ui/views/cocoa/bridged_content_view.mm ('K') | « 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