Chromium Code Reviews| 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 |