Index: content/browser/renderer_host/input/fling/flinger_unittest.cc |
diff --git a/content/browser/renderer_host/input/fling/flinger_unittest.cc b/content/browser/renderer_host/input/fling/flinger_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..4d8dbb9085d45fef07924a8829a0e4468cd083b0 |
--- /dev/null |
+++ b/content/browser/renderer_host/input/fling/flinger_unittest.cc |
@@ -0,0 +1,167 @@ |
+// Copyright 2013 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 "content/browser/renderer_host/input/fling/flinger.h" |
+ |
+#include "base/basictypes.h" |
+#include "base/logging.h" |
+#include "base/memory/scoped_ptr.h" |
+#include "base/message_loop/message_loop.h" |
+#include "content/browser/renderer_host/input/mock_web_input_event_builders.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+using base::TimeDelta; |
+using WebKit::WebGestureEvent; |
+using WebKit::WebInputEvent; |
+ |
+namespace content { |
+ |
+class FlingerTest : public testing::Test, |
+ public FlingHelper { |
+ public: |
+ FlingerTest() : sent_gesture_event_count_(0) {} |
+ |
+ virtual ~FlingerTest() {} |
+ |
+ // testing::Test |
+ virtual void SetUp() OVERRIDE { |
+ flinger_.reset(new Flinger(this)); |
+ } |
+ |
+ virtual void TearDown() OVERRIDE { |
+ // Process all pending tasks to avoid leaks. |
+ RunUntilIdle(); |
+ flinger_.reset(); |
+ } |
+ |
+ // FlingHelper |
+ void SendEventForFling(const WebKit::WebInputEvent& event) OVERRIDE { |
+ ++sent_gesture_event_count_; |
+ } |
+ |
+ void FlingFinished(WebKit::WebGestureEvent::SourceDevice source) OVERRIDE { |
+ } |
+ |
+ protected: |
+ |
+ // Returns the result of |GestureEventFilter::ShouldForward()|. |
+ bool SimulateGestureEvent(const WebGestureEvent& gesture) { |
+ GestureEventWithLatencyInfo gesture_with_latency(gesture, |
+ ui::LatencyInfo()); |
+ return flinger_->HandleGestureEvent(gesture_with_latency); |
+ } |
+ |
+ void SimulateGestureEvent(WebInputEvent::Type type, |
+ WebGestureEvent::SourceDevice sourceDevice) { |
+ SimulateGestureEvent(MockWebGestureEventBuilder::Build(type, sourceDevice)); |
+ } |
+ |
+ void SimulateGestureScrollUpdateEvent(float dX, float dY, int modifiers) { |
+ SimulateGestureEvent( |
+ MockWebGestureEventBuilder::BuildScrollUpdate(dX, dY, modifiers)); |
+ } |
+ |
+ void SimulateGesturePinchUpdateEvent(float scale, |
+ float anchorX, |
+ float anchorY, |
+ int modifiers) { |
+ SimulateGestureEvent( |
+ MockWebGestureEventBuilder::BuildPinchUpdate(scale, |
+ anchorX, |
+ anchorY, |
+ modifiers)); |
+ } |
+ |
+ void SimulateGestureFlingStartEvent( |
+ float velocityX, |
+ float velocityY, |
+ WebGestureEvent::SourceDevice sourceDevice) { |
+ SimulateGestureEvent( |
+ MockWebGestureEventBuilder::BuildFling(velocityX, |
+ velocityY, |
+ sourceDevice)); |
+ } |
+ |
+ void SimulateFlingCurveTimerFired() { |
+ flinger_->CurveTimerFired(); |
+ } |
+ |
+ void SendInputEventACK(WebInputEvent::Type type, |
+ InputEventAckState ack) { |
+ --sent_gesture_event_count_; |
+ flinger_->ProcessEventAck(type, ack, ui::LatencyInfo()); |
+ } |
+ |
+ void RunUntilIdle() { |
+ base::MessageLoop::current()->RunUntilIdle(); |
+ } |
+ |
+ size_t GetAndResetSentGestureEventCount() { |
+ size_t count = sent_gesture_event_count_; |
+ sent_gesture_event_count_ = 0; |
+ return count; |
+ } |
+ |
+ bool FlingInProgress() { |
+ return flinger_->fling_in_progress_; |
+ } |
+ |
+ private: |
+ scoped_ptr<Flinger> flinger_; |
+ size_t sent_gesture_event_count_; |
+ base::MessageLoopForUI message_loop_; |
+}; |
+ |
+#if GTEST_HAS_PARAM_TEST |
+// This is for tests that are to be run for all source devices. |
+class FlingerWithSourceTest |
+ : public FlingerTest, |
+ public testing::WithParamInterface<WebGestureEvent::SourceDevice> { |
+}; |
+#endif // GTEST_HAS_PARAM_TEST |
+ |
+#if GTEST_HAS_PARAM_TEST |
+TEST_P(FlingerWithSourceTest, GestureFlingCancelsFiltered) { |
+ WebGestureEvent::SourceDevice source_device = GetParam(); |
+ |
+ // GFC without previous GFS is dropped. |
+ SimulateGestureEvent(WebInputEvent::GestureFlingCancel, source_device); |
+ EXPECT_EQ(0U, GetAndResetSentGestureEventCount()); |
+ |
+ // GFC after GFS stops fling. |
+ SimulateGestureFlingStartEvent(0, -10, source_device); |
+ EXPECT_TRUE(FlingInProgress()); |
+ SimulateGestureEvent(WebInputEvent::GestureFlingCancel, source_device); |
+ EXPECT_FALSE(FlingInProgress()); |
+ EXPECT_EQ(0U, GetAndResetSentGestureEventCount()); |
+ |
+ // Advance state realistically. |
+ SimulateGestureFlingStartEvent(0, -10, source_device); |
+ EXPECT_TRUE(FlingInProgress()); |
+ RunUntilIdle(); |
+ SimulateFlingCurveTimerFired(); |
+ SimulateGestureEvent(WebInputEvent::GestureFlingCancel, source_device); |
+ EXPECT_FALSE(FlingInProgress()); |
+ EXPECT_NE(0U, GetAndResetSentGestureEventCount()); |
+} |
+ |
+INSTANTIATE_TEST_CASE_P(AllSources, |
+ FlingerWithSourceTest, |
+ testing::Values(WebGestureEvent::Touchscreen, |
+ WebGestureEvent::Touchpad)); |
+#endif // GTEST_HAS_PARAM_TEST |
+ |
+TEST_F(FlingerTest, DropZeroVelocityFlings) { |
+ WebGestureEvent gesture_event; |
+ gesture_event.type = WebInputEvent::GestureFlingStart; |
+ gesture_event.sourceDevice = WebGestureEvent::Touchpad; |
+ gesture_event.data.flingStart.velocityX = 0.f; |
+ gesture_event.data.flingStart.velocityY = 0.f; |
+ ASSERT_EQ(0U, GetAndResetSentGestureEventCount()); |
+ EXPECT_TRUE(SimulateGestureEvent(gesture_event)); |
+ EXPECT_EQ(0U, GetAndResetSentGestureEventCount()); |
+ EXPECT_FALSE(FlingInProgress()); |
+} |
+ |
+} // namespace content |