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

Unified 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: Addressed review comments and made tests concise. 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 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 3f0d110643b817a4b8e6aeb20a4ec666d68d768d..fde5af4fd3ae9190925667891c014e32f7f00be9 100644
--- a/ui/views/cocoa/bridged_native_widget_unittest.mm
+++ b/ui/views/cocoa/bridged_native_widget_unittest.mm
@@ -17,6 +17,7 @@
#import "ui/base/cocoa/window_size_constants.h"
#include "ui/base/ime/input_method.h"
#import "ui/gfx/test/ui_cocoa_test_helper.h"
+#include "ui/gfx/mac/coordinate_conversion.h"
tapted 2015/12/30 06:48:53 nit: import
karandeepb 2015/12/31 02:42:43 Done.
#import "ui/views/cocoa/bridged_content_view.h"
#import "ui/views/cocoa/native_widget_mac_nswindow.h"
#import "ui/views/cocoa/views_nswindow_delegate.h"
@@ -43,6 +44,37 @@ NSRange EmptyRange() {
return NSMakeRange(NSNotFound, 0);
}
+// Sets |composition_text| as the composition text with caret placed at
+// |caret_pos| and updates |caret_range|.
+void SetCompositionText(ui::TextInputClient* client,
+ const base::string16& composition_text,
+ const int caret_pos,
+ NSRange* caret_range = nil) {
tapted 2015/12/30 06:48:53 I don't think anything relies on the default argum
karandeepb 2015/12/31 02:42:43 Done.
+ ui::CompositionText composition;
+ composition.selection = gfx::Range(caret_pos);
+ composition.text = composition_text;
+ client->SetCompositionText(composition);
+ if (caret_range)
+ *caret_range = NSMakeRange(caret_pos, 0);
+}
+
+// Returns a zero width rectangle corresponding to current caret position.
+gfx::Rect GetCaretBounds(const ui::TextInputClient* client) {
+ gfx::Rect caret_bounds = client->GetCaretBounds();
+ caret_bounds.set_width(0);
+ return caret_bounds;
+}
+
+// Returns a zero width rectangle corresponding to caret bounds when it's placed
+// at |caret_pos| and updates |caret_range|.
+gfx::Rect GetCaretBoundsForPosition(ui::TextInputClient* client,
+ const base::string16& composition_text,
+ const int caret_pos,
+ NSRange* caret_range = nil) {
tapted 2015/12/30 06:48:52 I think there's one call that wants the default -
karandeepb 2015/12/31 02:42:44 Done.
+ SetCompositionText(client, composition_text, caret_pos, caret_range);
+ return GetCaretBounds(client);
+}
+
} // namespace
// Class to override -[NSWindow toggleFullScreen:] to a no-op. This simulates
@@ -128,6 +160,8 @@ class BridgedNativeWidgetTestBase : public ui::CocoaTest {
// Opacity defaults to "infer" which is usually updated by ViewsDelegate.
init_params_.opacity = Widget::InitParams::OPAQUE_WINDOW;
+ init_params_.bounds = gfx::Rect(100, 100, 100, 100);
+
native_widget_mac_->GetWidget()->Init(init_params_);
}
@@ -174,6 +208,7 @@ BridgedNativeWidgetTest::~BridgedNativeWidgetTest() {
void BridgedNativeWidgetTest::InstallTextField(const std::string& text) {
Textfield* textfield = new Textfield();
textfield->SetText(ASCIIToUTF16(text));
+ textfield->SetBoundsRect(init_params_.bounds);
view_->AddChildView(textfield);
// Request focus so the InputMethod can dispatch events to the RootView, and
@@ -505,6 +540,101 @@ TEST_F(BridgedNativeWidgetTest, TextInput_DeleteForward) {
EXPECT_EQ_RANGE(NSMakeRange(0, 0), [ns_view_ selectedRange]);
}
+// Test firstRectForCharacterRange:actualRange for cases where query range is
+// empty or outside composition range.
+TEST_F(BridgedNativeWidgetTest, TextInput_FirstRectForCharacterRange_Caret) {
+ InstallTextField("");
+ ui::TextInputClient* client = [ns_view_ textInputClient];
+
+ // No composition. Ensure bounds and range corresponding to the current caret
+ // position are returned.
+ // Initially selection range will be [0, 0].
+ NSRange caret_range = NSMakeRange(0, 0);
+ NSRange query_range = NSMakeRange(1, 1);
+ NSRange actual_range;
+ NSRect rect = [ns_view_ firstRectForCharacterRange:query_range
+ actualRange:&actual_range];
+ EXPECT_EQ(GetCaretBounds(client), gfx::ScreenRectFromNSRect(rect));
+ EXPECT_EQ_RANGE(caret_range, actual_range);
+
+ // Set composition with caret before second character ('e').
+ const base::string16 kTestString = base::ASCIIToUTF16("test_str");
tapted 2015/12/30 06:48:53 So there's a weird convention (or, the literal int
karandeepb 2015/12/31 02:42:44 Can't find this in the cpp style guide - https://e
tapted 2016/01/04 02:28:10 It says "Variables declared constexpr or const, an
karandeepb 2016/01/04 04:33:55 Done. Will refactor the other usages in a separate
+ const size_t kTextLength = 8;
+ SetCompositionText(client, kTestString, 1, &caret_range);
+
+ // Test empty ranges within the composition range.
tapted 2015/12/30 06:48:53 nit: follow comment with the expectations, E.g.
karandeepb 2015/12/31 02:42:43 Done.
+ query_range = NSMakeRange(1, 0);
+ rect = [ns_view_ firstRectForCharacterRange:query_range
+ actualRange:&actual_range];
+ EXPECT_EQ(GetCaretBoundsForPosition(client, kTestString, 1, &caret_range),
+ gfx::ScreenRectFromNSRect(rect));
+ EXPECT_EQ_RANGE(query_range, actual_range);
+
+ query_range = NSMakeRange(kTextLength, 0);
tapted 2015/12/30 06:48:53 likewise, "Test empty range at the end of the text
karandeepb 2015/12/31 02:42:44 Done.
+ rect = [ns_view_ firstRectForCharacterRange:query_range
+ actualRange:&actual_range];
+ EXPECT_NE(GetCaretBoundsForPosition(client, kTestString, 1, &caret_range),
+ gfx::ScreenRectFromNSRect(rect));
+ EXPECT_EQ(
+ GetCaretBoundsForPosition(client, kTestString, kTextLength, &caret_range),
+ gfx::ScreenRectFromNSRect(rect));
+ EXPECT_EQ_RANGE(query_range, actual_range);
+
+ // Query outside composition range. Ensure bounds and range corresponding to
+ // the current caret position are returned.
+ query_range = NSMakeRange(kTextLength + 1, 0);
+ rect = [ns_view_ firstRectForCharacterRange:query_range
+ actualRange:&actual_range];
+ EXPECT_EQ(GetCaretBounds(client), gfx::ScreenRectFromNSRect(rect));
+ EXPECT_EQ_RANGE(caret_range, actual_range);
+
+ // Make sure not crashing by passing NULL pointer instead of actualRange.
tapted 2015/12/30 06:48:52 nit: NULL->null
karandeepb 2015/12/31 02:42:43 Done.
+ rect = [ns_view_ firstRectForCharacterRange:query_range actualRange:NULL];
tapted 2015/12/30 06:48:53 nit: NULL->nullptr (again it's convention: `null`
karandeepb 2015/12/31 02:42:43 Done.
tapted 2016/01/04 02:28:10 (ooh, I should say -- and you may have already fig
karandeepb 2016/01/04 04:33:55 Didn't know all of it. Thanks!
+}
+
+// Test firstRectForCharacterRange:actualRange for all valid ranges of a test
+// string.
+TEST_F(BridgedNativeWidgetTest, TextInput_FirstRectForCharacterRange) {
+ InstallTextField("");
+ ui::TextInputClient* client = [ns_view_ textInputClient];
+ const base::string16 kTestString = base::ASCIIToUTF16("test_str");
tapted 2015/12/30 06:48:53 Is there a minimum test string that can give code
karandeepb 2015/12/31 02:42:43 Removed the loops. Somehow, this approach did not
+ const size_t kTextLength = 8;
+
+ std::vector<gfx::Rect> char_bounds(kTextLength);
+ std::vector<gfx::Rect> caret_bounds(kTextLength + 1);
+
+ // Generate caret_bounds between different characters.
+ for (size_t i = 0; i <= kTextLength; i++)
+ caret_bounds[i] = GetCaretBoundsForPosition(client, kTestString, i);
+
+ // Generate individual character bounds from caret positions.
+ for (size_t i = 0; i < kTextLength; i++) {
+ char_bounds[i].set_origin(caret_bounds[i].origin());
+ char_bounds[i].set_width(caret_bounds[i + 1].x() - caret_bounds[i].x());
+ char_bounds[i].set_height(caret_bounds[i].height());
+ }
+
+ // Verify bounds for all valid ranges.
+ NSRange query_range;
+ NSRange actual_range;
+ NSRect rect;
+ gfx::Rect expected_bounds;
+ for (size_t i = 0; i < kTextLength; i++) {
+ for (size_t j = i + 1; j <= kTextLength; j++) {
+ query_range = NSMakeRange(i, j - i);
+ rect = [ns_view_ firstRectForCharacterRange:query_range
+ actualRange:&actual_range];
+
+ expected_bounds = gfx::Rect();
+ for (size_t k = i; k < j; k++)
+ expected_bounds.Union(char_bounds[k]);
+
+ EXPECT_EQ(expected_bounds, gfx::ScreenRectFromNSRect(rect));
+ EXPECT_EQ_RANGE(query_range, actual_range);
+ }
+ }
+}
+
typedef BridgedNativeWidgetTestBase BridgedNativeWidgetSimulateFullscreenTest;
// Simulate the notifications that AppKit would send out if a fullscreen
« 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