Index: content/browser/renderer_host/input/touch_emulator_unittest.cc |
diff --git a/content/browser/renderer_host/input/touch_emulator_unittest.cc b/content/browser/renderer_host/input/touch_emulator_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..08939f4991cbef8897ff24a7998da44ae497ea3a |
--- /dev/null |
+++ b/content/browser/renderer_host/input/touch_emulator_unittest.cc |
@@ -0,0 +1,280 @@ |
+// 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 <vector> |
+ |
+#include "base/basictypes.h" |
+#include "base/memory/scoped_ptr.h" |
+#include "base/message_loop/message_loop.h" |
+#include "base/time/time.h" |
+#include "content/browser/renderer_host/input/touch_emulator.h" |
+#include "content/browser/renderer_host/input/touch_emulator_client.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+#include "ui/events/gesture_detection/gesture_config_helper.h" |
+ |
+using blink::WebGestureEvent; |
+using blink::WebInputEvent; |
+using blink::WebKeyboardEvent; |
+using blink::WebMouseEvent; |
+using blink::WebTouchEvent; |
+using blink::WebTouchPoint; |
+ |
+namespace content { |
+ |
+class TouchEmulatorTest : public testing::Test, |
+ public TouchEmulatorClient { |
+ public: |
+ TouchEmulatorTest() |
+ : shift_pressed_(false), |
+ mouse_pressed_(false), |
+ last_mouse_x_(-1), |
+ last_mouse_y_(-1), |
+ scrolling_(false), |
+ pinching_(false) {} |
+ |
+ virtual ~TouchEmulatorTest() {} |
+ |
+ // testing::Test |
+ virtual void SetUp() OVERRIDE { |
+ ui::GestureProvider::Config config; |
+ config.gesture_detector_config = ui::DefaultGestureDetectorConfig(); |
+ config.scale_gesture_detector_config = |
+ ui::DefaultScaleGestureDetectorConfig(); |
+ config.snap_scroll_controller_config.screen_width_pixels = 800; |
+ config.snap_scroll_controller_config.screen_height_pixels = 600; |
+ config.snap_scroll_controller_config.device_scale_factor = 1.f; |
+ emulator_.reset(new TouchEmulator(this, config)); |
+ } |
+ |
+ virtual void TearDown() OVERRIDE { |
+ // Process all pending tasks to avoid leaks. |
+ std::string expected = pinching_ ? "PINCH_END SCROLL_END" : |
+ (scrolling_ ? "SCROLL_END" : ""); |
+ emulator_.reset(); |
+ Expect(expected); |
+ } |
+ |
+ virtual void ForwardGestureEvent( |
+ const blink::WebGestureEvent& event) OVERRIDE { |
+ if (event.type == WebInputEvent::GestureScrollBegin) |
+ scrolling_ = true; |
+ if (event.type == WebInputEvent::GestureScrollEnd) |
+ scrolling_ = false; |
+ if (event.type == WebInputEvent::GestureFlingStart) |
+ scrolling_ = false; |
+ if (event.type == WebInputEvent::GesturePinchBegin) |
+ pinching_ = true; |
+ if (event.type == WebInputEvent::GesturePinchEnd) |
+ pinching_ = false; |
+ forwarded_events_.push_back(event.type); |
+ } |
+ |
+ virtual void ForwardTouchEventWithLatencyInfo( |
+ const blink::WebTouchEvent& event, |
+ const ui::LatencyInfo& latency_info) OVERRIDE { |
+ forwarded_events_.push_back(event.type); |
+ emulator()->HandleTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS); |
+ } |
+ |
+ virtual void SetCursor(const WebCursor& cursor) OVERRIDE {} |
+ |
+ protected: |
+ TouchEmulator* emulator() const { |
+ return emulator_.get(); |
+ } |
+ |
+ void DestroyEmulator() { |
jdduke (slow)
2014/04/07 18:07:26
Nit: This isn't used.
dgozman
2014/04/08 16:56:49
Done.
|
+ emulator_.reset(); |
+ } |
+ |
+ int modifiers() const { |
+ return shift_pressed_ ? WebInputEvent::ShiftKey : 0; |
+ } |
+ |
+ std::string EventTypeToString(WebInputEvent::Type type) { |
+ switch (type) { |
+ case WebInputEvent::TouchStart: |
jdduke (slow)
2014/04/07 18:07:26
You can use |WebInputEventTraits::GetName(type)| i
dgozman
2014/04/08 16:56:49
Nice! Done.
|
+ return "TOUCH_START"; |
+ case WebInputEvent::TouchMove: |
+ return "TOUCH_MOVE"; |
+ case WebInputEvent::TouchEnd: |
+ return "TOUCH_END"; |
+ case WebInputEvent::TouchCancel: |
+ return "TOUCH_CANCEL"; |
+ case WebInputEvent::GestureScrollBegin: |
+ return "SCROLL_BEGIN"; |
+ case WebInputEvent::GestureScrollUpdate: |
+ return "SCROLL_UPDATE"; |
+ case WebInputEvent::GestureScrollEnd: |
+ return "SCROLL_END"; |
+ case WebInputEvent::GestureFlingStart: |
+ return "FLING_START"; |
+ case WebInputEvent::GestureFlingCancel: |
+ return "FLING_CANCEL"; |
+ case WebInputEvent::GesturePinchBegin: |
+ return "PINCH_BEGIN"; |
+ case WebInputEvent::GesturePinchUpdate: |
+ return "PINCH_UPDATE"; |
+ case WebInputEvent::GesturePinchEnd: |
+ return "PINCH_END"; |
+ case WebInputEvent::GestureShowPress: |
+ return "SHOW_PRESS"; |
+ case WebInputEvent::GestureTap: |
+ return "TAP"; |
+ case WebInputEvent::GestureTapUnconfirmed: |
+ return "TAP_UNCONFIRMED"; |
+ case WebInputEvent::GestureTapDown: |
+ return "TAP_DOWN"; |
+ case WebInputEvent::GestureTapCancel: |
+ return "TAP_CANCEL"; |
+ default: |
+ return "UNKNOWN"; |
+ } |
+ } |
+ |
+ void Expect(std::string events) { |
+ std::string forwarded; |
+ for (size_t i = 0; i < forwarded_events_.size(); ++i) { |
+ if (i != 0) |
+ forwarded += " "; |
+ forwarded += EventTypeToString(forwarded_events_[i]); |
+ } |
+ forwarded_events_.clear(); |
+ EXPECT_EQ(events, forwarded); |
+ } |
+ |
+ void SendKeyboardEvent() { |
+ WebKeyboardEvent event; |
+ event.timeStampSeconds = base::Time::Now().ToDoubleT(); |
+ event.type = WebInputEvent::KeyDown; |
+ event.modifiers = modifiers(); |
+ emulator()->HandleKeyboardEvent(event); |
+ event.type = WebInputEvent::KeyUp; |
+ event.modifiers = modifiers(); |
+ emulator()->HandleKeyboardEvent(event); |
+ } |
+ |
+ void PressShift() { |
+ DCHECK(!shift_pressed_); |
+ shift_pressed_ = true; |
+ SendKeyboardEvent(); |
+ } |
+ |
+ void ReleaseShift() { |
+ DCHECK(shift_pressed_); |
+ shift_pressed_ = false; |
+ SendKeyboardEvent(); |
+ } |
+ |
+ void SendMouseEvent(WebInputEvent::Type type, int x, int y) { |
+ WebMouseEvent event; |
+ event.timeStampSeconds = base::Time::Now().ToDoubleT(); |
+ event.type = type; |
+ event.button = mouse_pressed_ ? WebMouseEvent::ButtonLeft : |
+ WebMouseEvent::ButtonNone; |
+ event.modifiers = modifiers(); |
+ last_mouse_x_ = x; |
+ last_mouse_y_ = y; |
+ event.x = event.windowX = event.globalX = x; |
+ event.y = event.windowY = event.globalY = y; |
+ emulator()->HandleMouseEvent(event); |
+ } |
+ |
+ void MouseDown(int x, int y) { |
+ DCHECK(!mouse_pressed_); |
+ if (x != last_mouse_x_ || y != last_mouse_y_) |
+ SendMouseEvent(WebInputEvent::MouseMove, x, y); |
+ mouse_pressed_ = true; |
+ SendMouseEvent(WebInputEvent::MouseDown, x, y); |
+ } |
+ |
+ void MouseDrag(int x, int y) { |
+ DCHECK(mouse_pressed_); |
+ SendMouseEvent(WebInputEvent::MouseMove, x, y); |
+ } |
+ |
+ void MouseMove(int x, int y) { |
+ DCHECK(!mouse_pressed_); |
+ SendMouseEvent(WebInputEvent::MouseMove, x, y); |
+ } |
+ |
+ void MouseUp(int x, int y) { |
+ DCHECK(mouse_pressed_); |
+ if (x != last_mouse_x_ || y != last_mouse_y_) |
+ SendMouseEvent(WebInputEvent::MouseMove, x, y); |
+ SendMouseEvent(WebInputEvent::MouseUp, x, y); |
+ mouse_pressed_ = false; |
+ } |
+ |
+ private: |
+ scoped_ptr<TouchEmulator> emulator_; |
+ std::vector<WebInputEvent::Type> forwarded_events_; |
+ bool shift_pressed_; |
+ bool mouse_pressed_; |
+ int last_mouse_x_; |
+ int last_mouse_y_; |
+ bool scrolling_; |
+ bool pinching_; |
+ base::MessageLoopForUI message_loop_; |
+}; |
+ |
tdresser
2014/04/07 18:44:04
I'd be more comfortable if these tests looked at g
dgozman
2014/04/08 16:56:49
I'm not sure how to test this. Looks like properly
tdresser
2014/04/08 18:39:15
ForwardGestureEvent could record the most recent W
jdduke (slow)
2014/04/08 19:14:11
I think event orderings are more important than ch
tdresser
2014/04/08 19:21:23
Good call - I'd be perfectly happy with a single t
|
+ |
+TEST_F(TouchEmulatorTest, NoTouches) { |
+ MouseMove(100, 200); |
+ MouseMove(300, 300); |
+ Expect(""); |
jdduke (slow)
2014/04/07 18:07:26
Will |EXPECT_EQ(ExpectedEvents(), "")| not work? I
dgozman
2014/04/08 16:56:49
You are right, fixed.
|
+} |
+ |
+TEST_F(TouchEmulatorTest, Touch) { |
+ MouseMove(100, 200); |
+ Expect(""); |
+ MouseDown(100, 200); |
+ MouseUp(200, 200); |
+ Expect("TOUCH_START TAP_DOWN TOUCH_MOVE TAP_CANCEL" |
+ " SCROLL_BEGIN SCROLL_UPDATE TOUCH_END FLING_START"); |
+} |
+ |
+TEST_F(TouchEmulatorTest, MultipleTouches) { |
+ MouseMove(100, 200); |
+ Expect(""); |
+ MouseDown(100, 200); |
+ MouseUp(200, 200); |
+ Expect("TOUCH_START TAP_DOWN TOUCH_MOVE TAP_CANCEL" |
+ " SCROLL_BEGIN SCROLL_UPDATE TOUCH_END FLING_START"); |
+ MouseMove(300, 200); |
+ MouseMove(200, 200); |
+ Expect(""); |
+ MouseDown(300, 200); |
+ Expect("TOUCH_START FLING_CANCEL TAP_DOWN"); |
+ MouseDrag(300, 300); |
+ Expect("TOUCH_MOVE TAP_CANCEL SCROLL_BEGIN SCROLL_UPDATE"); |
+ MouseDrag(300, 400); |
+ Expect("TOUCH_MOVE SCROLL_UPDATE"); |
+ MouseUp(300, 500); |
+ Expect("TOUCH_MOVE SCROLL_UPDATE TOUCH_END SCROLL_END"); |
+} |
+ |
+TEST_F(TouchEmulatorTest, Pinch) { |
+ MouseDown(100, 200); |
+ MouseDrag(200, 200); |
+ PressShift(); |
+ MouseDrag(300, 200); |
+ Expect("TOUCH_START TAP_DOWN TOUCH_MOVE TAP_CANCEL" |
+ " SCROLL_BEGIN SCROLL_UPDATE TOUCH_MOVE PINCH_BEGIN"); |
+ ReleaseShift(); |
+ MouseDrag(400, 200); |
+ MouseUp(400, 200); |
+ Expect("TOUCH_MOVE PINCH_END SCROLL_UPDATE TOUCH_END SCROLL_END"); |
+} |
+ |
+TEST_F(TouchEmulatorTest, DestroyWhilePinch) { |
+ MouseDown(100, 200); |
+ MouseDrag(200, 200); |
+ PressShift(); |
+ MouseDrag(300, 200); |
+ Expect("TOUCH_START TAP_DOWN TOUCH_MOVE TAP_CANCEL" |
+ " SCROLL_BEGIN SCROLL_UPDATE TOUCH_MOVE PINCH_BEGIN"); |
jdduke (slow)
2014/04/07 18:07:26
Hmm, did you want to add some more code here?
dgozman
2014/04/08 16:56:49
At first, I planned to call DestroyEmulator here.
|
+} |
+ |
+} // namespace content |