Chromium Code Reviews| Index: views/view_unittest.cc |
| diff --git a/views/view_unittest.cc b/views/view_unittest.cc |
| index 59384b1e6f974387e9c9c75353fff73067322720..2bcd0234ac6bde2629f369745af8b86e9c02cb56 100644 |
| --- a/views/view_unittest.cc |
| +++ b/views/view_unittest.cc |
| @@ -37,12 +37,21 @@ |
| #include "views/widget/root_view.h" |
| #include "views/window/dialog_delegate.h" |
| +#if defined(TOUCH_UI) |
| +// TODO(Gajen): This voilates Google coding style but placing this above |
| +// testing/gmock/include/gmock/gmock.h doesn't let gtest to compile. |
| +#include <X11/Xlib.h> |
|
rjkroege
2011/11/09 02:43:30
I think that the need for this here is a sign of a
Gajen
2011/11/09 18:14:43
This was required to instantiate base::NativeEvent
Gajen
2011/11/10 15:52:55
Deprecated, currently MockGesture is used for GM.
|
| +#endif |
| + |
| #if defined(OS_WIN) |
| #include "views/test/test_views_delegate.h" |
| #endif |
| #if defined(USE_AURA) |
| #include "ui/aura/desktop.h" |
| #endif |
| +#if defined(TOUCH_UI) |
| +#include "views/touchui/gesture_recognizer.h" |
| +#endif |
| using ::testing::_; |
| @@ -204,6 +213,8 @@ class TestView : public View { |
| location_.SetPoint(0, 0); |
| last_touch_event_type_ = 0; |
| last_touch_event_was_handled_ = false; |
| + last_gesture_event_type_ = 0; |
| + last_gesture_event_was_handled_ = false; |
| last_clip_.setEmpty(); |
| accelerator_count_map_.clear(); |
| } |
| @@ -213,6 +224,9 @@ class TestView : public View { |
| virtual bool OnMouseDragged(const MouseEvent& event) OVERRIDE; |
| virtual void OnMouseReleased(const MouseEvent& event) OVERRIDE; |
| virtual ui::TouchStatus OnTouchEvent(const TouchEvent& event) OVERRIDE; |
| + |
| + // Ignores GestureEvent by default. |
| + virtual ui::GestureStatus OnGestureEvent(const GestureEvent& event) OVERRIDE; |
| virtual void Paint(gfx::Canvas* canvas) OVERRIDE; |
| virtual void SchedulePaintInRect(const gfx::Rect& rect) OVERRIDE; |
| virtual bool AcceleratorPressed(const Accelerator& accelerator) OVERRIDE; |
| @@ -233,6 +247,10 @@ class TestView : public View { |
| bool last_touch_event_was_handled_; |
| bool in_touch_sequence_; |
| + // GestureEvent |
| + int last_gesture_event_type_; |
| + bool last_gesture_event_was_handled_; |
| + |
| // Painting. |
| SkRect last_clip_; |
| @@ -264,6 +282,32 @@ class MockGestureManager : public GestureManager { |
| DISALLOW_COPY_AND_ASSIGN(MockGestureManager); |
| }; |
| +// GestureRecognizer for testing. |
| +class TestGestureRecognizer: public GestureRecognizer { |
| + public: |
| + // Reset all test state. |
| + void reset() { |
| + last_touch_event_ = 0; |
| + last_gesture_event_ = 0; |
| + last_view_ = NULL; |
| + previously_handled_flag_ = false; |
| + dispatched_synthetic_event_ = false; |
| + } |
| + |
| + virtual bool ProcessTouchEventForGesture(const TouchEvent& event, |
| + View* source, |
| + ui::TouchStatus status) OVERRIDE; |
| + TestGestureRecognizer(); |
| + |
| + bool previously_handled_flag_; |
| + int last_touch_event_; |
| + int last_gesture_event_; |
| + View *last_view_; |
| + bool dispatched_synthetic_event_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(TestGestureRecognizer); |
| +}; |
| + |
| // A view subclass that ignores all touch events for testing purposes. |
| class TestViewIgnoreTouch : public TestView { |
| public: |
| @@ -274,6 +318,17 @@ class TestViewIgnoreTouch : public TestView { |
| virtual ui::TouchStatus OnTouchEvent(const TouchEvent& event) OVERRIDE; |
| }; |
| +// A view subclass that consumes all Gesture events for testing purposes. |
| +class TestViewConsumeGesture : public TestView { |
| + public: |
| + TestViewConsumeGesture() : TestView() {} |
| + virtual ~TestViewConsumeGesture() {} |
| + |
| + private: |
| + virtual ui::TouchStatus OnTouchEvent(const TouchEvent& event) OVERRIDE; |
| + virtual ui::GestureStatus OnGestureEvent(const GestureEvent& event) OVERRIDE; |
| +}; |
| + |
| //////////////////////////////////////////////////////////////////////////////// |
| // OnBoundsChanged |
| //////////////////////////////////////////////////////////////////////////////// |
| @@ -538,6 +593,253 @@ TEST_F(ViewTest, TouchEvent) { |
| } |
| //////////////////////////////////////////////////////////////////////////////// |
| +// GestureEvent |
| +//////////////////////////////////////////////////////////////////////////////// |
| + |
| +bool TestGestureRecognizer::ProcessTouchEventForGesture( |
| + const TouchEvent& event, |
| + View* source, |
| + ui::TouchStatus status) { |
| + if (status != ui::TOUCH_STATUS_UNKNOWN) { |
| + dispatched_synthetic_event_ = false; |
| + return false; |
| + } |
| + last_touch_event_ = event.type(); |
| + last_view_ = source; |
| + previously_handled_flag_ = status != ui::TOUCH_STATUS_UNKNOWN; |
| + dispatched_synthetic_event_ = GestureRecognizer::ProcessTouchEventForGesture( |
| + event, source, status); |
| + return true; |
| +} |
| + |
| +TestGestureRecognizer::TestGestureRecognizer() { |
| +} |
| + |
| +ui::GestureStatus TestView::OnGestureEvent(const GestureEvent& event) { |
| + return ui::GESTURE_STATUS_UNKNOWN; |
| +} |
| + |
| +// GestureConsumer view should ignore TouchEvent for testing purposes. |
| +ui::TouchStatus TestViewConsumeGesture::OnTouchEvent( |
| + const TouchEvent& event) { |
| + return ui::TOUCH_STATUS_UNKNOWN; |
| +} |
| + |
| +ui::GestureStatus TestViewConsumeGesture::OnGestureEvent( |
| + const GestureEvent& event) { |
| + last_gesture_event_type_ = event.type(); |
| + location_.SetPoint(event.x(), event.y()); |
| + return ui::GESTURE_STATUS_CONSUMED; |
| +} |
| + |
| +#if defined(TOUCH_UI) |
| +TEST_F(ViewTest, GestureEvent) { |
| + TestGestureRecognizer gm; |
| + |
| + // Views hierarchy for non delivery of GestureEvent. |
| + TestView* v1 = new TestViewConsumeGesture(); |
| + v1->SetBounds(0, 0, 300, 300); |
| + |
| + TestView* v2 = new TestView(); |
| + v2->SetBounds(100, 100, 100, 100); |
| + |
| + TestView* v3 = new TestViewConsumeGesture(); |
| + v3->SetBounds(0, 0, 100, 100); |
| + |
| + // Views hierarchy for delivery of GestureEvent. |
| + TestView* v4 = new TestViewConsumeGesture(); |
| + v4->SetBounds(200, 200, 100, 100); |
| + |
| + scoped_ptr<Widget> widget(new Widget()); |
| + Widget::InitParams params(Widget::InitParams::TYPE_POPUP); |
| + params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| + params.bounds = gfx::Rect(50, 50, 650, 650); |
| + widget->Init(params); |
| + View* root = widget->GetRootView(); |
| + |
| + root->AddChildView(v1); |
| + static_cast<internal::RootView*>(root)->SetGestureManagerForTesting(&gm); |
| + v1->AddChildView(v2); |
| + v2->AddChildView(v3); |
| + v1->AddChildView(v4); |
| + |
| + // |v3| completely obscures |v2|, but all the touch events on |v3| should |
|
rjkroege
2011/11/09 02:43:30
This is testing gesture events? Can you updated th
Gajen
2011/11/10 15:52:55
Done.
|
| + // reach |v2| because |v3| doesn't process any touch events, hence |v3| |
| + // should also not recieve gesture events. |
| + |
| + // Both |v4| and |v1| ignore touch events, hence |v4| should recieve gesture |
| + // events. |
| + |
| + // Make sure if none of the views handle the touch event, the gesture manager |
| + // does. |
| + v1->Reset(); |
| + v2->Reset(); |
| + v3->Reset(); |
| + v4->Reset(); |
| + gm.reset(); |
| + |
| + // Just to pass Touch to Mouse conversion process through |
| + // EventFlagsFromNative(), EventLocationFromNative() in ui/base/x/events_x.cc. |
| + XEvent native_event; |
| + memset(&native_event, 0, sizeof(native_event)); |
|
rjkroege
2011/11/09 02:43:30
this should not be necessary. You can construct th
Gajen
2011/11/09 18:14:43
Since, TouchEvent generated this way would set to
Gajen
2011/11/10 15:52:55
Deprecated, as new CL http://codereview.chromium.o
|
| + |
| + TouchEvent unhandled(ui::ET_TOUCH_MOVED, |
| + 400, |
| + 400, |
| + 0, /* no flags */ |
| + 0, /* first finger touch */ |
| + 1.0, 0.0, 1.0, 0.0); |
| + |
| + unhandled.set_native_event(&native_event); |
| + root->OnTouchEvent(unhandled); |
| + |
| + EXPECT_EQ(v1->last_touch_event_type_, 0); |
| + EXPECT_EQ(v2->last_touch_event_type_, 0); |
| + EXPECT_EQ(v4->last_touch_event_type_, 0); |
| + EXPECT_EQ(v4->last_gesture_event_type_, 0); |
| + |
| + EXPECT_EQ(gm.previously_handled_flag_, false); |
| + EXPECT_EQ(gm.last_touch_event_, ui::ET_TOUCH_MOVED); |
| + EXPECT_EQ(gm.last_view_, root); |
| + EXPECT_EQ(gm.dispatched_synthetic_event_, true); |
| + |
| + // Test press, drag, release touch sequence. |
| + v1->Reset(); |
| + v2->Reset(); |
| + v3->Reset(); |
| + v4->Reset(); |
| + gm.reset(); |
| + |
| + TouchEvent pressed(ui::ET_TOUCH_PRESSED, |
| + 110, |
| + 120, |
| + 0, /* no flags */ |
| + 0, /* first finger touch */ |
| + 1.0, 0.0, 1.0, 0.0); |
| + v2->last_touch_event_was_handled_ = true; |
| + pressed.set_native_event(&native_event); |
| + root->OnTouchEvent(pressed); |
| + |
| + EXPECT_EQ(v2->last_touch_event_type_, ui::ET_TOUCH_PRESSED); |
| + EXPECT_EQ(v2->location_.x(), 10); |
| + EXPECT_EQ(v2->location_.y(), 20); |
| + // Make sure v1 did not receive the event |
| + EXPECT_EQ(v1->last_touch_event_type_, 0); |
| + |
| + // Since v2 handled the touch-event, the gesture manager should not handle it. |
| + EXPECT_EQ(gm.last_touch_event_, 0); |
| + EXPECT_EQ(NULL, gm.last_view_); |
| + EXPECT_EQ(gm.previously_handled_flag_, false); |
| + |
| + // Drag event out of bounds. Should still go to v2 |
| + v1->Reset(); |
| + v2->Reset(); |
| + TouchEvent dragged(ui::ET_TOUCH_MOVED, |
| + 50, |
| + 40, |
| + 0, /* no flags */ |
| + 0, /* first finger touch */ |
| + 1.0, 0.0, 1.0, 0.0); |
| + dragged.set_native_event(&native_event); |
| + root->OnTouchEvent(dragged); |
| + EXPECT_EQ(v2->last_touch_event_type_, ui::ET_TOUCH_MOVED); |
| + EXPECT_EQ(v2->location_.x(), -50); |
| + EXPECT_EQ(v2->location_.y(), -60); |
| + // Make sure v1 did not receive the event |
| + EXPECT_EQ(v1->last_touch_event_type_, 0); |
| + |
| + EXPECT_EQ(gm.last_touch_event_, 0); |
| + EXPECT_EQ(NULL, gm.last_view_); |
| + EXPECT_EQ(gm.previously_handled_flag_, false); |
| + |
| + // Released event out of bounds. Should still go to v2 |
| + v1->Reset(); |
| + v2->Reset(); |
| + TouchEvent released(ui::ET_TOUCH_RELEASED, 0, 0, 0, 0 /* first finger */, |
| + 1.0, 0.0, 1.0, 0.0); |
| + released.set_native_event(&native_event); |
| + v2->last_touch_event_was_handled_ = true; |
| + root->OnTouchEvent(released); |
| + EXPECT_EQ(v2->last_touch_event_type_, ui::ET_TOUCH_RELEASED); |
| + EXPECT_EQ(v2->location_.x(), -100); |
| + EXPECT_EQ(v2->location_.y(), -100); |
| + // Make sure v1 did not receive the event |
| + EXPECT_EQ(v1->last_touch_event_type_, 0); |
| + |
| + EXPECT_EQ(gm.last_touch_event_, 0); |
| + EXPECT_EQ(NULL, gm.last_view_); |
| + EXPECT_EQ(gm.previously_handled_flag_, false); |
| + |
| + // Gesture event handling test. |
| + // 1) Test gesture type ui::ET_GESTURE_TAP_DOWN. |
| + v1->Reset(); |
| + v4->Reset(); |
| + gm.reset(); |
| + |
| + TouchEvent second_pressed(ui::ET_TOUCH_PRESSED, |
| + 210, |
| + 220, |
| + 0, /* no flags */ |
| + 0, /* first finger touch */ |
| + 1.0, 0.0, 1.0, 0.0); |
| + second_pressed.set_native_event(&native_event); |
| + base::Time pressed_time = second_pressed.time_stamp(); |
| + root->OnTouchEvent(second_pressed); |
| + |
| + // Since v1 and V4 didn't handled touch event, the gesture manager should |
| + // handle it. |
| + EXPECT_EQ(gm.last_touch_event_, ui::ET_TOUCH_PRESSED); |
| + EXPECT_EQ(root, gm.last_view_); |
| + EXPECT_EQ(gm.previously_handled_flag_, false); |
| + |
| + // Check v4 should receive gesture event but not v1. |
| + EXPECT_EQ(v1->last_touch_event_type_, 0); |
| + EXPECT_EQ(v4->last_touch_event_type_, 0); |
| + EXPECT_EQ(v4->last_gesture_event_type_, ui::ET_GESTURE_TAP_DOWN); |
| + EXPECT_EQ(v4->location_.x(), 10); |
| + EXPECT_EQ(v4->location_.y(), 20); |
| + |
| + // Check mouse conversions shouldn't take place. |
| + EXPECT_EQ(gm.dispatched_synthetic_event_, false); |
| + |
| + // 2) Test gesture type ui::ET_GESTURE_TAP. |
| + v1->Reset(); |
| + v4->Reset(); |
| + gm.reset(); |
| + |
| + TouchEvent second_released(ui::ET_TOUCH_RELEASED, |
| + 210, |
| + 220, |
| + 0, /* no flags */ |
| + 0, /* first finger touch */ |
| + 1.0, 0.0, 1.0, 0.0); |
| + second_released.set_native_event(&native_event); |
| + |
| + // Set touch time with-in click window. |
| + second_released.set_time_stamp(base::Time::FromDoubleT( |
| + pressed_time.ToDoubleT() + 0.7)); |
| + root->OnTouchEvent(second_released); |
| + |
| + // Since v1 and V4 didn't handled touch event, the gesture manager should |
| + // handle it. |
| + EXPECT_EQ(gm.last_touch_event_, ui::ET_TOUCH_RELEASED); |
| + EXPECT_EQ(root, gm.last_view_); |
| + EXPECT_EQ(gm.previously_handled_flag_, false); |
| + |
| + // Check v4 should receive gesture event but not v1. |
| + EXPECT_EQ(v1->last_touch_event_type_, 0); |
| + EXPECT_EQ(v4->last_touch_event_type_, 0); |
| + EXPECT_EQ(v4->last_gesture_event_type_, ui::ET_GESTURE_TAP); |
| + EXPECT_EQ(v4->location_.x(), 10); |
| + EXPECT_EQ(v4->location_.y(), 20); |
| + |
| + // Check mouse conversions shouldn't take place. |
|
rjkroege
2011/11/09 02:43:30
mouse conversions are in-use in actual code. Pleas
Gajen
2011/11/10 15:52:55
Verified touch to mouse conversion and propagation
|
| + EXPECT_EQ(gm.dispatched_synthetic_event_, false); |
| + widget->CloseNow(); |
| +} |
| +#endif |
| + |
| +//////////////////////////////////////////////////////////////////////////////// |
| // Painting |
| //////////////////////////////////////////////////////////////////////////////// |