Index: ui/aura_shell/drag_drop_controller_unittest.cc |
diff --git a/ui/aura_shell/drag_drop_controller_unittest.cc b/ui/aura_shell/drag_drop_controller_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ad87b3d6c04bf54397efe9115ff5c136a30b6140 |
--- /dev/null |
+++ b/ui/aura_shell/drag_drop_controller_unittest.cc |
@@ -0,0 +1,371 @@ |
+// Copyright (c) 2011 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/aura_shell/drag_drop_controller.h" |
+ |
+#include "base/location.h" |
+#include "base/utf_string_conversions.h" |
+#include "ui/aura/client/aura_constants.h" |
+#include "ui/aura/desktop.h" |
+#include "ui/aura/event.h" |
+#include "ui/aura_shell/desktop_event_filter.h" |
+#include "ui/aura_shell/test/aura_shell_test_base.h" |
+#include "ui/base/dragdrop/os_exchange_data.h" |
+#include "ui/base/dragdrop/drag_drop_types.h" |
+#include "views/events/event.h" |
+#include "views/view.h" |
+#include "views/widget/widget.h" |
+ |
+namespace aura_shell { |
+namespace test { |
+ |
+namespace { |
+ |
+// A simple view that makes sure RunShellDrag is invoked on mouse drag. |
+class DragTestView : public views::View { |
+ public: |
+ DragTestView() : views::View() { |
+ Reset(); |
+ } |
+ |
+ void Reset() { |
+ num_drag_enters_ = 0; |
+ num_drag_exits_ = 0; |
+ num_drag_updates_ = 0; |
+ num_drops_ = 0; |
+ drag_done_received_ = false; |
+ } |
+ |
+ int VerticalDragThreshold() { |
+ return views::View::GetVerticalDragThreshold(); |
+ } |
+ |
+ int HorizontalDragThreshold() { |
+ return views::View::GetHorizontalDragThreshold(); |
+ } |
+ |
+ int num_drag_enters_; |
+ int num_drag_exits_; |
+ int num_drag_updates_; |
+ int num_drops_; |
+ bool drag_done_received_; |
+ |
+ private: |
+ // View overrides: |
+ int GetDragOperations(const gfx::Point& press_pt) OVERRIDE { |
+ return ui::DragDropTypes::DRAG_COPY; |
+ } |
+ |
+ void WriteDragData(const gfx::Point& p, OSExchangeData* data) OVERRIDE { |
+ data->SetString(UTF8ToUTF16("I am being dragged")); |
+ } |
+ |
+ bool OnMousePressed(const views::MouseEvent& event) OVERRIDE { |
+ return true; |
+ } |
+ |
+ bool GetDropFormats(int* formats, |
+ std::set<OSExchangeData::CustomFormat>* custom_formats) { |
+ *formats = ui::OSExchangeData::STRING; |
+ return true; |
+ } |
+ |
+ bool CanDrop(const OSExchangeData& data) OVERRIDE { |
+ return true; |
+ } |
+ |
+ void OnDragEntered(const views::DropTargetEvent& event) OVERRIDE { |
+ num_drag_enters_++; |
+ } |
+ |
+ int OnDragUpdated(const views::DropTargetEvent& event) OVERRIDE { |
+ num_drag_updates_++; |
+ return ui::DragDropTypes::DRAG_COPY; |
+ } |
+ |
+ void OnDragExited() OVERRIDE { |
+ num_drag_exits_++; |
+ } |
+ |
+ int OnPerformDrop(const views::DropTargetEvent& event) OVERRIDE { |
+ num_drops_++; |
+ return ui::DragDropTypes::DRAG_COPY; |
+ } |
+ |
+ void OnDragDone() OVERRIDE { |
+ drag_done_received_ = true; |
+ } |
+ |
+ DISALLOW_COPY_AND_ASSIGN(DragTestView); |
+}; |
+ |
+class TestDragDropController : public internal::DragDropController { |
+ public: |
+ TestDragDropController() : internal::DragDropController() { |
+ Reset(); |
+ } |
+ |
+ void Reset() { |
+ drag_start_received_ = false; |
+ num_drag_updates_ = 0; |
+ drop_received_ = false; |
+ drag_string_.clear(); |
+ } |
+ |
+ bool drag_start_received_; |
+ int num_drag_updates_; |
+ bool drop_received_; |
+ string16 drag_string_; |
+ |
+ private: |
+ void StartDragAndDrop(const ui::OSExchangeData& data, |
+ int operation) OVERRIDE { |
+ DragDropController::StartDragAndDrop(data, operation); |
+ drag_start_received_ = true; |
+ data.GetString(&drag_string_); |
+ } |
+ |
+ void DragUpdate(aura::Window* target, |
+ const aura::MouseEvent& event) OVERRIDE { |
+ DragDropController::DragUpdate(target, event); |
+ num_drag_updates_++; |
+ } |
+ |
+ void Drop(aura::Window* target, const aura::MouseEvent& event) OVERRIDE { |
+ DragDropController::Drop(target, event); |
+ drop_received_ = true; |
+ } |
+ |
+ DISALLOW_COPY_AND_ASSIGN(TestDragDropController); |
+}; |
+ |
+views::Widget* CreateNewWidget() { |
+ views::Widget* widget = new views::Widget; |
+ views::Widget::InitParams params; |
+ params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS; |
+ params.accept_events = true; |
+ params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
+ params.parent = aura::Desktop::GetInstance(); |
+ params.child = true; |
+ widget->Init(params); |
+ widget->Show(); |
+ return widget; |
+} |
+ |
+void AddViewToWidgetAndResize(views::Widget* widget, views::View* view) { |
+ if (!widget->GetContentsView()) { |
+ views::View* contents_view = new views::View; |
+ widget->SetContentsView(contents_view); |
+ } |
+ |
+ views::View* contents_view = widget->GetContentsView(); |
+ contents_view->AddChildView(view); |
+ view->SetBounds(contents_view->width(), 0, 100, 100); |
+ gfx::Rect contents_view_bounds = contents_view->bounds(); |
+ contents_view_bounds = contents_view_bounds.Union(view->bounds()); |
+ contents_view->SetBoundsRect(contents_view_bounds); |
+ widget->SetBounds(contents_view_bounds); |
+} |
+ |
+} // namespace |
+ |
+class DragDropControllerTest : public AuraShellTestBase { |
+ public: |
+ DragDropControllerTest() : AuraShellTestBase() { |
+ } |
+ |
+ virtual ~DragDropControllerTest() { |
+ aura::Desktop::GetInstance()->SetProperty(aura::kDesktopDragDropClientKey, |
+ NULL); |
+ } |
+ |
+ void SetUp() OVERRIDE { |
+ AuraShellTestBase::SetUp(); |
+ drag_drop_controller_ = new TestDragDropController; |
+ drag_drop_controller_->set_should_block_during_drag_drop(false); |
+ aura::Desktop::GetInstance()->SetProperty(aura::kDesktopDragDropClientKey, |
+ drag_drop_controller_); |
+ } |
+ |
+ void TearDown() OVERRIDE { |
+ delete drag_drop_controller_; |
+ drag_drop_controller_ = NULL; |
+ AuraShellTestBase::TearDown(); |
+ } |
+ |
+ void UpdateDragData(ui::OSExchangeData* data) { |
+ drag_drop_controller_->drag_data_ = data; |
+ } |
+ |
+ protected: |
+ TestDragDropController* drag_drop_controller_; |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(DragDropControllerTest); |
+}; |
+ |
+TEST_F(DragDropControllerTest, DragDropInSingleViewTest) { |
+ views::Widget* widget = CreateNewWidget(); |
+ DragTestView* drag_view = new DragTestView; |
+ AddViewToWidgetAndResize(widget, drag_view); |
+ gfx::Point point = gfx::Rect(drag_view->bounds()).CenterPoint(); |
+ ui::OSExchangeData data; |
+ data.SetString(UTF8ToUTF16("I am being dragged")); |
+ |
+ aura::MouseEvent event1(ui::ET_MOUSE_PRESSED, point, ui::EF_LEFT_BUTTON_DOWN); |
+ aura::Desktop::GetInstance()->DispatchMouseEvent(&event1); |
+ |
+ int num_drags = 17; |
+ for (int i = 0; i < num_drags; ++i) { |
+ // Because we are not doing a blocking drag and drop, the original |
+ // OSDragExchangeData object is lost as soon as we return from the drag |
+ // initiation in DragDropController::StartDragAndDrop(). Hence we set the |
+ // drag_data_ to a fake drag data object that we created. |
+ if (i > 0) |
+ UpdateDragData(&data); |
+ point.Offset(0, 1); |
+ aura::MouseEvent drag_event(ui::ET_MOUSE_DRAGGED, point, |
+ ui::EF_LEFT_BUTTON_DOWN); |
+ aura::Desktop::GetInstance()->DispatchMouseEvent(&drag_event); |
+ } |
+ |
+ aura::MouseEvent event2(ui::ET_MOUSE_RELEASED, point, 0); |
+ aura::Desktop::GetInstance()->DispatchMouseEvent(&event2); |
+ |
+ EXPECT_TRUE(drag_drop_controller_->drag_start_received_); |
+ EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold(), |
+ drag_drop_controller_->num_drag_updates_); |
+ EXPECT_TRUE(drag_drop_controller_->drop_received_); |
+ EXPECT_EQ(UTF8ToUTF16("I am being dragged"), |
+ drag_drop_controller_->drag_string_); |
+ |
+ EXPECT_EQ(1, drag_view->num_drag_enters_); |
+ EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold(), |
+ drag_view->num_drag_updates_); |
+ EXPECT_EQ(1, drag_view->num_drops_); |
+ EXPECT_EQ(0, drag_view->num_drag_exits_); |
+ EXPECT_TRUE(drag_view->drag_done_received_); |
+ delete widget; |
+} |
+ |
+TEST_F(DragDropControllerTest, DragDropInMultipleViewsSingleWidgetTest) { |
+ views::Widget* widget = CreateNewWidget(); |
+ DragTestView* drag_view1 = new DragTestView; |
+ AddViewToWidgetAndResize(widget, drag_view1); |
+ gfx::Point point = drag_view1->bounds().CenterPoint(); |
+ DragTestView* drag_view2 = new DragTestView; |
+ AddViewToWidgetAndResize(widget, drag_view2); |
+ |
+ ui::OSExchangeData data; |
+ data.SetString(UTF8ToUTF16("I am being dragged")); |
+ |
+ aura::MouseEvent event1(ui::ET_MOUSE_PRESSED, point, ui::EF_LEFT_BUTTON_DOWN); |
+ aura::Desktop::GetInstance()->DispatchMouseEvent(&event1); |
+ |
+ int num_drags = drag_view1->width(); |
+ for (int i = 0; i < num_drags; ++i) { |
+ // Because we are not doing a blocking drag and drop, the original |
+ // OSDragExchangeData object is lost as soon as we return from the drag |
+ // initiation in DragDropController::StartDragAndDrop(). Hence we set the |
+ // drag_data_ to a fake drag data object that we created. |
+ if (i > 0) |
+ UpdateDragData(&data); |
+ point.Offset(1, 0); |
+ aura::MouseEvent drag_event(ui::ET_MOUSE_DRAGGED, point, |
+ ui::EF_LEFT_BUTTON_DOWN); |
+ aura::Desktop::GetInstance()->DispatchMouseEvent(&drag_event); |
+ } |
+ |
+ aura::MouseEvent event2(ui::ET_MOUSE_RELEASED, point, 0); |
+ aura::Desktop::GetInstance()->DispatchMouseEvent(&event2); |
+ |
+ EXPECT_TRUE(drag_drop_controller_->drag_start_received_); |
+ EXPECT_EQ(num_drags - 1 - drag_view1->HorizontalDragThreshold(), |
+ drag_drop_controller_->num_drag_updates_); |
+ EXPECT_TRUE(drag_drop_controller_->drop_received_); |
+ EXPECT_EQ(UTF8ToUTF16("I am being dragged"), |
+ drag_drop_controller_->drag_string_); |
+ |
+ EXPECT_EQ(1, drag_view1->num_drag_enters_); |
+ int num_expected_updates = drag_view1->bounds().width() - |
+ drag_view1->bounds().CenterPoint().x() - 2; |
+ EXPECT_EQ(num_expected_updates - drag_view1->HorizontalDragThreshold(), |
+ drag_view1->num_drag_updates_); |
+ EXPECT_EQ(0, drag_view1->num_drops_); |
+ EXPECT_EQ(1, drag_view1->num_drag_exits_); |
+ EXPECT_TRUE(drag_view1->drag_done_received_); |
+ |
+ EXPECT_EQ(1, drag_view2->num_drag_enters_); |
+ num_expected_updates = num_drags - num_expected_updates - 1; |
+ EXPECT_EQ(num_expected_updates, drag_view2->num_drag_updates_); |
+ EXPECT_EQ(1, drag_view2->num_drops_); |
+ EXPECT_EQ(0, drag_view2->num_drag_exits_); |
+ EXPECT_FALSE(drag_view2->drag_done_received_); |
+ delete widget; |
+} |
+ |
+TEST_F(DragDropControllerTest, DragDropInMultipleViewsMultipleWidgetsTest) { |
+ views::Widget* widget1 = CreateNewWidget(); |
+ DragTestView* drag_view1 = new DragTestView; |
+ AddViewToWidgetAndResize(widget1, drag_view1); |
+ gfx::Point point = drag_view1->bounds().CenterPoint(); |
+ views::Widget* widget2 = CreateNewWidget(); |
+ DragTestView* drag_view2 = new DragTestView; |
+ AddViewToWidgetAndResize(widget2, drag_view2); |
+ gfx::Rect widget1_bounds = widget1->GetClientAreaScreenBounds(); |
+ gfx::Rect widget2_bounds = widget2->GetClientAreaScreenBounds(); |
+ widget2->SetBounds(gfx::Rect(widget1_bounds.width(), 0, |
+ widget2_bounds.width(), widget2_bounds.height())); |
+ |
+ ui::OSExchangeData data; |
+ data.SetString(UTF8ToUTF16("I am being dragged")); |
+ |
+ aura::MouseEvent event1(ui::ET_MOUSE_PRESSED, point, ui::EF_LEFT_BUTTON_DOWN); |
+ aura::Desktop::GetInstance()->DispatchMouseEvent(&event1); |
+ |
+ int num_drags = drag_view1->width(); |
+ for (int i = 0; i < num_drags; ++i) { |
+ // Because we are not doing a blocking drag and drop, the original |
+ // OSDragExchangeData object is lost as soon as we return from the drag |
+ // initiation in DragDropController::StartDragAndDrop(). Hence we set the |
+ // drag_data_ to a fake drag data object that we created. |
+ if (i > 0) |
+ UpdateDragData(&data); |
+ point.Offset(1, 0); |
+ aura::MouseEvent drag_event(ui::ET_MOUSE_DRAGGED, point, |
+ ui::EF_LEFT_BUTTON_DOWN); |
+ aura::Desktop::GetInstance()->DispatchMouseEvent(&drag_event); |
+ } |
+ |
+ aura::MouseEvent event2(ui::ET_MOUSE_RELEASED, point, 0); |
+ aura::Desktop::GetInstance()->DispatchMouseEvent(&event2); |
+ |
+ EXPECT_TRUE(drag_drop_controller_->drag_start_received_); |
+ EXPECT_EQ(num_drags - 1 - drag_view1->HorizontalDragThreshold(), |
+ drag_drop_controller_->num_drag_updates_); |
+ EXPECT_TRUE(drag_drop_controller_->drop_received_); |
+ EXPECT_EQ(UTF8ToUTF16("I am being dragged"), |
+ drag_drop_controller_->drag_string_); |
+ |
+ EXPECT_EQ(1, drag_view1->num_drag_enters_); |
+ int num_expected_updates = drag_view1->bounds().width() - |
+ drag_view1->bounds().CenterPoint().x() - 2; |
+ EXPECT_EQ(num_expected_updates - drag_view1->HorizontalDragThreshold(), |
+ drag_view1->num_drag_updates_); |
+ EXPECT_EQ(0, drag_view1->num_drops_); |
+ EXPECT_EQ(1, drag_view1->num_drag_exits_); |
+ EXPECT_TRUE(drag_view1->drag_done_received_); |
+ |
+ EXPECT_EQ(1, drag_view2->num_drag_enters_); |
+ num_expected_updates = num_drags - num_expected_updates - 2; |
+ EXPECT_EQ(num_expected_updates, drag_view2->num_drag_updates_); |
+ EXPECT_EQ(1, drag_view2->num_drops_); |
+ EXPECT_EQ(0, drag_view2->num_drag_exits_); |
+ EXPECT_FALSE(drag_view2->drag_done_received_); |
+ delete widget1; |
+ delete widget2; |
+} |
+ |
+} // namespace test |
+} // namespace aura |