| Index: content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
|
| diff --git a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
|
| index 8a898772b66b83b2bfeed69ebdbe344bcc0ee47c..6f140ba0f6557b726e1bab7709b0faaaeff9a816 100644
|
| --- a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
|
| +++ b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
|
| @@ -5,6 +5,7 @@
|
| #include "content/browser/renderer_host/render_widget_host_view_mac.h"
|
|
|
| #include "base/mac/scoped_nsautorelease_pool.h"
|
| +#include "base/utf_string_conversions.h"
|
| #include "content/browser/browser_thread_impl.h"
|
| #include "content/browser/renderer_host/test_render_view_host.h"
|
| #include "content/common/gpu/gpu_messages.h"
|
| @@ -15,6 +16,51 @@
|
|
|
| namespace content {
|
|
|
| +namespace {
|
| +
|
| +// Generates the |length| of composition rectangle vector and save them to
|
| +// |output|. It starts from |origin| and each rectangle contains |unit_size|.
|
| +void GenerateCompositionRectArray(const gfx::Point& origin,
|
| + const gfx::Size& unit_size,
|
| + size_t length,
|
| + const std::vector<size_t>& break_points,
|
| + std::vector<gfx::Rect>* output) {
|
| + DCHECK(output);
|
| + output->clear();
|
| +
|
| + std::queue<int> break_point_queue;
|
| + for (size_t i = 0; i < break_points.size(); ++i)
|
| + break_point_queue.push(break_points[i]);
|
| + break_point_queue.push(length);
|
| + size_t next_break_point = break_point_queue.front();
|
| + break_point_queue.pop();
|
| +
|
| + gfx::Rect current_rect(origin, unit_size);
|
| + for (size_t i = 0; i < length; ++i) {
|
| + if (i == next_break_point) {
|
| + current_rect.set_x(origin.x());
|
| + current_rect.set_y(current_rect.y() + current_rect.height());
|
| + next_break_point = break_point_queue.front();
|
| + break_point_queue.pop();
|
| + }
|
| + output->push_back(current_rect);
|
| + current_rect.set_x(current_rect.right());
|
| + }
|
| +}
|
| +
|
| +gfx::Rect GetExpectedRect(const gfx::Point& origin,
|
| + const gfx::Size& size,
|
| + const ui::Range& range,
|
| + int line_no) {
|
| + return gfx::Rect(
|
| + origin.x() + range.start() * size.width(),
|
| + origin.y() + line_no * size.height(),
|
| + range.length() * size.width(),
|
| + size.height());
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| class RenderWidgetHostViewMacTest : public RenderViewHostImplTestHarness {
|
| public:
|
| RenderWidgetHostViewMacTest() : old_rwhv_(NULL), rwhv_mac_(NULL) {}
|
| @@ -205,4 +251,301 @@ TEST_F(RenderWidgetHostViewMacTest, Fullscreen) {
|
| EXPECT_TRUE(rwhv_mac_->pepper_fullscreen_window());
|
| }
|
|
|
| +TEST_F(RenderWidgetHostViewMacTest, GetFirstRectForCharaacterRangeCaretCase) {
|
| + const string16 kDummyString = UTF8ToUTF16("hogehoge");
|
| + const size_t kDummyOffset = 0;
|
| +
|
| + gfx::Rect caret_rect(10, 11, 0, 10);
|
| + ui::Range caret_range(0, 0);
|
| +
|
| + NSRect rect;
|
| + NSRange actual_range;
|
| + rwhv_mac_->SelectionChanged(kDummyString, kDummyOffset, caret_range);
|
| + rwhv_mac_->SelectionBoundsChanged(caret_rect, caret_rect);
|
| + EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
|
| + caret_range.ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_EQ(caret_rect, gfx::Rect(NSRectToCGRect(rect)));
|
| + EXPECT_EQ(caret_range, ui::Range(actual_range));
|
| +
|
| + EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
|
| + ui::Range(0, 1).ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
|
| + ui::Range(1, 1).ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
|
| + ui::Range(2, 3).ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| +
|
| + // Caret moved.
|
| + caret_rect = gfx::Rect(20, 11, 0, 10);
|
| + caret_range = ui::Range(1, 1);
|
| + rwhv_mac_->SelectionChanged(kDummyString, kDummyOffset, caret_range);
|
| + rwhv_mac_->SelectionBoundsChanged(caret_rect, caret_rect);
|
| + EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
|
| + caret_range.ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_EQ(caret_rect, gfx::Rect(NSRectToCGRect(rect)));
|
| + EXPECT_EQ(caret_range, ui::Range(actual_range));
|
| +
|
| + EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
|
| + ui::Range(0, 0).ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
|
| + ui::Range(1, 2).ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
|
| + ui::Range(2, 3).ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| +
|
| + // No caret.
|
| + caret_range = ui::Range(1, 2);
|
| + rwhv_mac_->SelectionChanged(kDummyString, kDummyOffset, caret_range);
|
| + rwhv_mac_->SelectionBoundsChanged(caret_rect, gfx::Rect(30, 11, 0, 10));
|
| + EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
|
| + ui::Range(0, 0).ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
|
| + ui::Range(0, 1).ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
|
| + ui::Range(1, 1).ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
|
| + ui::Range(1, 2).ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
|
| + ui::Range(2, 2).ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| +}
|
| +
|
| +TEST_F(RenderWidgetHostViewMacTest, UpdateCompositionSinglelineCase) {
|
| + const gfx::Point kOrigin(10, 11);
|
| + const gfx::Size kBoundsUnit(10, 20);
|
| +
|
| + // If there are no update from renderer, always returned caret position.
|
| + NSRect rect;
|
| + NSRange actual_range;
|
| + EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
|
| + ui::Range(0, 0).ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
|
| + ui::Range(0, 1).ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
|
| + ui::Range(1, 0).ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
|
| + ui::Range(1, 1).ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
|
| + ui::Range(1, 2).ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| +
|
| + const int kCompositionLength = 10;
|
| + std::vector<gfx::Rect> composition_bounds;
|
| + const int kCompositionStart = 3;
|
| + const ui::Range kCompositionRange(kCompositionStart,
|
| + kCompositionStart + kCompositionLength);
|
| + GenerateCompositionRectArray(kOrigin,
|
| + kBoundsUnit,
|
| + kCompositionLength,
|
| + std::vector<size_t>(),
|
| + &composition_bounds);
|
| + rwhv_mac_->ImeCompositionRangeChanged(kCompositionRange, composition_bounds);
|
| +
|
| + // Out of range requests will return caret position.
|
| + EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
|
| + ui::Range(0, 0).ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
|
| + ui::Range(1, 1).ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
|
| + ui::Range(1, 2).ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
|
| + ui::Range(2, 2).ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
|
| + ui::Range(13, 14).ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
|
| + ui::Range(14, 15).ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| +
|
| + for (int i = 0; i <= kCompositionLength; ++i) {
|
| + for (int j = 0; j <= kCompositionLength - i; ++j) {
|
| + const ui::Range range(i, i + j);
|
| + const gfx::Rect expected_rect = GetExpectedRect(kOrigin,
|
| + kBoundsUnit,
|
| + range,
|
| + 0);
|
| + const NSRange request_range = ui::Range(
|
| + kCompositionStart + range.start(),
|
| + kCompositionStart + range.end()).ToNSRange();
|
| + EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
|
| + request_range,
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_EQ(ui::Range(request_range), ui::Range(actual_range));
|
| + EXPECT_EQ(expected_rect, gfx::Rect(NSRectToCGRect(rect)));
|
| + }
|
| + }
|
| +}
|
| +
|
| +TEST_F(RenderWidgetHostViewMacTest, UpdateCompositionMultilineCase) {
|
| + const gfx::Point kOrigin(10, 11);
|
| + const gfx::Size kBoundsUnit(10, 20);
|
| + NSRect rect;
|
| +
|
| + const int kCompositionLength = 30;
|
| + std::vector<gfx::Rect> composition_bounds;
|
| + const ui::Range kCompositionRange(0, kCompositionLength);
|
| + // Set breaking point at 10 and 20.
|
| + std::vector<size_t> break_points;
|
| + break_points.push_back(10);
|
| + break_points.push_back(20);
|
| + GenerateCompositionRectArray(kOrigin,
|
| + kBoundsUnit,
|
| + kCompositionLength,
|
| + break_points,
|
| + &composition_bounds);
|
| + rwhv_mac_->ImeCompositionRangeChanged(kCompositionRange, composition_bounds);
|
| +
|
| + // Range doesn't contain line breaking point.
|
| + ui::Range range;
|
| + range = ui::Range(5, 8);
|
| + NSRange actual_range;
|
| + EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(range.ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_EQ(range, ui::Range(actual_range));
|
| + EXPECT_EQ(
|
| + GetExpectedRect(kOrigin, kBoundsUnit, range, 0),
|
| + gfx::Rect(NSRectToCGRect(rect)));
|
| + range = ui::Range(15, 18);
|
| + EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(range.ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_EQ(range, ui::Range(actual_range));
|
| + EXPECT_EQ(
|
| + GetExpectedRect(kOrigin, kBoundsUnit, ui::Range(5, 8), 1),
|
| + gfx::Rect(NSRectToCGRect(rect)));
|
| + range = ui::Range(25, 28);
|
| + EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(range.ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_EQ(range, ui::Range(actual_range));
|
| + EXPECT_EQ(
|
| + GetExpectedRect(kOrigin, kBoundsUnit, ui::Range(5, 8), 2),
|
| + gfx::Rect(NSRectToCGRect(rect)));
|
| +
|
| + // Range contains line breaking point.
|
| + range = ui::Range(8, 12);
|
| + EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(range.ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_EQ(ui::Range(8, 10), ui::Range(actual_range));
|
| + EXPECT_EQ(
|
| + GetExpectedRect(kOrigin, kBoundsUnit, ui::Range(8, 10), 0),
|
| + gfx::Rect(NSRectToCGRect(rect)));
|
| + range = ui::Range(18, 22);
|
| + EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(range.ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_EQ(ui::Range(18, 20), ui::Range(actual_range));
|
| + EXPECT_EQ(
|
| + GetExpectedRect(kOrigin, kBoundsUnit, ui::Range(8, 10), 1),
|
| + gfx::Rect(NSRectToCGRect(rect)));
|
| +
|
| + // Start point is line breaking point.
|
| + range = ui::Range(10, 12);
|
| + EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(range.ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_EQ(ui::Range(10, 12), ui::Range(actual_range));
|
| + EXPECT_EQ(
|
| + GetExpectedRect(kOrigin, kBoundsUnit, ui::Range(0, 2), 1),
|
| + gfx::Rect(NSRectToCGRect(rect)));
|
| + range = ui::Range(20, 22);
|
| + EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(range.ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_EQ(ui::Range(20, 22), ui::Range(actual_range));
|
| + EXPECT_EQ(
|
| + GetExpectedRect(kOrigin, kBoundsUnit, ui::Range(0, 2), 2),
|
| + gfx::Rect(NSRectToCGRect(rect)));
|
| +
|
| + // End point is line breaking point.
|
| + range = ui::Range(5, 10);
|
| + EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(range.ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_EQ(ui::Range(5, 10), ui::Range(actual_range));
|
| + EXPECT_EQ(
|
| + GetExpectedRect(kOrigin, kBoundsUnit, ui::Range(5, 10), 0),
|
| + gfx::Rect(NSRectToCGRect(rect)));
|
| + range = ui::Range(15, 20);
|
| + EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(range.ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_EQ(ui::Range(15, 20), ui::Range(actual_range));
|
| + EXPECT_EQ(
|
| + GetExpectedRect(kOrigin, kBoundsUnit, ui::Range(5, 10), 1),
|
| + gfx::Rect(NSRectToCGRect(rect)));
|
| +
|
| + // Start and end point are same line breaking point.
|
| + range = ui::Range(10, 10);
|
| + EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(range.ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_EQ(ui::Range(10, 10), ui::Range(actual_range));
|
| + EXPECT_EQ(
|
| + GetExpectedRect(kOrigin, kBoundsUnit, ui::Range(0, 0), 1),
|
| + gfx::Rect(NSRectToCGRect(rect)));
|
| + range = ui::Range(20, 20);
|
| + EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(range.ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_EQ(ui::Range(20, 20), ui::Range(actual_range));
|
| + EXPECT_EQ(
|
| + GetExpectedRect(kOrigin, kBoundsUnit, ui::Range(0, 0), 2),
|
| + gfx::Rect(NSRectToCGRect(rect)));
|
| +
|
| + // Start and end point are different line breaking point.
|
| + range = ui::Range(10, 20);
|
| + EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(range.ToNSRange(),
|
| + &rect,
|
| + &actual_range));
|
| + EXPECT_EQ(ui::Range(10, 20), ui::Range(actual_range));
|
| + EXPECT_EQ(
|
| + GetExpectedRect(kOrigin, kBoundsUnit, ui::Range(0, 10), 1),
|
| + gfx::Rect(NSRectToCGRect(rect)));
|
| +}
|
| } // namespace content
|
|
|