Index: ui/touch_selection/touch_selection_controller_aura_unittest.cc |
diff --git a/ui/touch_selection/touch_selection_controller_aura_unittest.cc b/ui/touch_selection/touch_selection_controller_aura_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..b6d330a6f1f5e032d212923dafb3eaa41b6905b2 |
--- /dev/null |
+++ b/ui/touch_selection/touch_selection_controller_aura_unittest.cc |
@@ -0,0 +1,391 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "ui/touch_selection/touch_selection_controller_aura.h" |
+ |
+#include "testing/gtest/include/gtest/gtest.h" |
+#include "ui/aura/test/aura_test_base.h" |
+#include "ui/aura/window.h" |
+#include "ui/events/test/event_generator.h" |
+#include "ui/touch_selection/touch_handle_drawable_aura.h" |
+#include "ui/touch_selection/touch_selection_menu_runner.h" |
+ |
+namespace ui { |
+namespace { |
+ |
+// ... |
+class TestTouchSelectionMenuRunner : public TouchSelectionMenuRunner { |
+ public: |
+ TestTouchSelectionMenuRunner() { |
+ SetInstance(this); |
+ } |
+ |
+ ~TestTouchSelectionMenuRunner() override { |
+ SetInstance(nullptr); |
+ } |
+ |
+ private: |
+ // TouchSelectionMenuRunner: |
+ void RunMenu(TouchSelectionMenuClient* client, |
+ const gfx::Rect& anchor_rect, |
+ const gfx::Size& handle_image_size, |
+ aura::Window* context) override { |
+ is_running_ = true; |
+ } |
+ |
+ void CloseMenu() override { |
+ is_running_ = false; |
+ } |
+ |
+ bool IsRunning() const override { |
+ return is_running_; |
+ } |
+ |
+ bool is_running_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(TestTouchSelectionMenuRunner); |
+}; |
+ |
+// Convenience to make constructing a GestureEvent simpler. |
+class GestureEventForTest : public ui::GestureEvent { |
+ public: |
+ GestureEventForTest(ui::EventType type, int x, int y) |
+ : GestureEvent(x, |
+ y, |
+ 0, |
+ base::TimeDelta(), |
+ ui::GestureEventDetails(type)) {} |
+}; |
+ |
+// ... |
+class TouchEventForTest : public ui::TouchEvent { |
+ public: |
+ TouchEventForTest(ui::EventType type, gfx::Point location) |
+ : TouchEvent(type, location, 0, base::TimeDelta()) {} |
+}; |
+ |
+} // namespace |
+ |
+class TouchSelectionControllerAuraTest |
+ : public aura::test::AuraTestBase, |
+ public TouchSelectionControllerAuraClient { |
+ public: |
+ TouchSelectionControllerAuraTest() : caret_moved_(false), |
+ selection_moved_(false), |
+ selection_points_swapped_(false), |
+ last_command_id_(0), |
+ context_menu_opened_(false) { |
+ } |
+ |
+ ~TouchSelectionControllerAuraTest() override {} |
+ |
+ void ChangeSelection(const gfx::PointF& start_top, |
+ const gfx::PointF& start_bottom, |
+ const gfx::PointF& end_top, |
+ const gfx::PointF& end_bottom) { |
+ SelectionBound start_bound, end_bound; |
+ start_bound.set_type(SelectionBound::LEFT); |
+ end_bound.set_type(SelectionBound::RIGHT); |
+ start_bound.SetEdge(start_top, start_bottom); |
+ end_bound.SetEdge(end_top, end_bottom); |
+ start_bound.set_visible(true); |
+ end_bound.set_visible(true); |
+ controller_->OnSelectionBoundsUpdated(start_bound, end_bound); |
+ } |
+ |
+ void ChangeInsertion(const gfx::Point& top, |
+ const gfx::Point& bottom) { |
+ SelectionBound bound; |
+ bound.set_type(SelectionBound::CENTER); |
+ bound.SetEdge(top, bottom); |
+ bound.set_visible(true); |
+ controller_->OnSelectionBoundsUpdated(bound, bound); |
+ } |
+ |
+ void ClearSelection() { |
+ controller_->OnSelectionBoundsUpdated(SelectionBound(), |
+ SelectionBound()); |
+ } |
+ |
+ void ClearInsertion() { ClearSelection(); } |
+ |
+ bool GetAndResetCaretMoved() { |
+ bool moved = caret_moved_; |
+ caret_moved_ = false; |
+ return moved; |
+ } |
+ |
+ bool GetAndResetSelectionMoved() { |
+ bool moved = selection_moved_; |
+ selection_moved_ = false; |
+ return moved; |
+ } |
+ |
+ bool GetAndResetSelectionPointsSwapped() { |
+ bool swapped = selection_points_swapped_; |
+ selection_points_swapped_ = false; |
+ return swapped; |
+ } |
+ |
+ const gfx::PointF& GetLastCaretPosition() const { return caret_position_; } |
+ const gfx::PointF& GetLastSelectionStart() const { return selection_start_; } |
+ const gfx::PointF& GetLastSelectionEnd() const { return selection_end_; } |
+ |
+ TouchSelectionControllerAura& controller() const { return *controller_; } |
+ |
+ TouchHandleDrawableAura* GetInsertionHandleDrawable() const { |
+ return static_cast<TouchHandleDrawableAura*>( |
+ controller_->controller_for_testing()->insertion_handle_for_testing() |
+ ->drawable_for_testing()); |
+ } |
+ |
+ aura::Window* GetInsertionHandleWindow() const { |
+ return GetInsertionHandleDrawable()->window_for_testing(); |
+ } |
+ |
+ bool IsInsertionActive() const { |
+ return controller_->controller_for_testing()->is_insertion_active(); |
+ } |
+ |
+ bool IsSelectionActive() const { |
+ return controller_->controller_for_testing()->is_selection_active(); |
+ } |
+ |
+ bool IsMenuRunning() const { |
+ return menu_runner_->IsRunning(); |
+ } |
+ |
+ private: |
+ // aura::test::AuraTestBase: |
+ void SetUp() override { |
+ AuraTestBase::SetUp(); |
+ |
+ parent_window_.reset(CreateNormalWindow(0, root_window(), NULL)); |
+ parent_window_->SetBounds(gfx::Rect(0, 0, 400, 400)); |
+ |
+ controller_.reset(new TouchSelectionControllerAura(this)); |
+ controller_->set_immediate_quick_menu_for_testing(true); |
+ |
+ menu_runner_.reset(new TestTouchSelectionMenuRunner()); |
+ } |
+ |
+ void TearDown() override { |
+ menu_runner_.reset(); |
+ controller_.reset(); |
+ parent_window_.reset(); |
+ |
+ AuraTestBase::TearDown(); |
+ } |
+ |
+ // TouchSelectionControllerAuraClient: |
+ void MoveCaret(const gfx::PointF& position) override { |
+ caret_moved_ = true; |
+ caret_position_ = position; |
+ } |
+ |
+ void MoveRangeSelectionExtent(const gfx::PointF& extent) override { |
+ selection_moved_ = true; |
+ selection_end_ = extent; |
+ } |
+ |
+ void SelectBetweenCoordinates(const gfx::PointF& base, |
+ const gfx::PointF& extent) override { |
+ if (base == selection_end_ && extent == selection_start_) |
+ selection_points_swapped_ = true; |
+ |
+ selection_start_ = base; |
+ selection_end_ = extent; |
+ } |
+ |
+ aura::Window* GetParentWindow() const override { |
+ return parent_window_.get(); |
+ } |
+ |
+ bool IsCommandIdEnabled(int command_id) const override { |
+ return true; |
+ } |
+ |
+ void ExecuteCommand(int command_id, int event_flags) override { |
+ last_command_id_ = command_id; |
+ } |
+ |
+ void OpenContextMenu(const gfx::PointF& point) override { |
+ context_menu_opened_ = true; |
+ } |
+ |
+ gfx::Rect ConvertRectToScreen(const gfx::Rect& rect) const override { |
+ return rect; |
+ } |
+ |
+ scoped_ptr<aura::Window> parent_window_; |
+ gfx::PointF caret_position_; |
+ gfx::PointF selection_start_; |
+ gfx::PointF selection_end_; |
+ bool caret_moved_; |
+ bool selection_moved_; |
+ bool selection_points_swapped_; |
+ int last_command_id_; |
+ bool context_menu_opened_; |
+ scoped_ptr<TouchSelectionControllerAura> controller_; |
+ scoped_ptr<TouchSelectionMenuRunner> menu_runner_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(TouchSelectionControllerAuraTest); |
+}; |
+ |
+TEST_F(TouchSelectionControllerAuraTest, QuickMenuShowHide) { |
+ gfx::Point top(5, 5); |
+ gfx::Point bottom(5, 15); |
+ |
+ controller().OnSelectionEditable(true); |
+ ui::GestureEventForTest tap(ui::ET_GESTURE_TAP, top.x(), top.y()); |
+ controller().HandleGestureEvent(&tap); |
+ ChangeInsertion(top, bottom); |
+ EXPECT_TRUE(IsInsertionActive()); |
+ EXPECT_FALSE(IsSelectionActive()); |
+ EXPECT_TRUE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning()); |
+ EXPECT_TRUE(IsMenuRunning()); |
+ |
+ ClearInsertion(); |
+ EXPECT_FALSE(IsInsertionActive()); |
+ EXPECT_FALSE(IsSelectionActive()); |
+ EXPECT_FALSE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning()); |
+ EXPECT_FALSE(IsMenuRunning()); |
+} |
+ |
+TEST_F(TouchSelectionControllerAuraTest, QuickMenuHiddenOnScroll) { |
+ gfx::Point top(5, 5); |
+ gfx::Point bottom(5, 15); |
+ |
+ controller().OnSelectionEditable(true); |
+ ui::GestureEventForTest tap(ui::ET_GESTURE_TAP, top.x(), top.y()); |
+ controller().HandleGestureEvent(&tap); |
+ ChangeInsertion(top, bottom); |
+ EXPECT_TRUE(IsInsertionActive()); |
+ EXPECT_FALSE(IsSelectionActive()); |
+ EXPECT_TRUE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning()); |
+ EXPECT_TRUE(IsMenuRunning()); |
+ |
+ ui::GestureEventForTest scroll_begin(ui::ET_GESTURE_SCROLL_BEGIN, top.x(), |
+ top.y()); |
+ controller().HandleGestureEvent(&scroll_begin); |
+ EXPECT_TRUE(IsInsertionActive()); |
+ EXPECT_FALSE(IsSelectionActive()); |
+ EXPECT_FALSE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning()); |
+ EXPECT_FALSE(IsMenuRunning()); |
+ |
+ ui::GestureEventForTest scroll_end(ui::ET_GESTURE_SCROLL_END, top.x(), |
+ top.y()); |
+ controller().HandleGestureEvent(&scroll_end); |
+ EXPECT_TRUE(IsInsertionActive()); |
+ EXPECT_FALSE(IsSelectionActive()); |
+ EXPECT_TRUE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning()); |
+ EXPECT_TRUE(IsMenuRunning()); |
+ |
+ ClearInsertion(); |
+ EXPECT_FALSE(IsInsertionActive()); |
+ EXPECT_FALSE(IsSelectionActive()); |
+ EXPECT_FALSE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning()); |
+ EXPECT_FALSE(IsMenuRunning()); |
+} |
+ |
+TEST_F(TouchSelectionControllerAuraTest, QuickMenuHiddenOnHandleDrag) { |
+ gfx::Point top(5, 5); |
+ gfx::Point bottom(5, 15); |
+ |
+ controller().OnSelectionEditable(true); |
+ ui::GestureEventForTest tap(ui::ET_GESTURE_TAP, top.x(), top.y()); |
+ controller().HandleGestureEvent(&tap); |
+ ChangeInsertion(top, bottom); |
+ EXPECT_TRUE(IsInsertionActive()); |
+ EXPECT_FALSE(IsSelectionActive()); |
+ EXPECT_TRUE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning()); |
+ EXPECT_TRUE(IsMenuRunning()); |
+ |
+ gfx::Point drag_point = |
+ GetInsertionHandleWindow()->GetBoundsInScreen().CenterPoint(); |
+ |
+ ui::TouchEventForTest touch_pressed(ui::ET_TOUCH_PRESSED, drag_point); |
+ controller().HandleTouchEvent(&touch_pressed); |
+ EXPECT_TRUE(IsInsertionActive()); |
+ EXPECT_FALSE(IsSelectionActive()); |
+ EXPECT_FALSE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning()); |
+ EXPECT_FALSE(IsMenuRunning()); |
+ |
+ ui::TouchEventForTest touch_released(ui::ET_TOUCH_RELEASED, drag_point); |
+ controller().HandleTouchEvent(&touch_released); |
+ EXPECT_TRUE(IsInsertionActive()); |
+ EXPECT_FALSE(IsSelectionActive()); |
+ EXPECT_TRUE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning()); |
+ EXPECT_TRUE(IsMenuRunning()); |
+ |
+ ClearInsertion(); |
+ EXPECT_FALSE(IsInsertionActive()); |
+ EXPECT_FALSE(IsSelectionActive()); |
+ EXPECT_FALSE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning()); |
+ EXPECT_FALSE(IsMenuRunning()); |
+} |
+ |
+TEST_F(TouchSelectionControllerAuraTest, TapOverSelection) { |
+ gfx::Point start_top(5, 5); |
+ gfx::Point start_bottom(5, 15); |
+ gfx::Point middle(15, 10); |
+ gfx::Point end_top(25, 5); |
+ gfx::Point end_bottom(25, 15); |
+ |
+ controller().OnSelectionEditable(false); |
+ ChangeSelection(start_top, start_bottom, end_top, end_bottom); |
+ EXPECT_FALSE(IsInsertionActive()); |
+ EXPECT_FALSE(IsSelectionActive()); |
+ |
+ ui::GestureEventForTest tap(ui::ET_GESTURE_TAP, middle.x(), middle.y()); |
+ controller().HandleGestureEvent(&tap); |
+ EXPECT_FALSE(IsInsertionActive()); |
+ EXPECT_TRUE(IsSelectionActive()); |
+ |
+ ClearSelection(); |
+ EXPECT_FALSE(IsInsertionActive()); |
+ EXPECT_FALSE(IsSelectionActive()); |
+} |
+ |
+TEST_F(TouchSelectionControllerAuraTest, DeactivatedOnKeyEvent) { |
+ gfx::Point top(5, 5); |
+ gfx::Point bottom(5, 15); |
+ |
+ RunAllPendingInMessageLoop(); |
+ controller().OnSelectionEditable(true); |
+ ui::GestureEventForTest tap(ui::ET_GESTURE_TAP, top.x(), top.y()); |
+ controller().HandleGestureEvent(&tap); |
+ ChangeInsertion(top, bottom); |
+ EXPECT_TRUE(IsInsertionActive()); |
+ EXPECT_FALSE(IsSelectionActive()); |
+ |
+ test::EventGenerator generator(root_window()); |
+ generator.PressKey(VKEY_A, 0); |
+ RunAllPendingInMessageLoop(); |
+ EXPECT_FALSE(IsInsertionActive()); |
+ EXPECT_FALSE(IsSelectionActive()); |
+} |
+ |
+TEST_F(TouchSelectionControllerAuraTest, DeactivatedOnMouseEvent) { |
+ gfx::Point top(5, 5); |
+ gfx::Point bottom(5, 15); |
+ |
+ RunAllPendingInMessageLoop(); |
+ controller().OnSelectionEditable(true); |
+ ui::GestureEventForTest tap(ui::ET_GESTURE_TAP, top.x(), top.y()); |
+ controller().HandleGestureEvent(&tap); |
+ ChangeInsertion(top, bottom); |
+ EXPECT_TRUE(IsInsertionActive()); |
+ EXPECT_FALSE(IsSelectionActive()); |
+ |
+ test::EventGenerator generator(root_window()); |
+ generator.set_current_location(top); |
+ RunAllPendingInMessageLoop(); |
+ generator.MoveMouseTo(bottom); |
+ RunAllPendingInMessageLoop(); |
+ EXPECT_FALSE(IsInsertionActive()); |
+ EXPECT_FALSE(IsSelectionActive()); |
+} |
+ |
+} // namespace ui |