TEST(ScrollAnimatorTest, Disabled) { OwnPtrWillBeRawPtr<MockScrollableArea> scrollableArea = MockScrollableArea::create(false); OwnPtrWillBeRawPtr<ScrollAnimator> scrollAnimator = adoptPtrWillBeNoop(new ScrollAnimator(scrollableArea.get(), getMockedTime)); EXPECT_CALL(*scrollableArea, minimumScrollPosition()).Times(AtLeast(1)).WillRepeatedly(Return(IntPoint())); EXPECT_CALL(*scrollableArea, maximumScrollPosition()).Times(AtLeast(1)).WillRepeatedly(Return(IntPoint(1000, 1000))); EXPECT_CALL(*scrollableArea, setScrollOffset(_, _)).Times(8); EXPECT_CALL(*scrollableArea, registerForAnimation()).Times(0); scrollAnimator->userScroll(HorizontalScrollbar, ScrollByLine, 100, 1); EXPECT_EQ(100, scrollAnimator->currentPosition().x()); EXPECT_EQ(0, scrollAnimator->currentPosition().y()); reset(*scrollAnimator); scrollAnimator->userScroll(HorizontalScrollbar, ScrollByPage, 100, 1); EXPECT_EQ(100, scrollAnimator->currentPosition().x()); EXPECT_EQ(0, scrollAnimator->currentPosition().y()); reset(*scrollAnimator); scrollAnimator->userScroll(HorizontalScrollbar, ScrollByDocument, 100, 1); EXPECT_EQ(100, scrollAnimator->currentPosition().x()); EXPECT_EQ(0, scrollAnimator->currentPosition().y()); reset(*scrollAnimator); scrollAnimator->userScroll(HorizontalScrollbar, ScrollByPixel, 100, 1); EXPECT_EQ(100, scrollAnimator->currentPosition().x()); EXPECT_EQ(0, scrollAnimator->currentPosition().y()); reset(*scrollAnimator); }
TEST_F(SimpleObjectTest, erase_opengl_buffers_before_buffer_generating) { EXPECT_CALL(gl, gl_GetError()).Times(AnyNumber()); { InSequence s; EXPECT_CALL(gl, gl_GetError()).Times(AtLeast(1)); EXPECT_CALL(gl, gl_GenBuffers(_,_)).Times(AtLeast(1)); } SimpleObject so(to); }
TEST_F(JoynrClusterControllerRuntimeTest, registerAndSubscribeToLocalProvider) { createRuntimeMqttWithHttpBackend(); std::remove(LibjoynrSettings::DEFAULT_SUBSCRIPTIONREQUEST_STORAGE_FILENAME().c_str()); std::string domain("JoynrClusterControllerRuntimeTest.Domain.A"); auto mockTestProvider = std::make_shared<MockTestProvider>(); EXPECT_CALL( *mockTestProvider, getLocation(A<std::function<void(const types::Localisation::GpsLocation&)>>(), A<std::function<void(const joynr::exceptions::ProviderRuntimeException&)>>()) ) .Times(AtLeast(1)) .WillRepeatedly(Invoke( this, &JoynrClusterControllerRuntimeTest::invokeOnSuccessWithGpsLocation )); runtime->startMessaging(); std::string participantId = runtime->registerProvider<tests::testProvider>( domain, mockTestProvider ); ProxyBuilder<tests::testProxy>* testProxyBuilder = runtime->createProxyBuilder<tests::testProxy>(domain); DiscoveryQos discoveryQos(1000); discoveryQos.addCustomParameter("fixedParticipantId", participantId); discoveryQos.setDiscoveryTimeoutMs(50); discoveryQos.setArbitrationStrategy(DiscoveryQos::ArbitrationStrategy::FIXED_PARTICIPANT); tests::testProxy* testProxy = testProxyBuilder ->setMessagingQos(MessagingQos(5000)) ->setCached(false) ->setDiscoveryQos(discoveryQos) ->build(); auto mockSubscriptionListener = std::make_shared<MockGpsSubscriptionListener>(); EXPECT_CALL(*mockSubscriptionListener, onReceive(gpsLocation)) .Times(AtLeast(1)); OnChangeWithKeepAliveSubscriptionQos subscriptionQos( 480, // validity 200, // min interval 200, // max interval 200 // alert after interval ); std::string subscriptionId = testProxy->subscribeToLocation(mockSubscriptionListener, subscriptionQos); std::this_thread::sleep_for(std::chrono::milliseconds(250)); testProxy->unsubscribeFromLocation(subscriptionId); delete testProxy; delete testProxyBuilder; }
TEST_F(JoynrClusterControllerRuntimeTest, registerAndSubscribeToLocalProvider) { createRuntimeMqtt(); std::remove(LibjoynrSettings::DEFAULT_SUBSCRIPTIONREQUEST_PERSISTENCE_FILENAME().c_str()); std::string domain("JoynrClusterControllerRuntimeTest.Domain.A"); auto mockTestProvider = std::make_shared<MockTestProvider>(); types::ProviderQos providerQos; std::chrono::milliseconds millisSinceEpoch = std::chrono::duration_cast<std::chrono::milliseconds>( std::chrono::system_clock::now().time_since_epoch()); providerQos.setPriority(millisSinceEpoch.count()); providerQos.setScope(joynr::types::ProviderScope::GLOBAL); providerQos.setSupportsOnChangeSubscriptions(true); EXPECT_CALL( *mockTestProvider, getLocation( A<std::function<void(const types::Localisation::GpsLocation&)>>(), A<std::function<void(const joynr::exceptions::ProviderRuntimeException&)>>())) .Times(AtLeast(1)) .WillRepeatedly(Invoke( this, &JoynrClusterControllerRuntimeTest::invokeOnSuccessWithGpsLocation)); runtime->startExternalCommunication(); std::string participantId = runtime->registerProvider<tests::testProvider>(domain, mockTestProvider, providerQos); std::shared_ptr<ProxyBuilder<tests::testProxy>> testProxyBuilder = runtime->createProxyBuilder<tests::testProxy>(domain); DiscoveryQos discoveryQos(1000); discoveryQos.addCustomParameter("fixedParticipantId", participantId); discoveryQos.setDiscoveryTimeoutMs(50); discoveryQos.setArbitrationStrategy(DiscoveryQos::ArbitrationStrategy::FIXED_PARTICIPANT); std::shared_ptr<tests::testProxy> testProxy( testProxyBuilder->setMessagingQos(MessagingQos(5000)) ->setDiscoveryQos(discoveryQos) ->build()); auto mockSubscriptionListener = std::make_shared<MockGpsSubscriptionListener>(); EXPECT_CALL(*mockSubscriptionListener, onReceive(gpsLocation)).Times(AtLeast(1)); auto subscriptionQos = std::make_shared<OnChangeWithKeepAliveSubscriptionQos>(480, // validity 1000, // publication ttl 200, // min interval 200, // max interval 200 // alert after interval ); auto future = testProxy->subscribeToLocation(mockSubscriptionListener, subscriptionQos); std::string subscriptionId; JOYNR_ASSERT_NO_THROW({ future->get(5000, subscriptionId); });
TEST(ScrollAnimatorEnabled, Enabled) { MockScrollableArea scrollableArea(true); MockScrollAnimatorNone scrollAnimatorNone(&scrollableArea); EXPECT_CALL(scrollableArea, scrollSize(_)).Times(AtLeast(1)).WillRepeatedly(Return(1000)); EXPECT_CALL(scrollableArea, setScrollOffset(_)).Times(3); scrollAnimatorNone.scroll(HorizontalScrollbar, ScrollByLine, 100, 1); EXPECT_NE(100, scrollAnimatorNone.currentX()); EXPECT_NE(0, scrollAnimatorNone.currentX()); EXPECT_EQ(0, scrollAnimatorNone.currentY()); scrollAnimatorNone.reset(); scrollAnimatorNone.scroll(HorizontalScrollbar, ScrollByPage, 100, 1); EXPECT_NE(100, scrollAnimatorNone.currentX()); EXPECT_NE(0, scrollAnimatorNone.currentX()); EXPECT_EQ(0, scrollAnimatorNone.currentY()); scrollAnimatorNone.reset(); scrollAnimatorNone.scroll(HorizontalScrollbar, ScrollByPixel, 4, 25); EXPECT_NE(100, scrollAnimatorNone.currentX()); EXPECT_NE(0, scrollAnimatorNone.currentX()); EXPECT_EQ(0, scrollAnimatorNone.currentY()); scrollAnimatorNone.reset(); }
// Test that cancelling an animation resets the animation state. // See crbug.com/598548. TEST(ScrollAnimatorTest, CancellingAnimationResetsState) { MockScrollableArea* scrollableArea = MockScrollableArea::create( true, ScrollOffset(), ScrollOffset(1000, 1000)); ScrollAnimator* scrollAnimator = new ScrollAnimator(scrollableArea, getMockedTime); // Called from first userScroll, setCurrentOffset, and second userScroll. EXPECT_CALL(*scrollableArea, updateScrollOffset(_, _)).Times(3); // Called from userScroll, updateCompositorAnimations. EXPECT_CALL(*scrollableArea, registerForAnimation()).Times(4); EXPECT_CALL(*scrollableArea, scheduleAnimation()) .Times(AtLeast(1)) .WillRepeatedly(Return(true)); EXPECT_EQ(0, scrollAnimator->currentOffset().width()); EXPECT_EQ(0, scrollAnimator->currentOffset().height()); // WaitingToSendToCompositor scrollAnimator->userScroll(ScrollByLine, FloatSize(10, 0)); EXPECT_EQ( scrollAnimator->m_runState, ScrollAnimatorCompositorCoordinator::RunState::WaitingToSendToCompositor); // RunningOnMainThread gMockedTime += 0.05; scrollAnimator->updateCompositorAnimations(); EXPECT_EQ(scrollAnimator->m_runState, ScrollAnimatorCompositorCoordinator::RunState::RunningOnMainThread); scrollAnimator->tickAnimation(getMockedTime()); EXPECT_EQ(scrollAnimator->m_runState, ScrollAnimatorCompositorCoordinator::RunState::RunningOnMainThread); // Amount scrolled so far. float offsetX = scrollAnimator->currentOffset().width(); // Interrupt user scroll. scrollAnimator->cancelAnimation(); EXPECT_EQ( scrollAnimator->m_runState, ScrollAnimatorCompositorCoordinator::RunState::PostAnimationCleanup); // Another userScroll after modified scroll offset. scrollAnimator->setCurrentOffset(ScrollOffset(offsetX + 15, 0)); scrollAnimator->userScroll(ScrollByLine, FloatSize(10, 0)); EXPECT_EQ( scrollAnimator->m_runState, ScrollAnimatorCompositorCoordinator::RunState::WaitingToSendToCompositor); // Finish scroll animation. gMockedTime += 1.0; scrollAnimator->updateCompositorAnimations(); scrollAnimator->tickAnimation(getMockedTime()); EXPECT_EQ( scrollAnimator->m_runState, ScrollAnimatorCompositorCoordinator::RunState::PostAnimationCleanup); EXPECT_EQ(offsetX + 15 + 10, scrollAnimator->currentOffset().width()); EXPECT_EQ(0, scrollAnimator->currentOffset().height()); reset(*scrollAnimator); }
// Test that a smooth scroll offset animation is aborted when followed by a // non-smooth scroll offset animation. TEST(ScrollAnimatorTest, AnimatedScrollAborted) { OwnPtrWillBeRawPtr<MockScrollableArea> scrollableArea = MockScrollableArea::create(true); OwnPtrWillBeRawPtr<ScrollAnimator> scrollAnimator = adoptPtrWillBeNoop( new ScrollAnimator(scrollableArea.get(), getMockedTime)); EXPECT_CALL(*scrollableArea, minimumScrollPosition()).Times(AtLeast(1)) .WillRepeatedly(Return(IntPoint())); EXPECT_CALL(*scrollableArea, maximumScrollPosition()).Times(AtLeast(1)) .WillRepeatedly(Return(IntPoint(1000, 1000))); EXPECT_CALL(*scrollableArea, setScrollOffset(_, _)).Times(3); EXPECT_CALL(*scrollableArea, registerForAnimation()).Times(2); EXPECT_CALL(*scrollableArea, scheduleAnimation()).Times(AtLeast(1)) .WillRepeatedly(Return(true)); EXPECT_FALSE(scrollAnimator->hasAnimationThatRequiresService()); // Smooth scroll. ScrollResultOneDimensional result = scrollAnimator->userScroll( HorizontalScrollbar, ScrollByLine, 100, 1); EXPECT_TRUE(scrollAnimator->hasAnimationThatRequiresService()); EXPECT_TRUE(result.didScroll); EXPECT_FLOAT_EQ(0.0, result.unusedScrollDelta); EXPECT_TRUE(scrollAnimator->hasRunningAnimation()); gMockedTime += 0.05; scrollAnimator->updateCompositorAnimations(); scrollAnimator->tickAnimation(getMockedTime()); EXPECT_NE(100, scrollAnimator->currentPosition().x()); EXPECT_NE(0, scrollAnimator->currentPosition().x()); EXPECT_EQ(0, scrollAnimator->currentPosition().y()); float x = scrollAnimator->currentPosition().x(); // Instant scroll. result = scrollAnimator->userScroll( HorizontalScrollbar, ScrollByPrecisePixel, 100, 1); EXPECT_TRUE(result.didScroll); EXPECT_FALSE(scrollAnimator->hasRunningAnimation()); EXPECT_EQ(x + 100, scrollAnimator->currentPosition().x()); EXPECT_EQ(0, scrollAnimator->currentPosition().y()); reset(*scrollAnimator); }
TEST(ScrollAnimatorTest, MainThreadAnimationTargetAdjustment) { MockScrollableArea* scrollableArea = MockScrollableArea::create( true, ScrollOffset(-100, -100), ScrollOffset(1000, 1000)); ScrollAnimator* animator = new ScrollAnimator(scrollableArea, getMockedTime); scrollableArea->setScrollAnimator(animator); // Twice from tickAnimation, once from reset, and twice from // adjustAnimationAndSetScrollOffset. EXPECT_CALL(*scrollableArea, updateScrollOffset(_, _)).Times(5); // One from call to userScroll and one from updateCompositorAnimations. EXPECT_CALL(*scrollableArea, registerForAnimation()).Times(2); EXPECT_CALL(*scrollableArea, scheduleAnimation()) .Times(AtLeast(1)) .WillRepeatedly(Return(true)); // Idle EXPECT_FALSE(animator->hasAnimationThatRequiresService()); EXPECT_EQ(ScrollOffset(), animator->currentOffset()); // WaitingToSendToCompositor animator->userScroll(ScrollByLine, ScrollOffset(100, 100)); // RunningOnMainThread gMockedTime += 0.05; animator->updateCompositorAnimations(); animator->tickAnimation(getMockedTime()); ScrollOffset offset = animator->currentOffset(); EXPECT_EQ(ScrollOffset(100, 100), animator->desiredTargetOffset()); EXPECT_GT(offset.width(), 0); EXPECT_GT(offset.height(), 0); // Adjustment ScrollOffset newOffset = offset + ScrollOffset(10, -10); animator->adjustAnimationAndSetScrollOffset(newOffset, AnchoringScroll); EXPECT_EQ(ScrollOffset(110, 90), animator->desiredTargetOffset()); // Adjusting after finished animation should do nothing. gMockedTime += 1.0; animator->updateCompositorAnimations(); animator->tickAnimation(getMockedTime()); EXPECT_EQ( animator->runStateForTesting(), ScrollAnimatorCompositorCoordinator::RunState::PostAnimationCleanup); newOffset = animator->currentOffset() + ScrollOffset(10, -10); animator->adjustAnimationAndSetScrollOffset(newOffset, AnchoringScroll); EXPECT_EQ( animator->runStateForTesting(), ScrollAnimatorCompositorCoordinator::RunState::PostAnimationCleanup); EXPECT_EQ(ScrollOffset(110, 90), animator->desiredTargetOffset()); reset(*animator); // Forced GC in order to finalize objects depending on the mock object. ThreadState::current()->collectAllGarbage(); }
TEST(ScrollAnimatorTest, MainThreadStates) { MockScrollableArea* scrollableArea = MockScrollableArea::create( true, ScrollOffset(), ScrollOffset(1000, 1000)); ScrollAnimator* scrollAnimator = new ScrollAnimator(scrollableArea, getMockedTime); EXPECT_CALL(*scrollableArea, updateScrollOffset(_, _)).Times(2); // Once from userScroll, once from updateCompositorAnimations. EXPECT_CALL(*scrollableArea, registerForAnimation()).Times(2); EXPECT_CALL(*scrollableArea, scheduleAnimation()) .Times(AtLeast(1)) .WillRepeatedly(Return(true)); // Idle EXPECT_FALSE(scrollAnimator->hasAnimationThatRequiresService()); EXPECT_EQ(scrollAnimator->m_runState, ScrollAnimatorCompositorCoordinator::RunState::Idle); // WaitingToSendToCompositor scrollAnimator->userScroll(ScrollByLine, FloatSize(10, 0)); EXPECT_EQ( scrollAnimator->m_runState, ScrollAnimatorCompositorCoordinator::RunState::WaitingToSendToCompositor); // RunningOnMainThread gMockedTime += 0.05; scrollAnimator->updateCompositorAnimations(); EXPECT_EQ(scrollAnimator->m_runState, ScrollAnimatorCompositorCoordinator::RunState::RunningOnMainThread); scrollAnimator->tickAnimation(getMockedTime()); EXPECT_EQ(scrollAnimator->m_runState, ScrollAnimatorCompositorCoordinator::RunState::RunningOnMainThread); // PostAnimationCleanup scrollAnimator->cancelAnimation(); EXPECT_EQ( scrollAnimator->m_runState, ScrollAnimatorCompositorCoordinator::RunState::PostAnimationCleanup); // Idle scrollAnimator->updateCompositorAnimations(); scrollAnimator->tickAnimation(getMockedTime()); EXPECT_EQ(scrollAnimator->m_runState, ScrollAnimatorCompositorCoordinator::RunState::Idle); reset(*scrollAnimator); // Forced GC in order to finalize objects depending on the mock object. ThreadState::current()->collectAllGarbage(); }
std::shared_ptr<erizo::MockMediaStream> addMediaStream(bool is_publisher, StreamConfig config) { std::string id = std::to_string(index); std::string label = std::to_string(index); uint32_t video_sink_ssrc = getSsrcFromIndex(index); uint32_t audio_sink_ssrc = getSsrcFromIndex(index) + 1; uint32_t video_source_ssrc = getSsrcFromIndex(index) + 2; uint32_t audio_source_ssrc = getSsrcFromIndex(index) + 3; auto media_stream = std::make_shared<erizo::MockMediaStream>(nullptr, nullptr, id, label, rtp_maps, is_publisher); media_stream->setVideoSinkSSRC(video_sink_ssrc); media_stream->setAudioSinkSSRC(audio_sink_ssrc); media_stream->setVideoSourceSSRC(video_source_ssrc); media_stream->setAudioSourceSSRC(audio_source_ssrc); EXPECT_CALL(*media_stream, getMaxVideoBW()).Times(AtLeast(0)).WillRepeatedly(Return(config.max_video_bw)); EXPECT_CALL(*media_stream, getVideoBitrate()).Times(AtLeast(0)).WillRepeatedly(Return(config.bitrate_sent)); EXPECT_CALL(*media_stream, getBitrateFromMaxQualityLayer()).Times(AtLeast(0)) .WillRepeatedly(Return(config.max_quality_bitrate)); EXPECT_CALL(*media_stream, isSlideShowModeEnabled()).Times(AtLeast(0)).WillRepeatedly(Return(config.slideshow)); EXPECT_CALL(*media_stream, isSimulcast()).Times(AtLeast(0)).WillRepeatedly(Return(config.simulcast)); index++; return media_stream; }
// Test that a smooth scroll offset animation running on the compositor is // completed on the main thread. TEST(ScrollAnimatorTest, AnimatedScrollTakeover) { MockScrollableArea* scrollableArea = MockScrollableArea::create( true, ScrollOffset(), ScrollOffset(1000, 1000)); TestScrollAnimator* scrollAnimator = new TestScrollAnimator(scrollableArea, getMockedTime); EXPECT_CALL(*scrollableArea, updateScrollOffset(_, _)).Times(2); // Called from userScroll, updateCompositorAnimations, then // takeOverCompositorAnimation (to re-register after RunningOnCompositor). EXPECT_CALL(*scrollableArea, registerForAnimation()).Times(3); EXPECT_CALL(*scrollableArea, scheduleAnimation()) .Times(AtLeast(1)) .WillRepeatedly(Return(true)); EXPECT_FALSE(scrollAnimator->hasAnimationThatRequiresService()); // Smooth scroll. ScrollResult result = scrollAnimator->userScroll(ScrollByLine, FloatSize(100, 0)); EXPECT_TRUE(scrollAnimator->hasAnimationThatRequiresService()); EXPECT_TRUE(result.didScrollX); EXPECT_FLOAT_EQ(0.0, result.unusedScrollDeltaX); EXPECT_TRUE(scrollAnimator->hasRunningAnimation()); // Update compositor animation. gMockedTime += 0.05; scrollAnimator->setShouldSendToCompositor(true); scrollAnimator->updateCompositorAnimations(); EXPECT_EQ(scrollAnimator->m_runState, ScrollAnimatorCompositorCoordinator::RunState::RunningOnCompositor); // Takeover. scrollAnimator->takeOverCompositorAnimation(); EXPECT_EQ(scrollAnimator->m_runState, ScrollAnimatorCompositorCoordinator::RunState:: RunningOnCompositorButNeedsTakeover); // Animation should now be running on the main thread. scrollAnimator->setShouldSendToCompositor(false); scrollAnimator->updateCompositorAnimations(); EXPECT_EQ(scrollAnimator->m_runState, ScrollAnimatorCompositorCoordinator::RunState::RunningOnMainThread); scrollAnimator->tickAnimation(getMockedTime()); EXPECT_NE(100, scrollAnimator->currentOffset().width()); EXPECT_NE(0, scrollAnimator->currentOffset().width()); EXPECT_EQ(0, scrollAnimator->currentOffset().height()); reset(*scrollAnimator); }
std::shared_ptr<erizo::MockMediaStream> addMediaStream(bool is_publisher, uint32_t max_video_bw) { std::string id = std::to_string(index); std::string label = std::to_string(index); uint32_t video_sink_ssrc = getSsrcFromIndex(index); uint32_t audio_sink_ssrc = getSsrcFromIndex(index) + 1; uint32_t video_source_ssrc = getSsrcFromIndex(index) + 2; uint32_t audio_source_ssrc = getSsrcFromIndex(index) + 3; auto media_stream = std::make_shared<erizo::MockMediaStream>(nullptr, nullptr, id, label, rtp_maps, is_publisher); media_stream->setVideoSinkSSRC(video_sink_ssrc); media_stream->setAudioSinkSSRC(audio_sink_ssrc); media_stream->setVideoSourceSSRC(video_source_ssrc); media_stream->setAudioSourceSSRC(audio_source_ssrc); EXPECT_CALL(*media_stream, getMaxVideoBW()).Times(AtLeast(0)).WillRepeatedly(Return(max_video_bw)); index++; return media_stream; }
// Test that a smooth scroll offset animation is aborted when followed by a // non-smooth scroll offset animation. TEST(ScrollAnimatorTest, AnimatedScrollAborted) { MockScrollableArea* scrollableArea = MockScrollableArea::create( true, ScrollOffset(), ScrollOffset(1000, 1000)); ScrollAnimator* scrollAnimator = new ScrollAnimator(scrollableArea, getMockedTime); EXPECT_CALL(*scrollableArea, updateScrollOffset(_, _)).Times(3); EXPECT_CALL(*scrollableArea, registerForAnimation()).Times(2); EXPECT_CALL(*scrollableArea, scheduleAnimation()) .Times(AtLeast(1)) .WillRepeatedly(Return(true)); EXPECT_FALSE(scrollAnimator->hasAnimationThatRequiresService()); // Smooth scroll. ScrollResult result = scrollAnimator->userScroll(ScrollByLine, FloatSize(100, 0)); EXPECT_TRUE(scrollAnimator->hasAnimationThatRequiresService()); EXPECT_TRUE(result.didScrollX); EXPECT_FLOAT_EQ(0.0, result.unusedScrollDeltaX); EXPECT_TRUE(scrollAnimator->hasRunningAnimation()); gMockedTime += 0.05; scrollAnimator->updateCompositorAnimations(); scrollAnimator->tickAnimation(getMockedTime()); EXPECT_NE(100, scrollAnimator->currentOffset().width()); EXPECT_NE(0, scrollAnimator->currentOffset().width()); EXPECT_EQ(0, scrollAnimator->currentOffset().height()); float x = scrollAnimator->currentOffset().width(); // Instant scroll. result = scrollAnimator->userScroll(ScrollByPrecisePixel, FloatSize(100, 0)); EXPECT_TRUE(result.didScrollX); gMockedTime += 0.05; scrollAnimator->updateCompositorAnimations(); EXPECT_FALSE(scrollAnimator->hasRunningAnimation()); EXPECT_EQ(x + 100, scrollAnimator->currentOffset().width()); EXPECT_EQ(0, scrollAnimator->currentOffset().height()); reset(*scrollAnimator); }
TEST(ScrollAnimatorTest, Enabled) { OwnPtrWillBeRawPtr<MockScrollableArea> scrollableArea = MockScrollableArea::create(true); OwnPtr<ScrollAnimator> scrollAnimator = adoptPtr(new ScrollAnimator(scrollableArea.get(), getMockedTime)); EXPECT_CALL(*scrollableArea, minimumScrollPosition()).Times(AtLeast(1)).WillRepeatedly(Return(IntPoint())); EXPECT_CALL(*scrollableArea, maximumScrollPosition()).Times(AtLeast(1)).WillRepeatedly(Return(IntPoint(1000, 1000))); EXPECT_CALL(*scrollableArea, setScrollOffset(_, _)).Times(12); EXPECT_CALL(*scrollableArea, registerForAnimation()).Times(3); EXPECT_FALSE(scrollAnimator->hasRunningAnimation()); ScrollResultOneDimensional result = scrollAnimator->userScroll(HorizontalScrollbar, ScrollByLine, 100, -1); EXPECT_FALSE(scrollAnimator->hasRunningAnimation()); EXPECT_FALSE(result.didScroll); EXPECT_FLOAT_EQ(-100.0, result.unusedScrollDelta); result = scrollAnimator->userScroll(HorizontalScrollbar, ScrollByLine, 100, 1); EXPECT_TRUE(scrollAnimator->hasRunningAnimation()); EXPECT_TRUE(result.didScroll); EXPECT_FLOAT_EQ(0.0, result.unusedScrollDelta); gMockedTime += 0.05; scrollAnimator->serviceScrollAnimations(); EXPECT_NE(100, scrollAnimator->currentPosition().x()); EXPECT_NE(0, scrollAnimator->currentPosition().x()); EXPECT_EQ(0, scrollAnimator->currentPosition().y()); reset(*scrollAnimator); scrollAnimator->userScroll(HorizontalScrollbar, ScrollByPage, 100, 1); EXPECT_TRUE(scrollAnimator->hasRunningAnimation()); gMockedTime += 0.05; scrollAnimator->serviceScrollAnimations(); EXPECT_NE(100, scrollAnimator->currentPosition().x()); EXPECT_NE(0, scrollAnimator->currentPosition().x()); EXPECT_EQ(0, scrollAnimator->currentPosition().y()); reset(*scrollAnimator); scrollAnimator->userScroll(HorizontalScrollbar, ScrollByPixel, 4, 25); EXPECT_TRUE(scrollAnimator->hasRunningAnimation()); gMockedTime += 0.05; scrollAnimator->serviceScrollAnimations(); EXPECT_NE(100, scrollAnimator->currentPosition().x()); EXPECT_NE(0, scrollAnimator->currentPosition().x()); EXPECT_EQ(0, scrollAnimator->currentPosition().y()); gMockedTime += 1.0; scrollAnimator->serviceScrollAnimations(); EXPECT_FALSE(scrollAnimator->hasRunningAnimation()); EXPECT_EQ(100, scrollAnimator->currentPosition().x()); reset(*scrollAnimator); scrollAnimator->userScroll(HorizontalScrollbar, ScrollByPrecisePixel, 4, 25); EXPECT_FALSE(scrollAnimator->hasRunningAnimation()); EXPECT_EQ(100, scrollAnimator->currentPosition().x()); EXPECT_NE(0, scrollAnimator->currentPosition().x()); EXPECT_EQ(0, scrollAnimator->currentPosition().y()); reset(*scrollAnimator); }
// Test the behavior when in WaitingToCancelOnCompositor and a new user scroll // happens. TEST(ScrollAnimatorTest, CancellingCompositorAnimation) { MockScrollableArea* scrollableArea = MockScrollableArea::create( true, ScrollOffset(), ScrollOffset(1000, 1000)); TestScrollAnimator* scrollAnimator = new TestScrollAnimator(scrollableArea, getMockedTime); // Called when reset, not setting anywhere else. EXPECT_CALL(*scrollableArea, updateScrollOffset(_, _)).Times(1); // Called from userScroll, and first update. EXPECT_CALL(*scrollableArea, registerForAnimation()).Times(4); EXPECT_CALL(*scrollableArea, scheduleAnimation()) .Times(AtLeast(1)) .WillRepeatedly(Return(true)); EXPECT_FALSE(scrollAnimator->hasAnimationThatRequiresService()); // First user scroll. ScrollResult result = scrollAnimator->userScroll(ScrollByLine, FloatSize(100, 0)); EXPECT_TRUE(scrollAnimator->hasAnimationThatRequiresService()); EXPECT_TRUE(result.didScrollX); EXPECT_FLOAT_EQ(0.0, result.unusedScrollDeltaX); EXPECT_TRUE(scrollAnimator->hasRunningAnimation()); EXPECT_EQ(100, scrollAnimator->desiredTargetOffset().width()); EXPECT_EQ(0, scrollAnimator->desiredTargetOffset().height()); // Update compositor animation. gMockedTime += 0.05; scrollAnimator->setShouldSendToCompositor(true); scrollAnimator->updateCompositorAnimations(); EXPECT_EQ(scrollAnimator->m_runState, ScrollAnimatorCompositorCoordinator::RunState::RunningOnCompositor); // Cancel scrollAnimator->cancelAnimation(); EXPECT_EQ(scrollAnimator->m_runState, ScrollAnimatorCompositorCoordinator::RunState:: WaitingToCancelOnCompositor); // Unrelated scroll offset update. scrollAnimator->setCurrentOffset(ScrollOffset(50, 0)); // Desired target offset should be that of the second scroll. result = scrollAnimator->userScroll(ScrollByLine, FloatSize(100, 0)); EXPECT_TRUE(scrollAnimator->hasAnimationThatRequiresService()); EXPECT_TRUE(result.didScrollX); EXPECT_FLOAT_EQ(0.0, result.unusedScrollDeltaX); EXPECT_EQ(scrollAnimator->m_runState, ScrollAnimatorCompositorCoordinator::RunState:: WaitingToCancelOnCompositorButNewScroll); EXPECT_EQ(150, scrollAnimator->desiredTargetOffset().width()); EXPECT_EQ(0, scrollAnimator->desiredTargetOffset().height()); // Update compositor animation. gMockedTime += 0.05; scrollAnimator->updateCompositorAnimations(); EXPECT_EQ(scrollAnimator->m_runState, ScrollAnimatorCompositorCoordinator::RunState::RunningOnCompositor); // Third user scroll after compositor update updates the target. result = scrollAnimator->userScroll(ScrollByLine, FloatSize(100, 0)); EXPECT_TRUE(scrollAnimator->hasAnimationThatRequiresService()); EXPECT_TRUE(result.didScrollX); EXPECT_FLOAT_EQ(0.0, result.unusedScrollDeltaX); EXPECT_EQ(scrollAnimator->m_runState, ScrollAnimatorCompositorCoordinator::RunState:: RunningOnCompositorButNeedsUpdate); EXPECT_EQ(250, scrollAnimator->desiredTargetOffset().width()); EXPECT_EQ(0, scrollAnimator->desiredTargetOffset().height()); reset(*scrollAnimator); // Forced GC in order to finalize objects depending on the mock object. ThreadState::current()->collectAllGarbage(); }