Chromium Code Reviews| Index: ui/touch_selection/longpress_drag_selector_unittest.cc |
| diff --git a/ui/touch_selection/longpress_drag_selector_unittest.cc b/ui/touch_selection/longpress_drag_selector_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..1721d690a2b69dc0689490963f7de36037b1504d |
| --- /dev/null |
| +++ b/ui/touch_selection/longpress_drag_selector_unittest.cc |
| @@ -0,0 +1,332 @@ |
| +// 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 "ui/touch_selection/longpress_drag_selector.h" |
| + |
| +#include "testing/gtest/include/gtest/gtest.h" |
| +#include "ui/events/test/motion_event_test_utils.h" |
| + |
| +using ui::test::MockMotionEvent; |
| + |
| +namespace ui { |
| +namespace { |
| + |
| +const double kSlop = 10.; |
| + |
| +} // namespace |
| + |
| +class LongPressDragSelectorTest : public testing::Test, |
| + public LongPressDragSelectorClient { |
| + public: |
| + LongPressDragSelectorTest() |
| + : dragging_(false), active_state_changed_(false) {} |
| + |
| + ~LongPressDragSelectorTest() override {} |
| + |
| + // LongPressDragSelectorClient implementation. |
|
mfomitchev
2015/05/13 20:52:25
Can we put the LongPressDragSelectorClient methods
jdduke (slow)
2015/05/14 18:29:26
Done.
|
| + void OnDragBegin(const TouchSelectionDraggable& handler, |
| + const gfx::PointF& drag_position) override { |
| + dragging_ = true; |
| + drag_position_ = drag_position; |
| + } |
| + |
| + void OnDragUpdate(const TouchSelectionDraggable& handler, |
| + const gfx::PointF& drag_position) override { |
| + drag_position_ = drag_position; |
| + } |
| + |
| + void OnDragEnd(const TouchSelectionDraggable& handler) override { |
| + dragging_ = false; |
| + } |
| + |
| + bool IsWithinTapSlop(const gfx::Vector2dF& delta) const override { |
| + return delta.LengthSquared() < (kSlop * kSlop); |
| + } |
| + |
| + void OnLongPressDragActiveStateChanged() override { |
| + active_state_changed_ = true; |
| + } |
| + |
| + gfx::PointF GetSelectionStart() const override { return selection_start_; } |
| + |
| + gfx::PointF GetSelectionEnd() const override { return selection_end_; } |
| + |
| + void SetSelection(const gfx::PointF& start, const gfx::PointF& end) { |
| + selection_start_ = start; |
| + selection_end_ = end; |
| + } |
| + |
| + bool GetAndResetActiveStateChanged() { |
| + bool active_state_changed = active_state_changed_; |
| + active_state_changed_ = false; |
| + return active_state_changed; |
| + } |
| + |
| + bool IsDragging() const { return dragging_; } |
| + const gfx::PointF& DragPosition() const { return drag_position_; } |
| + |
| + private: |
| + bool dragging_; |
| + bool active_state_changed_; |
| + gfx::PointF drag_position_; |
| + |
| + gfx::PointF selection_start_; |
| + gfx::PointF selection_end_; |
| +}; |
| + |
| +TEST_F(LongPressDragSelectorTest, BasicDrag) { |
| + LongPressDragSelector selector(this); |
| + MockMotionEvent event; |
| + |
| + // Start a touch sequence. |
| + EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0))); |
| + EXPECT_FALSE(GetAndResetActiveStateChanged()); |
| + |
| + // Activate a longpress-triggered selection. |
| + gfx::PointF selection_start(0, 10); |
| + gfx::PointF selection_end(10, 10); |
| + selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF()); |
| + EXPECT_TRUE(GetAndResetActiveStateChanged()); |
| + |
| + // Motion should not be consumed until a selection is detected. |
| + EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0))); |
| + SetSelection(selection_start, selection_end); |
| + selector.OnSelectionActivated(); |
| + EXPECT_FALSE(IsDragging()); |
| + |
| + // Initiate drag motion. The motion is downward, so the end selection point |
|
mfomitchev
2015/05/13 20:52:25
The comment about downward motion would probably f
jdduke (slow)
2015/05/14 18:29:26
Done.
|
| + // should be moved. Note that the first move event after activation is used to |
| + // initialize the drag start anchor. |
| + EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0))); |
| + EXPECT_FALSE(IsDragging()); |
| + |
| + // The first slop exceeding motion will start the drag. |
| + EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop))); |
| + EXPECT_TRUE(IsDragging()); |
| + EXPECT_EQ(selection_end, DragPosition()); |
| + |
| + // Subsequent motion will extend the selection. |
| + EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2))); |
| + EXPECT_TRUE(IsDragging()); |
| + EXPECT_EQ(selection_end + gfx::Vector2dF(0, kSlop), DragPosition()); |
| + EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 3))); |
| + EXPECT_TRUE(IsDragging()); |
| + EXPECT_EQ(selection_end + gfx::Vector2dF(0, kSlop * 2), DragPosition()); |
| + |
| + // Release the touch sequence, ending the drag. The selector will never |
| + // consume the start/end events, only move events after a longpress. |
| + EXPECT_FALSE(selector.WillHandleTouchEvent(event.ReleasePoint())); |
| + EXPECT_FALSE(IsDragging()); |
| + EXPECT_TRUE(GetAndResetActiveStateChanged()); |
| +} |
| + |
| +TEST_F(LongPressDragSelectorTest, BasicReverseDrag) { |
| + LongPressDragSelector selector(this); |
| + MockMotionEvent event; |
| + |
| + // Start a touch sequence. |
| + EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0))); |
| + EXPECT_FALSE(GetAndResetActiveStateChanged()); |
| + |
| + // Activate a longpress-triggered selection. |
| + gfx::PointF selection_start(0, 10); |
| + gfx::PointF selection_end(10, 10); |
| + selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF()); |
| + EXPECT_TRUE(GetAndResetActiveStateChanged()); |
| + SetSelection(selection_start, selection_end); |
| + selector.OnSelectionActivated(); |
| + EXPECT_FALSE(IsDragging()); |
| + |
| + // Initiate drag motion. The initial motion is leftward, toward the selection |
| + // start, so that should be the drag point. |
| + EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, kSlop, 0))); |
|
mfomitchev
2015/05/13 20:52:25
I don't get it - kSlop is greater than 0, so why i
jdduke (slow)
2015/05/14 18:29:26
Yeah, the comment is in a bad position, I'll chang
|
| + EXPECT_FALSE(IsDragging()); |
| + |
| + EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0))); |
| + EXPECT_TRUE(IsDragging()); |
| + EXPECT_EQ(selection_start, DragPosition()); |
| + |
| + EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, -kSlop))); |
| + EXPECT_TRUE(IsDragging()); |
| + EXPECT_EQ(selection_start + gfx::Vector2dF(0, -kSlop), DragPosition()); |
| + |
| + // Release the touch sequence, ending the drag. |
| + EXPECT_FALSE(selector.WillHandleTouchEvent(event.ReleasePoint())); |
| + EXPECT_FALSE(IsDragging()); |
| + EXPECT_TRUE(GetAndResetActiveStateChanged()); |
| +} |
| + |
| +TEST_F(LongPressDragSelectorTest, NoActiveTouch) { |
| + LongPressDragSelector selector(this); |
| + MockMotionEvent event; |
| + |
| + // Activate a longpress-triggered selection. |
| + gfx::PointF selection_start(0, 10); |
| + gfx::PointF selection_end(10, 10); |
| + selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF()); |
| + SetSelection(selection_start, selection_end); |
| + selector.OnSelectionActivated(); |
| + EXPECT_FALSE(GetAndResetActiveStateChanged()); |
| + EXPECT_FALSE(IsDragging()); |
| + |
| + // Start a new touch sequence; it shouldn't initiate selection drag as there |
| + // was no active touch sequence when the longpress selection started. |
| + EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0))); |
| + EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0))); |
| + EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop))); |
| + EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2))); |
| + EXPECT_FALSE(IsDragging()); |
| + EXPECT_EQ(gfx::PointF(), DragPosition()); |
| +} |
| + |
| +TEST_F(LongPressDragSelectorTest, NoLongPress) { |
| + LongPressDragSelector selector(this); |
| + MockMotionEvent event; |
| + |
| + // Start a touch sequence. |
| + EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0))); |
| + EXPECT_FALSE(GetAndResetActiveStateChanged()); |
| + |
| + // Activate a selection without a preceding longpress. |
| + gfx::PointF selection_start(0, 10); |
| + gfx::PointF selection_end(10, 10); |
| + SetSelection(selection_start, selection_end); |
| + selector.OnSelectionActivated(); |
| + EXPECT_FALSE(GetAndResetActiveStateChanged()); |
| + EXPECT_FALSE(IsDragging()); |
| + |
| + // Touch movement should not initiate selection drag. |
| + EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0))); |
| + EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop))); |
| + EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2))); |
| + EXPECT_FALSE(IsDragging()); |
| + EXPECT_EQ(gfx::PointF(), DragPosition()); |
| +} |
| + |
| +TEST_F(LongPressDragSelectorTest, NoValidLongPress) { |
| + LongPressDragSelector selector(this); |
| + MockMotionEvent event; |
| + |
| + // Start a touch sequence. |
| + EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0))); |
| + EXPECT_FALSE(GetAndResetActiveStateChanged()); |
| + |
| + gfx::PointF selection_start(0, 10); |
| + gfx::PointF selection_end(10, 10); |
| + SetSelection(selection_start, selection_end); |
| + |
| + // Activate a longpress-triggered selection, but at a time different than the |
|
mfomitchev
2015/05/13 20:52:25
different -> before ?
jdduke (slow)
2015/05/14 18:29:26
Done.
|
| + // current touch down event. |
| + selector.OnLongPressEvent( |
| + event.GetEventTime() - base::TimeDelta::FromSeconds(1), gfx::PointF()); |
| + selector.OnSelectionActivated(); |
| + EXPECT_FALSE(GetAndResetActiveStateChanged()); |
| + EXPECT_FALSE(IsDragging()); |
| + |
| + // Activate a longpress-triggered selection, but at a place different than the |
| + // current touch down event. |
| + selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF(kSlop * 2, 0)); |
|
mfomitchev
2015/05/13 20:52:25
Can we do kSlop here instead of kSlop * 2?
jdduke (slow)
2015/05/14 18:29:26
Done.
|
| + selector.OnSelectionActivated(); |
| + EXPECT_FALSE(GetAndResetActiveStateChanged()); |
| + EXPECT_FALSE(IsDragging()); |
| + |
| + // Touch movement should not initiate selection drag. |
| + EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0))); |
| + EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop))); |
| + EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2))); |
| + EXPECT_FALSE(IsDragging()); |
| + EXPECT_EQ(gfx::PointF(), DragPosition()); |
| +} |
| + |
| +TEST_F(LongPressDragSelectorTest, NoSelection) { |
| + LongPressDragSelector selector(this); |
| + MockMotionEvent event; |
| + |
| + // Start a touch sequence. |
| + EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0))); |
| + EXPECT_FALSE(GetAndResetActiveStateChanged()); |
| + |
| + // Trigger a longpress. This will notify the client that detection is active, |
| + // but until there's a longpress no drag selection should occur. |
| + selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF()); |
| + EXPECT_TRUE(GetAndResetActiveStateChanged()); |
| + EXPECT_FALSE(IsDragging()); |
| + |
| + // Touch movement should not initiate selection drag, as there is no active |
| + // selection. |
| + EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0))); |
| + EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop))); |
| + EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2))); |
| + EXPECT_FALSE(IsDragging()); |
| + EXPECT_EQ(gfx::PointF(), DragPosition()); |
| + |
| + EXPECT_FALSE(selector.WillHandleTouchEvent(event.ReleasePoint())); |
| + EXPECT_TRUE(GetAndResetActiveStateChanged()); |
| +} |
| + |
| +TEST_F(LongPressDragSelectorTest, NoDragMotion) { |
| + LongPressDragSelector selector(this); |
| + MockMotionEvent event; |
| + |
| + // Start a touch sequence. |
| + EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0))); |
| + EXPECT_FALSE(GetAndResetActiveStateChanged()); |
| + |
| + // Activate a longpress-triggered selection. |
| + selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF()); |
| + EXPECT_TRUE(GetAndResetActiveStateChanged()); |
| + gfx::PointF selection_start(0, 10); |
| + gfx::PointF selection_end(10, 10); |
| + SetSelection(selection_start, selection_end); |
| + selector.OnSelectionActivated(); |
| + EXPECT_FALSE(IsDragging()); |
| + |
| + // Touch movement within the slop region should not initiate selection drag. |
| + EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0))); |
| + EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop / 2))); |
| + EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, -kSlop / 2))); |
| + EXPECT_FALSE(IsDragging()); |
| + EXPECT_EQ(gfx::PointF(), DragPosition()); |
| + |
| + EXPECT_FALSE(selector.WillHandleTouchEvent(event.ReleasePoint())); |
| + EXPECT_TRUE(GetAndResetActiveStateChanged()); |
| +} |
| + |
| +TEST_F(LongPressDragSelectorTest, SelectionDeactivated) { |
| + LongPressDragSelector selector(this); |
| + MockMotionEvent event; |
| + |
| + // Start a touch sequence. |
| + EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0))); |
| + EXPECT_FALSE(GetAndResetActiveStateChanged()); |
| + |
| + // Activate a longpress-triggered selection. |
| + selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF()); |
| + EXPECT_TRUE(GetAndResetActiveStateChanged()); |
| + gfx::PointF selection_start(0, 10); |
| + gfx::PointF selection_end(10, 10); |
| + SetSelection(selection_start, selection_end); |
| + selector.OnSelectionActivated(); |
| + EXPECT_FALSE(IsDragging()); |
| + |
| + // Start a drag selection. |
| + EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0))); |
| + EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop))); |
| + EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2))); |
| + EXPECT_TRUE(IsDragging()); |
| + |
| + // Clearing the selection should force an end to the drag. |
| + selector.OnSelectionDeactivated(); |
| + EXPECT_TRUE(GetAndResetActiveStateChanged()); |
| + EXPECT_FALSE(IsDragging()); |
| + |
| + // Subsequent motion should not be consumed. |
| + EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0))); |
| + EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop))); |
| + EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2))); |
| + EXPECT_FALSE(IsDragging()); |
| + EXPECT_FALSE(selector.WillHandleTouchEvent(event.ReleasePoint())); |
| +} |
| + |
| +} // namespace ui |