diff options
Diffstat (limited to '')
-rw-r--r-- | layout/base/gtest/TestAccessibleCaretEventHub.cpp | 785 |
1 files changed, 785 insertions, 0 deletions
diff --git a/layout/base/gtest/TestAccessibleCaretEventHub.cpp b/layout/base/gtest/TestAccessibleCaretEventHub.cpp new file mode 100644 index 0000000000..6a3c9b61ac --- /dev/null +++ b/layout/base/gtest/TestAccessibleCaretEventHub.cpp @@ -0,0 +1,785 @@ +/* -*- 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 "AccessibleCaretManager.h" + +#include "mozilla/AccessibleCaretEventHub.h" +#include "mozilla/BasicEvents.h" +#include "mozilla/MouseEvents.h" +#include "mozilla/TouchEvents.h" + +using ::testing::_; +using ::testing::AtLeast; +using ::testing::DefaultValue; +using ::testing::Eq; +using ::testing::InSequence; +using ::testing::MockFunction; +using ::testing::Return; + +// ----------------------------------------------------------------------------- +// 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::DragCaretState; + using AccessibleCaretEventHub::LongTapState; + using AccessibleCaretEventHub::NoActionState; + using AccessibleCaretEventHub::PressCaretState; + using AccessibleCaretEventHub::PressNoCaretState; + using AccessibleCaretEventHub::ScrollState; + + MockAccessibleCaretEventHub() : AccessibleCaretEventHub(nullptr) { + mManager = MakeUnique<MockAccessibleCaretManager>(); + mInitialized = true; + } + + 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); + } + + 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. +static ::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() override { + // 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->mButton = MouseButton::ePrimary; + event->mRefPoint = LayoutDeviceIntPoint(aX, aY); + + return std::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 std::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 std::move(event); + } + + MOZ_CAN_RUN_SCRIPT_BOUNDARY void TestAsyncPanZoomScroll(); + + MOZ_CAN_RUN_SCRIPT_BOUNDARY + void HandleEventAndCheckState( + UniquePtr<WidgetEvent> aEvent, + MockAccessibleCaretEventHub::State* aExpectedState, + nsEventStatus aExpectedEventStatus) { + RefPtr<MockAccessibleCaretEventHub> hub(mHub); + nsEventStatus rv = hub->HandleEvent(aEvent.get()); + EXPECT_EQ(hub->GetState(), aExpectedState); + EXPECT_EQ(rv, aExpectedEventStatus); + } + + void CheckState(MockAccessibleCaretEventHub::State* aExpectedState) { + EXPECT_EQ(mHub->GetState(), aExpectedState); + } + + template <typename PressEventCreator, typename ReleaseEventCreator> + MOZ_CAN_RUN_SCRIPT_BOUNDARY void TestPressReleaseOnNoCaret( + PressEventCreator aPressEventCreator, + ReleaseEventCreator aReleaseEventCreator); + + template <typename PressEventCreator, typename ReleaseEventCreator> + MOZ_CAN_RUN_SCRIPT_BOUNDARY void TestPressReleaseOnCaret( + PressEventCreator aPressEventCreator, + ReleaseEventCreator aReleaseEventCreator); + + template <typename PressEventCreator, typename MoveEventCreator, + typename ReleaseEventCreator> + MOZ_CAN_RUN_SCRIPT_BOUNDARY void TestPressMoveReleaseOnNoCaret( + PressEventCreator aPressEventCreator, MoveEventCreator aMoveEventCreator, + ReleaseEventCreator aReleaseEventCreator); + + template <typename PressEventCreator, typename MoveEventCreator, + typename ReleaseEventCreator> + MOZ_CAN_RUN_SCRIPT_BOUNDARY void TestPressMoveReleaseOnCaret( + PressEventCreator aPressEventCreator, MoveEventCreator aMoveEventCreator, + ReleaseEventCreator aReleaseEventCreator); + + template <typename PressEventCreator, typename ReleaseEventCreator> + MOZ_CAN_RUN_SCRIPT_BOUNDARY void TestLongTapWithSelectWordSuccessful( + PressEventCreator aPressEventCreator, + ReleaseEventCreator aReleaseEventCreator); + + template <typename PressEventCreator, typename ReleaseEventCreator> + MOZ_CAN_RUN_SCRIPT_BOUNDARY void TestLongTapWithSelectWordFailed( + PressEventCreator aPressEventCreator, + ReleaseEventCreator aReleaseEventCreator); + + template <typename PressEventCreator, typename MoveEventCreator, + typename ReleaseEventCreator> + MOZ_CAN_RUN_SCRIPT_BOUNDARY void TestEventDrivenAsyncPanZoomScroll( + PressEventCreator aPressEventCreator, MoveEventCreator aMoveEventCreator, + ReleaseEventCreator aReleaseEventCreator); + + // Member variables + RefPtr<MockAccessibleCaretEventHub> mHub{new MockAccessibleCaretEventHub()}; + +}; // class AccessibleCaretEventHubTester + +TEST_F(AccessibleCaretEventHubTester, TestMousePressReleaseOnNoCaret) +MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION { + TestPressReleaseOnNoCaret(CreateMousePressEvent, CreateMouseReleaseEvent); +} + +TEST_F(AccessibleCaretEventHubTester, TestTouchPressReleaseOnNoCaret) +MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION { + 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) +MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION { + TestPressReleaseOnCaret(CreateMousePressEvent, CreateMouseReleaseEvent); +} + +TEST_F(AccessibleCaretEventHubTester, TestTouchPressReleaseOnCaret) +MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION { + 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) +MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION { + TestPressMoveReleaseOnNoCaret(CreateMousePressEvent, CreateMouseMoveEvent, + CreateMouseReleaseEvent); +} + +TEST_F(AccessibleCaretEventHubTester, TestTouchPressMoveReleaseOnNoCaret) +MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION { + 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) +MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION { + TestPressMoveReleaseOnCaret(CreateMousePressEvent, CreateMouseMoveEvent, + CreateMouseReleaseEvent); +} + +TEST_F(AccessibleCaretEventHubTester, TestTouchPressMoveReleaseOnCaret) +MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION { + 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) +MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION { + 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) +MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION { + TestLongTapWithSelectWordSuccessful(CreateMousePressEvent, + CreateMouseReleaseEvent); +} + +TEST_F(AccessibleCaretEventHubTester, TestTouchLongTapWithSelectWordSuccessful) +MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION { + 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); + + RefPtr<MockAccessibleCaretEventHub> hub(mHub); + hub->AsyncPanZoomStarted(); + EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + hub->ScrollPositionChanged(); + EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + hub->AsyncPanZoomStopped(); + EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::NoActionState()); + + HandleEventAndCheckState(aReleaseEventCreator(1, 1), + MockAccessibleCaretEventHub::NoActionState(), + nsEventStatus_eIgnore); +} + +TEST_F(AccessibleCaretEventHubTester, TestMouseLongTapWithSelectWordFailed) +MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION { + TestLongTapWithSelectWordFailed(CreateMousePressEvent, + CreateMouseReleaseEvent); +} + +TEST_F(AccessibleCaretEventHubTester, TestTouchLongTapWithSelectWordFailed) +MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION { + 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) +MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION { + TestEventDrivenAsyncPanZoomScroll(CreateTouchStartEvent, CreateTouchMoveEvent, + CreateTouchEndEvent); +} + +TEST_F(AccessibleCaretEventHubTester, TestMouseEventDrivenAsyncPanZoomScroll) +MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION { + 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(*mHub->GetMockAccessibleCaretManager(), OnScrollEnd()); + + EXPECT_CALL(check, Call("2")); + 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(*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 + RefPtr<MockAccessibleCaretEventHub> hub(mHub); + hub->AsyncPanZoomStarted(); + EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + HandleEventAndCheckState(aMoveEventCreator(160, 160), + MockAccessibleCaretEventHub::ScrollState(), + nsEventStatus_eIgnore); + + hub->ScrollPositionChanged(); + EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + // Event driven scroll ended + hub->AsyncPanZoomStopped(); + EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::NoActionState()); + + HandleEventAndCheckState(aReleaseEventCreator(210, 210), + MockAccessibleCaretEventHub::NoActionState(), + 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 + hub->AsyncPanZoomStarted(); + EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + hub->ScrollPositionChanged(); + EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + // Another APZ scroll ended + hub->AsyncPanZoomStopped(); + EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::NoActionState()); + + HandleEventAndCheckState(aReleaseEventCreator(310, 310), + MockAccessibleCaretEventHub::NoActionState(), + nsEventStatus_eIgnore); +} + +TEST_F(AccessibleCaretEventHubTester, TestAsyncPanZoomScroll) +MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION { TestAsyncPanZoomScroll(); } + +void AccessibleCaretEventHubTester::TestAsyncPanZoomScroll() { + MockFunction<void(::std::string aCheckPointName)> check; + { + InSequence dummy; + + EXPECT_CALL(check, Call("1")); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollStart()); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), + OnScrollPositionChanged()); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollEnd()); + + EXPECT_CALL(check, Call("2")); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollStart()); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), + OnScrollPositionChanged()); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollEnd()); + } + + // First APZ scrolling. + check.Call("1"); + + RefPtr<MockAccessibleCaretEventHub> hub(mHub); + hub->AsyncPanZoomStarted(); + EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + hub->ScrollPositionChanged(); + EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + hub->AsyncPanZoomStopped(); + EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::NoActionState()); + + // Second APZ scrolling. + check.Call("2"); + + hub->AsyncPanZoomStarted(); + EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + hub->ScrollPositionChanged(); + EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + hub->AsyncPanZoomStopped(); + EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::NoActionState()); +} + +TEST_F(AccessibleCaretEventHubTester, TestAsyncPanZoomScrollStartedThenBlur) +MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION { + { + InSequence dummy; + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollStart()); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollEnd()).Times(0); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnBlur()); + } + + RefPtr<MockAccessibleCaretEventHub> hub(mHub); + hub->AsyncPanZoomStarted(); + EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + hub->ScrollPositionChanged(); + EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + hub->NotifyBlur(true); + EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::NoActionState()); +} + +TEST_F(AccessibleCaretEventHubTester, TestAsyncPanZoomScrollEndedThenBlur) +MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION { + { + InSequence dummy; + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollStart()); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollEnd()); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnBlur()); + } + + RefPtr<MockAccessibleCaretEventHub> hub(mHub); + hub->AsyncPanZoomStarted(); + EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + hub->ScrollPositionChanged(); + EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + hub->AsyncPanZoomStopped(); + EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::NoActionState()); + + hub->NotifyBlur(true); + EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::NoActionState()); +} + +} // namespace mozilla |