diff options
Diffstat (limited to 'layout/base/gtest/TestAccessibleCaretEventHub.cpp')
-rw-r--r-- | layout/base/gtest/TestAccessibleCaretEventHub.cpp | 827 |
1 files changed, 827 insertions, 0 deletions
diff --git a/layout/base/gtest/TestAccessibleCaretEventHub.cpp b/layout/base/gtest/TestAccessibleCaretEventHub.cpp new file mode 100644 index 000000000..5216a52dc --- /dev/null +++ b/layout/base/gtest/TestAccessibleCaretEventHub.cpp @@ -0,0 +1,827 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "gtest/gtest.h" +#include "gmock/gmock.h" + +#include <iostream> +#include <string> + +#include "AccessibleCaretEventHub.h" +#include "AccessibleCaretManager.h" +#include "gfxPrefs.h" +#include "mozilla/BasicEvents.h" +#include "mozilla/MouseEvents.h" +#include "mozilla/TouchEvents.h" + +using ::testing::AtLeast; +using ::testing::DefaultValue; +using ::testing::Eq; +using ::testing::InSequence; +using ::testing::MockFunction; +using ::testing::Return; +using ::testing::_; + +// ----------------------------------------------------------------------------- +// This file test the state transitions of AccessibleCaretEventHub under +// various combination of events and callbacks. + +namespace mozilla +{ + +class MockAccessibleCaretManager : public AccessibleCaretManager +{ +public: + MockAccessibleCaretManager() + : AccessibleCaretManager(nullptr) + { + } + + MOCK_METHOD2(PressCaret, + nsresult(const nsPoint& aPoint, EventClassID aEventClass)); + MOCK_METHOD1(DragCaret, nsresult(const nsPoint& aPoint)); + MOCK_METHOD0(ReleaseCaret, nsresult()); + MOCK_METHOD1(TapCaret, nsresult(const nsPoint& aPoint)); + MOCK_METHOD1(SelectWordOrShortcut, nsresult(const nsPoint& aPoint)); + MOCK_METHOD0(OnScrollStart, void()); + MOCK_METHOD0(OnScrollEnd, void()); + MOCK_METHOD0(OnScrollPositionChanged, void()); + MOCK_METHOD0(OnBlur, void()); +}; + +class MockAccessibleCaretEventHub : public AccessibleCaretEventHub +{ +public: + using AccessibleCaretEventHub::NoActionState; + using AccessibleCaretEventHub::PressCaretState; + using AccessibleCaretEventHub::DragCaretState; + using AccessibleCaretEventHub::PressNoCaretState; + using AccessibleCaretEventHub::ScrollState; + using AccessibleCaretEventHub::PostScrollState; + using AccessibleCaretEventHub::LongTapState; + using AccessibleCaretEventHub::FireScrollEnd; + + MockAccessibleCaretEventHub() + : AccessibleCaretEventHub(nullptr) + { + mManager = MakeUnique<MockAccessibleCaretManager>(); + mInitialized = true; + } + + virtual nsPoint GetTouchEventPosition(WidgetTouchEvent* aEvent, + int32_t aIdentifier) const override + { + // Return the device point directly. + LayoutDeviceIntPoint touchIntPoint = aEvent->mTouches[0]->mRefPoint; + return nsPoint(touchIntPoint.x, touchIntPoint.y); + } + + virtual nsPoint GetMouseEventPosition(WidgetMouseEvent* aEvent) const override + { + // Return the device point directly. + LayoutDeviceIntPoint mouseIntPoint = aEvent->AsGUIEvent()->mRefPoint; + return nsPoint(mouseIntPoint.x, mouseIntPoint.y); + } + + MockAccessibleCaretManager* GetMockAccessibleCaretManager() + { + return static_cast<MockAccessibleCaretManager*>(mManager.get()); + } +}; + +// Print the name of the state for debugging. +::std::ostream& operator<<(::std::ostream& aOstream, + const MockAccessibleCaretEventHub::State* aState) +{ + return aOstream << aState->Name(); +} + +class AccessibleCaretEventHubTester : public ::testing::Test +{ +public: + AccessibleCaretEventHubTester() + { + DefaultValue<nsresult>::Set(NS_OK); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::NoActionState()); + + // AccessibleCaretEventHub requires the caller to hold a ref to it. We just + // add ref here for the sake of convenience. + mHub.get()->AddRef(); + } + + ~AccessibleCaretEventHubTester() + { + // Release the ref added in the constructor. + mHub.get()->Release(); + } + + static UniquePtr<WidgetEvent> CreateMouseEvent(EventMessage aMessage, + nscoord aX, + nscoord aY) + { + auto event = MakeUnique<WidgetMouseEvent>(true, aMessage, nullptr, + WidgetMouseEvent::eReal); + + event->button = WidgetMouseEvent::eLeftButton; + event->mRefPoint = LayoutDeviceIntPoint(aX, aY); + + return Move(event); + } + + static UniquePtr<WidgetEvent> CreateMousePressEvent(nscoord aX, nscoord aY) + { + return CreateMouseEvent(eMouseDown, aX, aY); + } + + static UniquePtr<WidgetEvent> CreateMouseMoveEvent(nscoord aX, nscoord aY) + { + return CreateMouseEvent(eMouseMove, aX, aY); + } + + static UniquePtr<WidgetEvent> CreateMouseReleaseEvent(nscoord aX, nscoord aY) + { + return CreateMouseEvent(eMouseUp, aX, aY); + } + + static UniquePtr<WidgetEvent> CreateLongTapEvent(nscoord aX, nscoord aY) + { + return CreateMouseEvent(eMouseLongTap, aX, aY); + } + + static UniquePtr<WidgetEvent> CreateTouchEvent(EventMessage aMessage, + nscoord aX, + nscoord aY) + { + auto event = MakeUnique<WidgetTouchEvent>(true, aMessage, nullptr); + int32_t identifier = 0; + LayoutDeviceIntPoint point(aX, aY); + LayoutDeviceIntPoint radius(19, 19); + float rotationAngle = 0; + float force = 1; + + RefPtr<dom::Touch> touch( + new dom::Touch(identifier, point, radius, rotationAngle, force)); + event->mTouches.AppendElement(touch); + + return Move(event); + } + + static UniquePtr<WidgetEvent> CreateTouchStartEvent(nscoord aX, nscoord aY) + { + return CreateTouchEvent(eTouchStart, aX, aY); + } + + static UniquePtr<WidgetEvent> CreateTouchMoveEvent(nscoord aX, nscoord aY) + { + return CreateTouchEvent(eTouchMove, aX, aY); + } + + static UniquePtr<WidgetEvent> CreateTouchEndEvent(nscoord aX, nscoord aY) + { + return CreateTouchEvent(eTouchEnd, aX, aY); + } + + static UniquePtr<WidgetEvent> CreateTouchCancelEvent(nscoord aX, nscoord aY) + { + return CreateTouchEvent(eTouchCancel, aX, aY); + } + + static UniquePtr<WidgetEvent> CreateWheelEvent(EventMessage aMessage) + { + auto event = MakeUnique<WidgetWheelEvent>(true, aMessage, nullptr); + + return Move(event); + } + + void HandleEventAndCheckState(UniquePtr<WidgetEvent> aEvent, + MockAccessibleCaretEventHub::State* aExpectedState, + nsEventStatus aExpectedEventStatus) + { + nsEventStatus rv = mHub->HandleEvent(aEvent.get()); + EXPECT_EQ(mHub->GetState(), aExpectedState); + EXPECT_EQ(rv, aExpectedEventStatus); + } + + void CheckState(MockAccessibleCaretEventHub::State* aExpectedState) + { + EXPECT_EQ(mHub->GetState(), aExpectedState); + } + + template <typename PressEventCreator, typename ReleaseEventCreator> + void TestPressReleaseOnNoCaret(PressEventCreator aPressEventCreator, + ReleaseEventCreator aReleaseEventCreator); + + template <typename PressEventCreator, typename ReleaseEventCreator> + void TestPressReleaseOnCaret(PressEventCreator aPressEventCreator, + ReleaseEventCreator aReleaseEventCreator); + + template <typename PressEventCreator, typename MoveEventCreator, + typename ReleaseEventCreator> + void TestPressMoveReleaseOnNoCaret(PressEventCreator aPressEventCreator, + MoveEventCreator aMoveEventCreator, + ReleaseEventCreator aReleaseEventCreator); + + template <typename PressEventCreator, typename MoveEventCreator, + typename ReleaseEventCreator> + void TestPressMoveReleaseOnCaret(PressEventCreator aPressEventCreator, + MoveEventCreator aMoveEventCreator, + ReleaseEventCreator aReleaseEventCreator); + + template <typename PressEventCreator, typename ReleaseEventCreator> + void TestLongTapWithSelectWordSuccessful( + PressEventCreator aPressEventCreator, + ReleaseEventCreator aReleaseEventCreator); + + template <typename PressEventCreator, typename ReleaseEventCreator> + void TestLongTapWithSelectWordFailed( + PressEventCreator aPressEventCreator, + ReleaseEventCreator aReleaseEventCreator); + + template <typename PressEventCreator, typename MoveEventCreator, + typename ReleaseEventCreator> + void TestEventDrivenAsyncPanZoomScroll( + PressEventCreator aPressEventCreator, MoveEventCreator aMoveEventCreator, + ReleaseEventCreator aReleaseEventCreator); + + // Member variables + RefPtr<MockAccessibleCaretEventHub> mHub{new MockAccessibleCaretEventHub()}; + +}; // class AccessibleCaretEventHubTester + +TEST_F(AccessibleCaretEventHubTester, TestMousePressReleaseOnNoCaret) +{ + TestPressReleaseOnNoCaret(CreateMousePressEvent, CreateMouseReleaseEvent); +} + +TEST_F(AccessibleCaretEventHubTester, TestTouchPressReleaseOnNoCaret) +{ + TestPressReleaseOnNoCaret(CreateTouchStartEvent, CreateTouchEndEvent); +} + +template <typename PressEventCreator, typename ReleaseEventCreator> +void +AccessibleCaretEventHubTester::TestPressReleaseOnNoCaret( + PressEventCreator aPressEventCreator, + ReleaseEventCreator aReleaseEventCreator) +{ + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), PressCaret(_, _)) + .WillOnce(Return(NS_ERROR_FAILURE)); + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), ReleaseCaret()).Times(0); + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), TapCaret(_)).Times(0); + + HandleEventAndCheckState(aPressEventCreator(0, 0), + MockAccessibleCaretEventHub::PressNoCaretState(), + nsEventStatus_eIgnore); + + HandleEventAndCheckState(aReleaseEventCreator(0, 0), + MockAccessibleCaretEventHub::NoActionState(), + nsEventStatus_eIgnore); +} + +TEST_F(AccessibleCaretEventHubTester, TestMousePressReleaseOnCaret) +{ + TestPressReleaseOnCaret(CreateMousePressEvent, CreateMouseReleaseEvent); +} + +TEST_F(AccessibleCaretEventHubTester, TestTouchPressReleaseOnCaret) +{ + TestPressReleaseOnCaret(CreateTouchStartEvent, CreateTouchEndEvent); +} + +template <typename PressEventCreator, typename ReleaseEventCreator> +void +AccessibleCaretEventHubTester::TestPressReleaseOnCaret( + PressEventCreator aPressEventCreator, + ReleaseEventCreator aReleaseEventCreator) +{ + { + InSequence dummy; + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), PressCaret(_, _)) + .WillOnce(Return(NS_OK)); + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), SelectWordOrShortcut(_)) + .Times(0); + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), ReleaseCaret()); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), TapCaret(_)); + } + + HandleEventAndCheckState(aPressEventCreator(0, 0), + MockAccessibleCaretEventHub::PressCaretState(), + nsEventStatus_eConsumeNoDefault); + + HandleEventAndCheckState(CreateLongTapEvent(0, 0), + MockAccessibleCaretEventHub::PressCaretState(), + nsEventStatus_eConsumeNoDefault); + + HandleEventAndCheckState(aReleaseEventCreator(0, 0), + MockAccessibleCaretEventHub::NoActionState(), + nsEventStatus_eConsumeNoDefault); +} + +TEST_F(AccessibleCaretEventHubTester, TestMousePressMoveReleaseOnNoCaret) +{ + TestPressMoveReleaseOnNoCaret(CreateMousePressEvent, CreateMouseMoveEvent, + CreateMouseReleaseEvent); +} + +TEST_F(AccessibleCaretEventHubTester, TestTouchPressMoveReleaseOnNoCaret) +{ + TestPressMoveReleaseOnNoCaret(CreateTouchStartEvent, CreateTouchMoveEvent, + CreateTouchEndEvent); +} + +template <typename PressEventCreator, typename MoveEventCreator, + typename ReleaseEventCreator> +void +AccessibleCaretEventHubTester::TestPressMoveReleaseOnNoCaret( + PressEventCreator aPressEventCreator, MoveEventCreator aMoveEventCreator, + ReleaseEventCreator aReleaseEventCreator) +{ + nscoord x0 = 0, y0 = 0; + nscoord x1 = 100, y1 = 100; + nscoord x2 = 300, y2 = 300; + nscoord x3 = 400, y3 = 400; + + { + InSequence dummy; + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), PressCaret(_, _)) + .WillOnce(Return(NS_ERROR_FAILURE)); + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), DragCaret(_)).Times(0); + } + + HandleEventAndCheckState(aPressEventCreator(x0, y0), + MockAccessibleCaretEventHub::PressNoCaretState(), + nsEventStatus_eIgnore); + + // A small move with the distance between (x0, y0) and (x1, y1) below the + // tolerance value. + HandleEventAndCheckState(aMoveEventCreator(x1, y1), + MockAccessibleCaretEventHub::PressNoCaretState(), + nsEventStatus_eIgnore); + + // A large move to simulate a dragging to select text since the distance + // between (x0, y0) and (x2, y2) is above the tolerance value. + HandleEventAndCheckState(aMoveEventCreator(x2, y2), + MockAccessibleCaretEventHub::NoActionState(), + nsEventStatus_eIgnore); + + HandleEventAndCheckState(aReleaseEventCreator(x3, y3), + MockAccessibleCaretEventHub::NoActionState(), + nsEventStatus_eIgnore); +} + +TEST_F(AccessibleCaretEventHubTester, TestMousePressMoveReleaseOnCaret) +{ + TestPressMoveReleaseOnCaret(CreateMousePressEvent, CreateMouseMoveEvent, + CreateMouseReleaseEvent); +} + +TEST_F(AccessibleCaretEventHubTester, TestTouchPressMoveReleaseOnCaret) +{ + TestPressMoveReleaseOnCaret(CreateTouchStartEvent, CreateTouchMoveEvent, + CreateTouchEndEvent); +} + +template <typename PressEventCreator, typename MoveEventCreator, + typename ReleaseEventCreator> +void +AccessibleCaretEventHubTester::TestPressMoveReleaseOnCaret( + PressEventCreator aPressEventCreator, MoveEventCreator aMoveEventCreator, + ReleaseEventCreator aReleaseEventCreator) +{ + nscoord x0 = 0, y0 = 0; + nscoord x1 = 100, y1 = 100; + nscoord x2 = 300, y2 = 300; + nscoord x3 = 400, y3 = 400; + + { + InSequence dummy; + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), PressCaret(_, _)) + .WillOnce(Return(NS_OK)); + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), DragCaret(_)) + .Times(2) // two valid drag operations + .WillRepeatedly(Return(NS_OK)); + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), ReleaseCaret()) + .WillOnce(Return(NS_OK)); + } + + HandleEventAndCheckState(aPressEventCreator(x0, y0), + MockAccessibleCaretEventHub::PressCaretState(), + nsEventStatus_eConsumeNoDefault); + + // A small move with the distance between (x0, y0) and (x1, y1) below the + // tolerance value. + HandleEventAndCheckState(aMoveEventCreator(x1, y1), + MockAccessibleCaretEventHub::PressCaretState(), + nsEventStatus_eConsumeNoDefault); + + // A large move forms a valid drag since the distance between (x0, y0) and + // (x2, y2) is above the tolerance value. + HandleEventAndCheckState(aMoveEventCreator(x2, y2), + MockAccessibleCaretEventHub::DragCaretState(), + nsEventStatus_eConsumeNoDefault); + + // Also a valid drag since the distance between (x0, y0) and (x3, y3) above + // the tolerance value even if the distance between (x2, y2) and (x3, y3) is + // below the tolerance value. + HandleEventAndCheckState(aMoveEventCreator(x3, y3), + MockAccessibleCaretEventHub::DragCaretState(), + nsEventStatus_eConsumeNoDefault); + + HandleEventAndCheckState(aReleaseEventCreator(x3, y3), + MockAccessibleCaretEventHub::NoActionState(), + nsEventStatus_eConsumeNoDefault); +} + +TEST_F(AccessibleCaretEventHubTester, + TestTouchStartMoveEndOnCaretWithTouchCancelIgnored) +{ + nscoord x0 = 0, y0 = 0; + nscoord x1 = 100, y1 = 100; + nscoord x2 = 300, y2 = 300; + nscoord x3 = 400, y3 = 400; + + { + InSequence dummy; + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), PressCaret(_, _)) + .WillOnce(Return(NS_OK)); + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), DragCaret(_)) + .WillOnce(Return(NS_OK)); + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), ReleaseCaret()) + .WillOnce(Return(NS_OK)); + } + + // All the eTouchCancel events should be ignored in this test. + + HandleEventAndCheckState(CreateTouchStartEvent(x0, y0), + MockAccessibleCaretEventHub::PressCaretState(), + nsEventStatus_eConsumeNoDefault); + + HandleEventAndCheckState(CreateTouchCancelEvent(x0, y0), + MockAccessibleCaretEventHub::PressCaretState(), + nsEventStatus_eIgnore); + + // A small move with the distance between (x0, y0) and (x1, y1) below the + // tolerance value. + HandleEventAndCheckState(CreateTouchMoveEvent(x1, y1), + MockAccessibleCaretEventHub::PressCaretState(), + nsEventStatus_eConsumeNoDefault); + + HandleEventAndCheckState(CreateTouchCancelEvent(x1, y1), + MockAccessibleCaretEventHub::PressCaretState(), + nsEventStatus_eIgnore); + + // A large move forms a valid drag since the distance between (x0, y0) and + // (x2, y2) is above the tolerance value. + HandleEventAndCheckState(CreateTouchMoveEvent(x2, y2), + MockAccessibleCaretEventHub::DragCaretState(), + nsEventStatus_eConsumeNoDefault); + + HandleEventAndCheckState(CreateTouchCancelEvent(x2, y2), + MockAccessibleCaretEventHub::DragCaretState(), + nsEventStatus_eIgnore); + + HandleEventAndCheckState(CreateTouchEndEvent(x3, y3), + MockAccessibleCaretEventHub::NoActionState(), + nsEventStatus_eConsumeNoDefault); + + HandleEventAndCheckState(CreateTouchCancelEvent(x3, y3), + MockAccessibleCaretEventHub::NoActionState(), + nsEventStatus_eIgnore);} + +TEST_F(AccessibleCaretEventHubTester, TestMouseLongTapWithSelectWordSuccessful) +{ + TestLongTapWithSelectWordSuccessful(CreateMousePressEvent, + CreateMouseReleaseEvent); +} + +TEST_F(AccessibleCaretEventHubTester, TestTouchLongTapWithSelectWordSuccessful) +{ + TestLongTapWithSelectWordSuccessful(CreateTouchStartEvent, + CreateTouchEndEvent); +} + +template <typename PressEventCreator, typename ReleaseEventCreator> +void +AccessibleCaretEventHubTester::TestLongTapWithSelectWordSuccessful( + PressEventCreator aPressEventCreator, + ReleaseEventCreator aReleaseEventCreator) +{ + MockFunction<void(::std::string aCheckPointName)> check; + { + InSequence dummy; + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), PressCaret(_, _)) + .WillOnce(Return(NS_ERROR_FAILURE)); + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), SelectWordOrShortcut(_)) + .WillOnce(Return(NS_OK)); + + EXPECT_CALL(check, Call("longtap with scrolling")); + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), PressCaret(_, _)) + .WillOnce(Return(NS_ERROR_FAILURE)); + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), SelectWordOrShortcut(_)) + .WillOnce(Return(NS_OK)); + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollStart()); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollEnd()); + } + + // Test long tap without scrolling. + HandleEventAndCheckState(aPressEventCreator(0, 0), + MockAccessibleCaretEventHub::PressNoCaretState(), + nsEventStatus_eIgnore); + + HandleEventAndCheckState(CreateLongTapEvent(0, 0), + MockAccessibleCaretEventHub::LongTapState(), + nsEventStatus_eIgnore); + + HandleEventAndCheckState(aReleaseEventCreator(0, 0), + MockAccessibleCaretEventHub::NoActionState(), + nsEventStatus_eIgnore); + + // On Fennec, after long tap, the script might scroll and zoom the input field + // to the center of the screen to make typing easier before the user lifts the + // finger. + check.Call("longtap with scrolling"); + + HandleEventAndCheckState(aPressEventCreator(1, 1), + MockAccessibleCaretEventHub::PressNoCaretState(), + nsEventStatus_eIgnore); + + HandleEventAndCheckState(CreateLongTapEvent(1, 1), + MockAccessibleCaretEventHub::LongTapState(), + nsEventStatus_eIgnore); + + mHub->AsyncPanZoomStarted(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + mHub->ScrollPositionChanged(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + mHub->AsyncPanZoomStopped(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::PostScrollState()); + + // Simulate scroll end fired by timer. + MockAccessibleCaretEventHub::FireScrollEnd(nullptr, mHub); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::NoActionState()); + + HandleEventAndCheckState(aReleaseEventCreator(1, 1), + MockAccessibleCaretEventHub::NoActionState(), + nsEventStatus_eIgnore); +} + +TEST_F(AccessibleCaretEventHubTester, TestMouseLongTapWithSelectWordFailed) +{ + TestLongTapWithSelectWordFailed(CreateMousePressEvent, + CreateMouseReleaseEvent); +} + +TEST_F(AccessibleCaretEventHubTester, TestTouchLongTapWithSelectWordFailed) +{ + TestLongTapWithSelectWordFailed(CreateTouchStartEvent, + CreateTouchEndEvent); +} + +template <typename PressEventCreator, typename ReleaseEventCreator> +void +AccessibleCaretEventHubTester::TestLongTapWithSelectWordFailed( + PressEventCreator aPressEventCreator, + ReleaseEventCreator aReleaseEventCreator) +{ + { + InSequence dummy; + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), PressCaret(_, _)) + .WillOnce(Return(NS_ERROR_FAILURE)); + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), SelectWordOrShortcut(_)) + .WillOnce(Return(NS_ERROR_FAILURE)); + } + + HandleEventAndCheckState(aPressEventCreator(0, 0), + MockAccessibleCaretEventHub::PressNoCaretState(), + nsEventStatus_eIgnore); + + HandleEventAndCheckState(CreateLongTapEvent(0, 0), + MockAccessibleCaretEventHub::LongTapState(), + nsEventStatus_eIgnore); + + HandleEventAndCheckState(aReleaseEventCreator(0, 0), + MockAccessibleCaretEventHub::NoActionState(), + nsEventStatus_eIgnore); +} + +TEST_F(AccessibleCaretEventHubTester, TestTouchEventDrivenAsyncPanZoomScroll) +{ + TestEventDrivenAsyncPanZoomScroll(CreateTouchStartEvent, CreateTouchMoveEvent, + CreateTouchEndEvent); +} + +TEST_F(AccessibleCaretEventHubTester, TestMouseEventDrivenAsyncPanZoomScroll) +{ + TestEventDrivenAsyncPanZoomScroll(CreateMousePressEvent, CreateMouseMoveEvent, + CreateMouseReleaseEvent); +} + +template <typename PressEventCreator, typename MoveEventCreator, + typename ReleaseEventCreator> +void +AccessibleCaretEventHubTester::TestEventDrivenAsyncPanZoomScroll( + PressEventCreator aPressEventCreator, MoveEventCreator aMoveEventCreator, + ReleaseEventCreator aReleaseEventCreator) +{ + MockFunction<void(::std::string aCheckPointName)> check; + { + InSequence dummy; + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), PressCaret(_, _)) + .WillOnce(Return(NS_ERROR_FAILURE)); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), DragCaret(_)).Times(0); + + EXPECT_CALL(check, Call("1")); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollStart()); + + EXPECT_CALL(check, Call("2")); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollEnd()); + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), PressCaret(_, _)) + .WillOnce(Return(NS_ERROR_FAILURE)); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), DragCaret(_)).Times(0); + + EXPECT_CALL(check, Call("3")); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollStart()); + + EXPECT_CALL(check, Call("4")); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollEnd()); + } + + // Receive press event. + HandleEventAndCheckState(aPressEventCreator(0, 0), + MockAccessibleCaretEventHub::PressNoCaretState(), + nsEventStatus_eIgnore); + + HandleEventAndCheckState(aMoveEventCreator(100, 100), + MockAccessibleCaretEventHub::PressNoCaretState(), + nsEventStatus_eIgnore); + + check.Call("1"); + + // Event driven scroll started + mHub->AsyncPanZoomStarted(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + HandleEventAndCheckState(aMoveEventCreator(160, 160), + MockAccessibleCaretEventHub::ScrollState(), + nsEventStatus_eIgnore); + + mHub->ScrollPositionChanged(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + // Event driven scroll ended + mHub->AsyncPanZoomStopped(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::PostScrollState()); + + HandleEventAndCheckState(aReleaseEventCreator(210, 210), + MockAccessibleCaretEventHub::PostScrollState(), + nsEventStatus_eIgnore); + + check.Call("2"); + + // Receive another press event. + HandleEventAndCheckState(aPressEventCreator(220, 220), + MockAccessibleCaretEventHub::PressNoCaretState(), + nsEventStatus_eIgnore); + + HandleEventAndCheckState(aMoveEventCreator(230, 230), + MockAccessibleCaretEventHub::PressNoCaretState(), + nsEventStatus_eIgnore); + + check.Call("3"); + + // Another APZ scroll started + mHub->AsyncPanZoomStarted(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + mHub->ScrollPositionChanged(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + // Another APZ scroll ended + mHub->AsyncPanZoomStopped(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::PostScrollState()); + + HandleEventAndCheckState(aReleaseEventCreator(310, 310), + MockAccessibleCaretEventHub::PostScrollState(), + nsEventStatus_eIgnore); + + check.Call("4"); + + // Simulate scroll end fired by timer. + MockAccessibleCaretEventHub::FireScrollEnd(nullptr, mHub); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::NoActionState()); +} + +TEST_F(AccessibleCaretEventHubTester, TestNoEventAsyncPanZoomScroll) +{ + MockFunction<void(::std::string aCheckPointName)> check; + { + InSequence dummy; + + EXPECT_CALL(check, Call("1")); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollStart()); + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), + OnScrollPositionChanged()).Times(0); + + EXPECT_CALL(check, Call("2")); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollEnd()); + } + + check.Call("1"); + + mHub->AsyncPanZoomStarted(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + mHub->ScrollPositionChanged(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + mHub->AsyncPanZoomStopped(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::PostScrollState()); + + mHub->AsyncPanZoomStarted(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + mHub->ScrollPositionChanged(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + mHub->AsyncPanZoomStopped(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::PostScrollState()); + + check.Call("2"); + + // Simulate scroll end fired by timer. + MockAccessibleCaretEventHub::FireScrollEnd(nullptr, mHub); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::NoActionState()); +} + +TEST_F(AccessibleCaretEventHubTester, TestAsyncPanZoomScrollStartedThenBlur) +{ + { + InSequence dummy; + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollStart()); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollEnd()).Times(0); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnBlur()); + } + + mHub->AsyncPanZoomStarted(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + mHub->ScrollPositionChanged(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + mHub->NotifyBlur(true); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::NoActionState()); +} + +TEST_F(AccessibleCaretEventHubTester, TestAsyncPanZoomScrollEndedThenBlur) +{ + { + InSequence dummy; + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollStart()); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollEnd()).Times(0); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnBlur()); + } + + mHub->AsyncPanZoomStarted(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + mHub->ScrollPositionChanged(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + mHub->AsyncPanZoomStopped(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::PostScrollState()); + + mHub->NotifyBlur(true); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::NoActionState()); +} + +} // namespace mozilla |