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

Side by Side Diff: ui/views/widget/widget_unittest.cc

Issue 322893005: MacViews: Add WidgetEventGenerator to abstract platform-specific event generation for tests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: No inheritance Created 6 years, 5 months 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 #include <algorithm> 5 #include <algorithm>
6 #include <set> 6 #include <set>
7 7
8 #include "base/basictypes.h" 8 #include "base/basictypes.h"
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop/message_loop.h" 11 #include "base/message_loop/message_loop.h"
12 #include "base/run_loop.h" 12 #include "base/run_loop.h"
13 #include "base/strings/utf_string_conversions.h" 13 #include "base/strings/utf_string_conversions.h"
14 #include "testing/gtest/include/gtest/gtest.h" 14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "ui/aura/test/event_generator.h"
16 #include "ui/aura/window.h"
17 #include "ui/base/hit_test.h" 15 #include "ui/base/hit_test.h"
18 #include "ui/compositor/layer_animation_observer.h" 16 #include "ui/compositor/layer_animation_observer.h"
19 #include "ui/compositor/scoped_animation_duration_scale_mode.h" 17 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
20 #include "ui/compositor/scoped_layer_animation_settings.h" 18 #include "ui/compositor/scoped_layer_animation_settings.h"
21 #include "ui/events/event_processor.h" 19 #include "ui/events/event_processor.h"
22 #include "ui/events/event_utils.h" 20 #include "ui/events/event_utils.h"
21 #include "ui/events/test/event_generator.h"
23 #include "ui/gfx/native_widget_types.h" 22 #include "ui/gfx/native_widget_types.h"
24 #include "ui/gfx/point.h" 23 #include "ui/gfx/point.h"
25 #include "ui/views/bubble/bubble_delegate.h" 24 #include "ui/views/bubble/bubble_delegate.h"
26 #include "ui/views/controls/textfield/textfield.h" 25 #include "ui/views/controls/textfield/textfield.h"
27 #include "ui/views/test/test_views_delegate.h" 26 #include "ui/views/test/test_views_delegate.h"
28 #include "ui/views/test/widget_test.h" 27 #include "ui/views/test/widget_test.h"
29 #include "ui/views/views_delegate.h" 28 #include "ui/views/views_delegate.h"
30 #include "ui/views/widget/native_widget_delegate.h" 29 #include "ui/views/widget/native_widget_delegate.h"
31 #include "ui/views/widget/root_view.h" 30 #include "ui/views/widget/root_view.h"
32 #include "ui/views/widget/widget_deletion_observer.h" 31 #include "ui/views/widget/widget_deletion_observer.h"
33 #include "ui/views/window/dialog_delegate.h" 32 #include "ui/views/window/dialog_delegate.h"
34 #include "ui/views/window/native_frame_view.h" 33 #include "ui/views/window/native_frame_view.h"
35 34
36 #if defined(OS_WIN) 35 #if defined(OS_WIN)
37 #include "ui/views/win/hwnd_util.h" 36 #include "ui/views/win/hwnd_util.h"
38 #endif 37 #endif
39 38
40 namespace views { 39 namespace views {
41 namespace test { 40 namespace test {
42 41
43 // A view that keeps track of the events it receives, but consumes no events. 42 // A view that keeps track of the events it receives, optionally consuming them.
44 class EventCountView : public View { 43 class EventCountView : public View {
45 public: 44 public:
46 EventCountView() {} 45 // Whether to call SetHandled() on events as they are received. For some event
46 // types, this will allow EventCountView to receives future events in the
47 // event sequence, such as a drag.
48 enum HandleMode {
49 PROPAGATE_EVENTS,
50 CONSUME_EVENTS
51 };
52
53 EventCountView()
54 : last_flags_(0),
55 handle_mode_(PROPAGATE_EVENTS) {}
56
47 virtual ~EventCountView() {} 57 virtual ~EventCountView() {}
48 58
49 int GetEventCount(ui::EventType type) { 59 int GetEventCount(ui::EventType type) {
50 return event_count_[type]; 60 return event_count_[type];
51 } 61 }
52 62
53 void ResetCounts() { 63 void ResetCounts() {
54 event_count_.clear(); 64 event_count_.clear();
55 } 65 }
56 66
67 int last_flags() const {
68 return last_flags_;
69 }
70
71 void set_handle_mode(HandleMode handle_mode) {
72 handle_mode_ = handle_mode;
73 }
74
57 protected: 75 protected:
76 // Overridden from View:
77 virtual void OnMouseMoved(const ui::MouseEvent& event) OVERRIDE {
78 // MouseMove events are not re-dispatched from the RootView.
79 ++event_count_[ui::ET_MOUSE_MOVED];
80 last_flags_ = 0;
81 }
82
58 // Overridden from ui::EventHandler: 83 // Overridden from ui::EventHandler:
59 virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE { 84 virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE {
60 RecordEvent(*event); 85 RecordEvent(event);
61 } 86 }
62 virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE { 87 virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
63 RecordEvent(*event); 88 RecordEvent(event);
64 } 89 }
65 virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE { 90 virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE {
66 RecordEvent(*event); 91 RecordEvent(event);
67 } 92 }
68 virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE { 93 virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
69 RecordEvent(*event); 94 RecordEvent(event);
70 } 95 }
71 96
72 private: 97 private:
73 void RecordEvent(const ui::Event& event) { 98 void RecordEvent(ui::Event* event) {
74 ++event_count_[event.type()]; 99 ++event_count_[event->type()];
100 last_flags_ = event->flags();
101 if (handle_mode_ == CONSUME_EVENTS)
102 event->SetHandled();
75 } 103 }
76 104
77 std::map<ui::EventType, int> event_count_; 105 std::map<ui::EventType, int> event_count_;
106 int last_flags_;
107 HandleMode handle_mode_;
78 108
79 DISALLOW_COPY_AND_ASSIGN(EventCountView); 109 DISALLOW_COPY_AND_ASSIGN(EventCountView);
80 }; 110 };
81 111
82 // A view that keeps track of the events it receives, and consumes all scroll 112 // A view that keeps track of the events it receives, and consumes all scroll
83 // gesture events and ui::ET_SCROLL events. 113 // gesture events and ui::ET_SCROLL events.
84 class ScrollableEventCountView : public EventCountView { 114 class ScrollableEventCountView : public EventCountView {
85 public: 115 public:
86 ScrollableEventCountView() {} 116 ScrollableEventCountView() {}
87 virtual ~ScrollableEventCountView() {} 117 virtual ~ScrollableEventCountView() {}
(...skipping 1430 matching lines...) Expand 10 before | Expand all | Expand 10 after
1518 widget->Show(); 1548 widget->Show();
1519 widget->SetSize(gfx::Size(300, 300)); 1549 widget->SetSize(gfx::Size(300, 300));
1520 1550
1521 EventCountView* event_count_view = new EventCountView(); 1551 EventCountView* event_count_view = new EventCountView();
1522 event_count_view->SetBounds(0, 0, 300, 300); 1552 event_count_view->SetBounds(0, 0, 300, 300);
1523 widget->GetRootView()->AddChildView(event_count_view); 1553 widget->GetRootView()->AddChildView(event_count_view);
1524 1554
1525 MousePressEventConsumer consumer; 1555 MousePressEventConsumer consumer;
1526 event_count_view->AddPostTargetHandler(&consumer); 1556 event_count_view->AddPostTargetHandler(&consumer);
1527 1557
1528 aura::test::EventGenerator generator(GetContext(), widget->GetNativeWindow()); 1558 ui::test::EventGenerator generator(GetContext(), widget->GetNativeWindow());
1529 generator.PressTouch(); 1559 generator.PressTouch();
1530 generator.ClickLeftButton(); 1560 generator.ClickLeftButton();
1531 1561
1532 EXPECT_EQ(1, event_count_view->GetEventCount(ui::ET_MOUSE_PRESSED)); 1562 EXPECT_EQ(1, event_count_view->GetEventCount(ui::ET_MOUSE_PRESSED));
1533 EXPECT_EQ(1, event_count_view->GetEventCount(ui::ET_MOUSE_RELEASED)); 1563 EXPECT_EQ(1, event_count_view->GetEventCount(ui::ET_MOUSE_RELEASED));
1534 1564
1535 widget->CloseNow(); 1565 widget->CloseNow();
1536 } 1566 }
1537 1567
1538 // Used by SingleWindowClosing to count number of times WindowClosing() has 1568 // Used by SingleWindowClosing to count number of times WindowClosing() has
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1638 Widget* widget = new Widget; 1668 Widget* widget = new Widget;
1639 Widget::InitParams params = 1669 Widget::InitParams params =
1640 CreateParams(views::Widget::InitParams::TYPE_POPUP); 1670 CreateParams(views::Widget::InitParams::TYPE_POPUP);
1641 widget->Init(params); 1671 widget->Init(params);
1642 1672
1643 widget->SetContentsView(new CloseWidgetView(ui::ET_MOUSE_PRESSED)); 1673 widget->SetContentsView(new CloseWidgetView(ui::ET_MOUSE_PRESSED));
1644 1674
1645 widget->SetSize(gfx::Size(100, 100)); 1675 widget->SetSize(gfx::Size(100, 100));
1646 widget->Show(); 1676 widget->Show();
1647 1677
1648 aura::test::EventGenerator generator(GetContext(), widget->GetNativeWindow()); 1678 ui::test::EventGenerator generator(GetContext(), widget->GetNativeWindow());
1649 1679
1650 WidgetDeletionObserver deletion_observer(widget); 1680 WidgetDeletionObserver deletion_observer(widget);
1651 generator.ClickLeftButton(); 1681 generator.ClickLeftButton();
1652 EXPECT_FALSE(deletion_observer.IsWidgetAlive()); 1682 EXPECT_FALSE(deletion_observer.IsWidgetAlive());
1653 1683
1654 // Yay we did not crash! 1684 // Yay we did not crash!
1655 } 1685 }
1656 1686
1657 TEST_F(WidgetTest, WidgetDeleted_InDispatchGestureEvent) { 1687 TEST_F(WidgetTest, WidgetDeleted_InDispatchGestureEvent) {
1658 Widget* widget = new Widget; 1688 Widget* widget = new Widget;
1659 Widget::InitParams params = 1689 Widget::InitParams params =
1660 CreateParams(views::Widget::InitParams::TYPE_POPUP); 1690 CreateParams(views::Widget::InitParams::TYPE_POPUP);
1661 widget->Init(params); 1691 widget->Init(params);
1662 1692
1663 widget->SetContentsView(new CloseWidgetView(ui::ET_GESTURE_TAP_DOWN)); 1693 widget->SetContentsView(new CloseWidgetView(ui::ET_GESTURE_TAP_DOWN));
1664 1694
1665 widget->SetSize(gfx::Size(100, 100)); 1695 widget->SetSize(gfx::Size(100, 100));
1666 widget->Show(); 1696 widget->Show();
1667 1697
1668 aura::test::EventGenerator generator(GetContext()); 1698 ui::test::EventGenerator generator(GetContext(), widget->GetNativeWindow());
1669 1699
1670 WidgetDeletionObserver deletion_observer(widget); 1700 WidgetDeletionObserver deletion_observer(widget);
1671 generator.GestureTapAt(widget->GetWindowBoundsInScreen().CenterPoint()); 1701 generator.GestureTapAt(widget->GetWindowBoundsInScreen().CenterPoint());
1672 EXPECT_FALSE(deletion_observer.IsWidgetAlive()); 1702 EXPECT_FALSE(deletion_observer.IsWidgetAlive());
1673 1703
1674 // Yay we did not crash! 1704 // Yay we did not crash!
1675 } 1705 }
1676 1706
1677 // See description of RunGetNativeThemeFromDestructor() for details. 1707 // See description of RunGetNativeThemeFromDestructor() for details.
1678 class GetNativeThemeFromDestructorView : public WidgetDelegateView { 1708 class GetNativeThemeFromDestructorView : public WidgetDelegateView {
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after
2170 init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 2200 init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
2171 2201
2172 { 2202 {
2173 Widget top_level_widget; 2203 Widget top_level_widget;
2174 top_level_widget.Init(init_params); 2204 top_level_widget.Init(init_params);
2175 top_level_widget.SetFullscreen(true); 2205 top_level_widget.SetFullscreen(true);
2176 EXPECT_EQ(top_level_widget.IsVisible(), 2206 EXPECT_EQ(top_level_widget.IsVisible(),
2177 IsNativeWindowVisible(top_level_widget.GetNativeWindow())); 2207 IsNativeWindowVisible(top_level_widget.GetNativeWindow()));
2178 top_level_widget.CloseNow(); 2208 top_level_widget.CloseNow();
2179 } 2209 }
2180
2181 #if !defined(OS_CHROMEOS) 2210 #if !defined(OS_CHROMEOS)
2182 { 2211 {
2183 Widget top_level_widget; 2212 Widget top_level_widget;
2184 init_params.native_widget = 2213 init_params.native_widget =
2185 new PlatformDesktopNativeWidget(&top_level_widget); 2214 new PlatformDesktopNativeWidget(&top_level_widget);
2186 top_level_widget.Init(init_params); 2215 top_level_widget.Init(init_params);
2187 top_level_widget.SetFullscreen(true); 2216 top_level_widget.SetFullscreen(true);
2188 EXPECT_EQ(top_level_widget.IsVisible(), 2217 EXPECT_EQ(top_level_widget.IsVisible(),
2189 IsNativeWindowVisible(top_level_widget.GetNativeWindow())); 2218 IsNativeWindowVisible(top_level_widget.GetNativeWindow()));
2190 top_level_widget.CloseNow(); 2219 top_level_widget.CloseNow();
2191 } 2220 }
2192 #endif 2221 #endif
2193 } 2222 }
2194
2195 #if defined(OS_WIN) 2223 #if defined(OS_WIN)
2196 2224
2197 // Provides functionality to test widget activation via an activation flag 2225 // Provides functionality to test widget activation via an activation flag
2198 // which can be set by an accessor. 2226 // which can be set by an accessor.
2199 class ModalWindowTestWidgetDelegate : public WidgetDelegate { 2227 class ModalWindowTestWidgetDelegate : public WidgetDelegate {
2200 public: 2228 public:
2201 ModalWindowTestWidgetDelegate() 2229 ModalWindowTestWidgetDelegate()
2202 : widget_(NULL), 2230 : widget_(NULL),
2203 can_activate_(true) {} 2231 can_activate_(true) {}
2204 2232
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
2492 child_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 2520 child_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
2493 child_params.context = parent_widget.GetNativeWindow(); 2521 child_params.context = parent_widget.GetNativeWindow();
2494 child_widget.Init(child_params); 2522 child_widget.Init(child_params);
2495 child_widget.AddObserver(&observer); 2523 child_widget.AddObserver(&observer);
2496 child_widget.Show(); 2524 child_widget.Show();
2497 2525
2498 parent_widget.CloseNow(); 2526 parent_widget.CloseNow();
2499 } 2527 }
2500 #endif // !defined(OS_CHROMEOS) 2528 #endif // !defined(OS_CHROMEOS)
2501 2529
2530 // Tests that events propagate through from the dispatcher with the correct
2531 // event type, and that the different platforms behave the same.
2532 TEST_F(WidgetTest, MouseEventTypesViaGenerator) {
2533 EventCountView* view = new EventCountView;
2534 view->set_handle_mode(EventCountView::CONSUME_EVENTS);
2535 view->SetBounds(10, 10, 50, 40);
2536
2537 Widget* widget = CreateTopLevelFramelessPlatformWidget();
2538 widget->GetRootView()->AddChildView(view);
2539
2540 widget->SetBounds(gfx::Rect(0, 0, 100, 80));
2541 widget->Show();
2542
2543 ui::test::EventGenerator generator(GetContext(), widget->GetNativeWindow());
2544 generator.set_current_location(gfx::Point(20, 20));
2545
2546 generator.ClickLeftButton();
2547 EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSE_PRESSED));
2548 EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSE_RELEASED));
2549 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, view->last_flags());
2550
2551 generator.PressRightButton();
2552 EXPECT_EQ(2, view->GetEventCount(ui::ET_MOUSE_PRESSED));
2553 EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSE_RELEASED));
2554 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON, view->last_flags());
2555
2556 generator.ReleaseRightButton();
2557 EXPECT_EQ(2, view->GetEventCount(ui::ET_MOUSE_PRESSED));
2558 EXPECT_EQ(2, view->GetEventCount(ui::ET_MOUSE_RELEASED));
2559 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON, view->last_flags());
2560
2561 // Test mouse move events.
2562 EXPECT_EQ(0, view->GetEventCount(ui::ET_MOUSE_MOVED));
2563 EXPECT_EQ(0, view->GetEventCount(ui::ET_MOUSE_ENTERED));
2564
2565 // Move the mouse within the view (20, 20) -> (30, 30).
2566 generator.MoveMouseTo(gfx::Point(30, 30));
2567 EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSE_MOVED));
2568 EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSE_ENTERED));
2569 EXPECT_EQ(ui::EF_NONE, view->last_flags());
2570
2571 // Move it again - entered count shouldn't change.
2572 generator.MoveMouseTo(gfx::Point(31, 31));
2573 EXPECT_EQ(2, view->GetEventCount(ui::ET_MOUSE_MOVED));
2574 EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSE_ENTERED));
2575 EXPECT_EQ(0, view->GetEventCount(ui::ET_MOUSE_EXITED));
2576
2577 // Move it off the view.
2578 generator.MoveMouseTo(gfx::Point(5, 5));
2579 EXPECT_EQ(2, view->GetEventCount(ui::ET_MOUSE_MOVED));
2580 EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSE_ENTERED));
2581 EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSE_EXITED));
2582
2583 // Move it back on.
2584 generator.MoveMouseTo(gfx::Point(20, 20));
2585 EXPECT_EQ(3, view->GetEventCount(ui::ET_MOUSE_MOVED));
2586 EXPECT_EQ(2, view->GetEventCount(ui::ET_MOUSE_ENTERED));
2587 EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSE_EXITED));
2588
2589 // Drargging. Cover HasCapture() and NativeWidgetPrivate::IsMouseButtonDown().
2590 generator.DragMouseTo(gfx::Point(40, 40));
2591 EXPECT_EQ(3, view->GetEventCount(ui::ET_MOUSE_PRESSED));
2592 EXPECT_EQ(3, view->GetEventCount(ui::ET_MOUSE_RELEASED));
2593 EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSE_DRAGGED));
2594 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, view->last_flags());
2595
2596 widget->CloseNow();
2597 }
2598
2502 } // namespace test 2599 } // namespace test
2503 } // namespace views 2600 } // namespace views
OLDNEW
« ui/views/test/widget_event_generator_mac.mm ('K') | « ui/views/widget/native_widget_mac.mm ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698