/*
 * Copyright (C) 2010 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

// Tests for the ScrollAnimator class.

#include "third_party/blink/renderer/core/scroll/scroll_animator.h"

#include "base/single_thread_task_runner.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
#include "third_party/blink/renderer/core/scroll/scroll_animator_base.h"
#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/platform/geometry/float_point.h"
#include "third_party/blink/renderer/platform/geometry/int_rect.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"

namespace blink {

using testing::AtLeast;
using testing::Return;
using testing::_;

static double g_mocked_time = 0.0;

static double GetMockedTime() {
  return g_mocked_time;
}

namespace {

class MockScrollableAreaForAnimatorTest
    : public GarbageCollectedFinalized<MockScrollableAreaForAnimatorTest>,
      public ScrollableArea {
  USING_GARBAGE_COLLECTED_MIXIN(MockScrollableAreaForAnimatorTest);

 public:
  static MockScrollableAreaForAnimatorTest* Create(
      bool scroll_animator_enabled,
      const ScrollOffset& min_offset,
      const ScrollOffset& max_offset) {
    return MakeGarbageCollected<MockScrollableAreaForAnimatorTest>(
        scroll_animator_enabled, min_offset, max_offset);
  }

  explicit MockScrollableAreaForAnimatorTest(bool scroll_animator_enabled,
                                             const ScrollOffset& min_offset,
                                             const ScrollOffset& max_offset)
      : scroll_animator_enabled_(scroll_animator_enabled),
        min_offset_(min_offset),
        max_offset_(max_offset) {}

  MOCK_CONST_METHOD0(VisualRectForScrollbarParts, LayoutRect());
  MOCK_CONST_METHOD0(IsActive, bool());
  MOCK_CONST_METHOD0(IsThrottled, bool());
  MOCK_CONST_METHOD1(ScrollSize, int(ScrollbarOrientation));
  MOCK_CONST_METHOD0(IsScrollCornerVisible, bool());
  MOCK_CONST_METHOD0(ScrollCornerRect, IntRect());
  MOCK_METHOD2(UpdateScrollOffset, void(const ScrollOffset&, ScrollType));
  MOCK_METHOD0(ScrollControlWasSetNeedsPaintInvalidation, void());
  MOCK_CONST_METHOD0(EnclosingScrollableArea, ScrollableArea*());
  MOCK_CONST_METHOD1(VisibleContentRect, IntRect(IncludeScrollbarsInRect));
  MOCK_CONST_METHOD0(ContentsSize, IntSize());
  MOCK_CONST_METHOD0(ScrollbarsCanBeActive, bool());
  MOCK_CONST_METHOD0(ScrollableAreaBoundingBox, IntRect());
  MOCK_METHOD0(RegisterForAnimation, void());
  MOCK_METHOD0(ScheduleAnimation, bool());

  bool UserInputScrollable(ScrollbarOrientation) const override { return true; }
  bool ShouldPlaceVerticalScrollbarOnLeft() const override { return false; }
  IntSize ScrollOffsetInt() const override { return IntSize(); }
  int VisibleHeight() const override { return 768; }
  int VisibleWidth() const override { return 1024; }
  CompositorElementId GetCompositorElementId() const override {
    return CompositorElementId();
  }
  bool ScrollAnimatorEnabled() const override {
    return scroll_animator_enabled_;
  }
  int PageStep(ScrollbarOrientation) const override { return 0; }
  IntSize MinimumScrollOffsetInt() const override {
    return FlooredIntSize(min_offset_);
  }
  IntSize MaximumScrollOffsetInt() const override {
    return FlooredIntSize(max_offset_);
  }

  void SetScrollAnimator(ScrollAnimator* scroll_animator) {
    animator = scroll_animator;
  }

  ScrollOffset GetScrollOffset() const override {
    if (animator)
      return animator->CurrentOffset();
    return ScrollableArea::GetScrollOffset();
  }

  void SetScrollOffset(
      const ScrollOffset& offset,
      ScrollType type,
      ScrollBehavior behavior = kScrollBehaviorInstant) override {
    if (animator)
      animator->SetCurrentOffset(offset);
    ScrollableArea::SetScrollOffset(offset, type, behavior);
  }

  scoped_refptr<base::SingleThreadTaskRunner> GetTimerTaskRunner() const final {
    if (!timer_task_runner_) {
      timer_task_runner_ =
          blink::scheduler::GetSingleThreadTaskRunnerForTesting();
    }
    return timer_task_runner_;
  }

  ScrollbarTheme& GetPageScrollbarTheme() const override {
    return ScrollbarTheme::DeprecatedStaticGetTheme();
  }

  void Trace(blink::Visitor* visitor) override {
    visitor->Trace(animator);
    ScrollableArea::Trace(visitor);
  }

 private:
  bool scroll_animator_enabled_;
  ScrollOffset min_offset_;
  ScrollOffset max_offset_;
  Member<ScrollAnimator> animator;
  mutable scoped_refptr<base::SingleThreadTaskRunner> timer_task_runner_;
};

class TestScrollAnimator : public ScrollAnimator {
 public:
  TestScrollAnimator(ScrollableArea* scrollable_area,
                     WTF::TimeFunction timing_function)
      : ScrollAnimator(scrollable_area, timing_function) {}
  ~TestScrollAnimator() override = default;

  void SetShouldSendToCompositor(bool send) {
    should_send_to_compositor_ = send;
  }

  bool SendAnimationToCompositor() override {
    if (should_send_to_compositor_) {
      run_state_ =
          ScrollAnimatorCompositorCoordinator::RunState::kRunningOnCompositor;
      compositor_animation_id_ = 1;
      return true;
    }
    return false;
  }

 protected:
  void AbortAnimation() override {}

 private:
  bool should_send_to_compositor_ = false;
};

}  // namespace

static void Reset(ScrollAnimator& scroll_animator) {
  scroll_animator.ScrollToOffsetWithoutAnimation(ScrollOffset());
}

// TODO(skobes): Add unit tests for composited scrolling paths.

TEST(ScrollAnimatorTest, MainThreadStates) {
  MockScrollableAreaForAnimatorTest* scrollable_area =
      MockScrollableAreaForAnimatorTest::Create(true, ScrollOffset(),
                                                ScrollOffset(1000, 1000));
  ScrollAnimator* scroll_animator =
      MakeGarbageCollected<ScrollAnimator>(scrollable_area, GetMockedTime);

  EXPECT_CALL(*scrollable_area, UpdateScrollOffset(_, _)).Times(2);
  // Once from userScroll, once from updateCompositorAnimations.
  EXPECT_CALL(*scrollable_area, RegisterForAnimation()).Times(2);
  EXPECT_CALL(*scrollable_area, ScheduleAnimation())
      .Times(AtLeast(1))
      .WillRepeatedly(Return(true));

  // Idle
  EXPECT_FALSE(scroll_animator->HasAnimationThatRequiresService());
  EXPECT_EQ(scroll_animator->run_state_,
            ScrollAnimatorCompositorCoordinator::RunState::kIdle);

  // WaitingToSendToCompositor
  scroll_animator->UserScroll(kScrollByLine, FloatSize(10, 0));
  EXPECT_EQ(scroll_animator->run_state_,
            ScrollAnimatorCompositorCoordinator::RunState::
                kWaitingToSendToCompositor);

  // RunningOnMainThread
  g_mocked_time += 0.05;
  scroll_animator->UpdateCompositorAnimations();
  EXPECT_EQ(
      scroll_animator->run_state_,
      ScrollAnimatorCompositorCoordinator::RunState::kRunningOnMainThread);
  scroll_animator->TickAnimation(GetMockedTime());
  EXPECT_EQ(
      scroll_animator->run_state_,
      ScrollAnimatorCompositorCoordinator::RunState::kRunningOnMainThread);

  // PostAnimationCleanup
  scroll_animator->CancelAnimation();
  EXPECT_EQ(
      scroll_animator->run_state_,
      ScrollAnimatorCompositorCoordinator::RunState::kPostAnimationCleanup);

  // Idle
  scroll_animator->UpdateCompositorAnimations();
  scroll_animator->TickAnimation(GetMockedTime());
  EXPECT_EQ(scroll_animator->run_state_,
            ScrollAnimatorCompositorCoordinator::RunState::kIdle);

  Reset(*scroll_animator);

  // Forced GC in order to finalize objects depending on the mock object.
  ThreadState::Current()->CollectAllGarbage();
}

TEST(ScrollAnimatorTest, MainThreadEnabled) {
  MockScrollableAreaForAnimatorTest* scrollable_area =
      MockScrollableAreaForAnimatorTest::Create(true, ScrollOffset(),
                                                ScrollOffset(1000, 1000));
  ScrollAnimator* scroll_animator =
      MakeGarbageCollected<ScrollAnimator>(scrollable_area, GetMockedTime);

  EXPECT_CALL(*scrollable_area, UpdateScrollOffset(_, _)).Times(9);
  EXPECT_CALL(*scrollable_area, RegisterForAnimation()).Times(6);
  EXPECT_CALL(*scrollable_area, ScheduleAnimation())
      .Times(AtLeast(1))
      .WillRepeatedly(Return(true));

  EXPECT_FALSE(scroll_animator->HasAnimationThatRequiresService());

  ScrollResult result =
      scroll_animator->UserScroll(kScrollByLine, FloatSize(-100, 0));
  EXPECT_FALSE(scroll_animator->HasAnimationThatRequiresService());
  EXPECT_FALSE(result.did_scroll_x);
  EXPECT_FLOAT_EQ(-100.0f, result.unused_scroll_delta_x);

  result = scroll_animator->UserScroll(kScrollByLine, FloatSize(100, 0));
  EXPECT_TRUE(scroll_animator->HasAnimationThatRequiresService());
  EXPECT_TRUE(result.did_scroll_x);
  EXPECT_FLOAT_EQ(0.0, result.unused_scroll_delta_x);

  g_mocked_time += 0.05;
  scroll_animator->UpdateCompositorAnimations();
  scroll_animator->TickAnimation(GetMockedTime());

  EXPECT_NE(100, scroll_animator->CurrentOffset().Width());
  EXPECT_NE(0, scroll_animator->CurrentOffset().Width());
  EXPECT_EQ(0, scroll_animator->CurrentOffset().Height());
  Reset(*scroll_animator);

  scroll_animator->UserScroll(kScrollByPage, FloatSize(100, 0));
  EXPECT_TRUE(scroll_animator->HasAnimationThatRequiresService());

  g_mocked_time += 0.05;
  scroll_animator->UpdateCompositorAnimations();
  scroll_animator->TickAnimation(GetMockedTime());

  EXPECT_NE(100, scroll_animator->CurrentOffset().Width());
  EXPECT_NE(0, scroll_animator->CurrentOffset().Width());
  EXPECT_EQ(0, scroll_animator->CurrentOffset().Height());
  Reset(*scroll_animator);

  scroll_animator->UserScroll(kScrollByPixel, FloatSize(100, 0));
  EXPECT_TRUE(scroll_animator->HasAnimationThatRequiresService());

  g_mocked_time += 0.05;
  scroll_animator->UpdateCompositorAnimations();
  scroll_animator->TickAnimation(GetMockedTime());

  EXPECT_NE(100, scroll_animator->CurrentOffset().Width());
  EXPECT_NE(0, scroll_animator->CurrentOffset().Width());
  EXPECT_EQ(0, scroll_animator->CurrentOffset().Height());

  g_mocked_time += 1.0;
  scroll_animator->UpdateCompositorAnimations();
  scroll_animator->TickAnimation(GetMockedTime());

  g_mocked_time += 0.05;
  scroll_animator->UpdateCompositorAnimations();
  EXPECT_FALSE(scroll_animator->HasAnimationThatRequiresService());
  EXPECT_EQ(100, scroll_animator->CurrentOffset().Width());

  Reset(*scroll_animator);

  scroll_animator->UserScroll(kScrollByPrecisePixel, FloatSize(100, 0));
  EXPECT_FALSE(scroll_animator->HasAnimationThatRequiresService());

  EXPECT_EQ(100, scroll_animator->CurrentOffset().Width());
  EXPECT_NE(0, scroll_animator->CurrentOffset().Width());
  EXPECT_EQ(0, scroll_animator->CurrentOffset().Height());
  Reset(*scroll_animator);
}

// Test that a smooth scroll offset animation is aborted when followed by a
// non-smooth scroll offset animation.
TEST(ScrollAnimatorTest, AnimatedScrollAborted) {
  MockScrollableAreaForAnimatorTest* scrollable_area =
      MockScrollableAreaForAnimatorTest::Create(true, ScrollOffset(),
                                                ScrollOffset(1000, 1000));
  ScrollAnimator* scroll_animator =
      MakeGarbageCollected<ScrollAnimator>(scrollable_area, GetMockedTime);

  EXPECT_CALL(*scrollable_area, UpdateScrollOffset(_, _)).Times(3);
  EXPECT_CALL(*scrollable_area, RegisterForAnimation()).Times(2);
  EXPECT_CALL(*scrollable_area, ScheduleAnimation())
      .Times(AtLeast(1))
      .WillRepeatedly(Return(true));

  EXPECT_FALSE(scroll_animator->HasAnimationThatRequiresService());

  // Smooth scroll.
  ScrollResult result =
      scroll_animator->UserScroll(kScrollByLine, FloatSize(100, 0));
  EXPECT_TRUE(scroll_animator->HasAnimationThatRequiresService());
  EXPECT_TRUE(result.did_scroll_x);
  EXPECT_FLOAT_EQ(0.0, result.unused_scroll_delta_x);
  EXPECT_TRUE(scroll_animator->HasRunningAnimation());

  g_mocked_time += 0.05;
  scroll_animator->UpdateCompositorAnimations();
  scroll_animator->TickAnimation(GetMockedTime());

  EXPECT_NE(100, scroll_animator->CurrentOffset().Width());
  EXPECT_NE(0, scroll_animator->CurrentOffset().Width());
  EXPECT_EQ(0, scroll_animator->CurrentOffset().Height());

  float x = scroll_animator->CurrentOffset().Width();

  // Instant scroll.
  result =
      scroll_animator->UserScroll(kScrollByPrecisePixel, FloatSize(100, 0));
  EXPECT_TRUE(result.did_scroll_x);
  g_mocked_time += 0.05;
  scroll_animator->UpdateCompositorAnimations();
  EXPECT_FALSE(scroll_animator->HasRunningAnimation());
  EXPECT_EQ(x + 100, scroll_animator->CurrentOffset().Width());
  EXPECT_EQ(0, scroll_animator->CurrentOffset().Height());

  Reset(*scroll_animator);
}

// Test that a smooth scroll offset animation running on the compositor is
// completed on the main thread.
TEST(ScrollAnimatorTest, AnimatedScrollTakeover) {
  MockScrollableAreaForAnimatorTest* scrollable_area =
      MockScrollableAreaForAnimatorTest::Create(true, ScrollOffset(),
                                                ScrollOffset(1000, 1000));
  TestScrollAnimator* scroll_animator =
      MakeGarbageCollected<TestScrollAnimator>(scrollable_area, GetMockedTime);

  EXPECT_CALL(*scrollable_area, UpdateScrollOffset(_, _)).Times(2);
  // Called from userScroll, updateCompositorAnimations, then
  // takeOverCompositorAnimation (to re-register after RunningOnCompositor).
  EXPECT_CALL(*scrollable_area, RegisterForAnimation()).Times(3);
  EXPECT_CALL(*scrollable_area, ScheduleAnimation())
      .Times(AtLeast(1))
      .WillRepeatedly(Return(true));

  EXPECT_FALSE(scroll_animator->HasAnimationThatRequiresService());

  // Smooth scroll.
  ScrollResult result =
      scroll_animator->UserScroll(kScrollByLine, FloatSize(100, 0));
  EXPECT_TRUE(scroll_animator->HasAnimationThatRequiresService());
  EXPECT_TRUE(result.did_scroll_x);
  EXPECT_FLOAT_EQ(0.0, result.unused_scroll_delta_x);
  EXPECT_TRUE(scroll_animator->HasRunningAnimation());

  // Update compositor animation.
  g_mocked_time += 0.05;
  scroll_animator->SetShouldSendToCompositor(true);
  scroll_animator->UpdateCompositorAnimations();
  EXPECT_EQ(
      scroll_animator->run_state_,
      ScrollAnimatorCompositorCoordinator::RunState::kRunningOnCompositor);

  // Takeover.
  scroll_animator->TakeOverCompositorAnimation();
  EXPECT_EQ(scroll_animator->run_state_,
            ScrollAnimatorCompositorCoordinator::RunState::
                kRunningOnCompositorButNeedsTakeover);

  // Animation should now be running on the main thread.
  scroll_animator->SetShouldSendToCompositor(false);
  scroll_animator->UpdateCompositorAnimations();
  EXPECT_EQ(
      scroll_animator->run_state_,
      ScrollAnimatorCompositorCoordinator::RunState::kRunningOnMainThread);
  scroll_animator->TickAnimation(GetMockedTime());
  EXPECT_NE(100, scroll_animator->CurrentOffset().Width());
  EXPECT_NE(0, scroll_animator->CurrentOffset().Width());
  EXPECT_EQ(0, scroll_animator->CurrentOffset().Height());
  Reset(*scroll_animator);
}

TEST(ScrollAnimatorTest, Disabled) {
  MockScrollableAreaForAnimatorTest* scrollable_area =
      MockScrollableAreaForAnimatorTest::Create(false, ScrollOffset(),
                                                ScrollOffset(1000, 1000));
  ScrollAnimator* scroll_animator =
      MakeGarbageCollected<ScrollAnimator>(scrollable_area, GetMockedTime);

  EXPECT_CALL(*scrollable_area, UpdateScrollOffset(_, _)).Times(8);
  EXPECT_CALL(*scrollable_area, RegisterForAnimation()).Times(0);

  scroll_animator->UserScroll(kScrollByLine, FloatSize(100, 0));
  EXPECT_EQ(100, scroll_animator->CurrentOffset().Width());
  EXPECT_EQ(0, scroll_animator->CurrentOffset().Height());
  Reset(*scroll_animator);

  scroll_animator->UserScroll(kScrollByPage, FloatSize(100, 0));
  EXPECT_EQ(100, scroll_animator->CurrentOffset().Width());
  EXPECT_EQ(0, scroll_animator->CurrentOffset().Height());
  Reset(*scroll_animator);

  scroll_animator->UserScroll(kScrollByDocument, FloatSize(100, 0));
  EXPECT_EQ(100, scroll_animator->CurrentOffset().Width());
  EXPECT_EQ(0, scroll_animator->CurrentOffset().Height());
  Reset(*scroll_animator);

  scroll_animator->UserScroll(kScrollByPixel, FloatSize(100, 0));
  EXPECT_EQ(100, scroll_animator->CurrentOffset().Width());
  EXPECT_EQ(0, scroll_animator->CurrentOffset().Height());
  Reset(*scroll_animator);
}

// Test that cancelling an animation resets the animation state.
// See crbug.com/598548.
TEST(ScrollAnimatorTest, CancellingAnimationResetsState) {
  MockScrollableAreaForAnimatorTest* scrollable_area =
      MockScrollableAreaForAnimatorTest::Create(true, ScrollOffset(),
                                                ScrollOffset(1000, 1000));
  ScrollAnimator* scroll_animator =
      MakeGarbageCollected<ScrollAnimator>(scrollable_area, GetMockedTime);

  // Called from first userScroll, setCurrentOffset, and second userScroll.
  EXPECT_CALL(*scrollable_area, UpdateScrollOffset(_, _)).Times(3);
  // Called from userScroll, updateCompositorAnimations.
  EXPECT_CALL(*scrollable_area, RegisterForAnimation()).Times(4);
  EXPECT_CALL(*scrollable_area, ScheduleAnimation())
      .Times(AtLeast(1))
      .WillRepeatedly(Return(true));

  EXPECT_EQ(0, scroll_animator->CurrentOffset().Width());
  EXPECT_EQ(0, scroll_animator->CurrentOffset().Height());

  // WaitingToSendToCompositor
  scroll_animator->UserScroll(kScrollByLine, FloatSize(10, 0));
  EXPECT_EQ(scroll_animator->run_state_,
            ScrollAnimatorCompositorCoordinator::RunState::
                kWaitingToSendToCompositor);

  // RunningOnMainThread
  g_mocked_time += 0.05;
  scroll_animator->UpdateCompositorAnimations();
  EXPECT_EQ(
      scroll_animator->run_state_,
      ScrollAnimatorCompositorCoordinator::RunState::kRunningOnMainThread);
  scroll_animator->TickAnimation(GetMockedTime());
  EXPECT_EQ(
      scroll_animator->run_state_,
      ScrollAnimatorCompositorCoordinator::RunState::kRunningOnMainThread);

  // Amount scrolled so far.
  float offset_x = scroll_animator->CurrentOffset().Width();

  // Interrupt user scroll.
  scroll_animator->CancelAnimation();
  EXPECT_EQ(
      scroll_animator->run_state_,
      ScrollAnimatorCompositorCoordinator::RunState::kPostAnimationCleanup);

  // Another userScroll after modified scroll offset.
  scroll_animator->SetCurrentOffset(ScrollOffset(offset_x + 15, 0));
  scroll_animator->UserScroll(kScrollByLine, FloatSize(10, 0));
  EXPECT_EQ(scroll_animator->run_state_,
            ScrollAnimatorCompositorCoordinator::RunState::
                kWaitingToSendToCompositor);

  // Finish scroll animation.
  g_mocked_time += 1.0;
  scroll_animator->UpdateCompositorAnimations();
  scroll_animator->TickAnimation(GetMockedTime());
  EXPECT_EQ(
      scroll_animator->run_state_,
      ScrollAnimatorCompositorCoordinator::RunState::kPostAnimationCleanup);

  EXPECT_EQ(offset_x + 15 + 10, scroll_animator->CurrentOffset().Width());
  EXPECT_EQ(0, scroll_animator->CurrentOffset().Height());
  Reset(*scroll_animator);
}

// Test the behavior when in WaitingToCancelOnCompositor and a new user scroll
// happens.
TEST(ScrollAnimatorTest, CancellingCompositorAnimation) {
  MockScrollableAreaForAnimatorTest* scrollable_area =
      MockScrollableAreaForAnimatorTest::Create(true, ScrollOffset(),
                                                ScrollOffset(1000, 1000));
  TestScrollAnimator* scroll_animator =
      MakeGarbageCollected<TestScrollAnimator>(scrollable_area, GetMockedTime);

  // Called when reset, not setting anywhere else.
  EXPECT_CALL(*scrollable_area, UpdateScrollOffset(_, _)).Times(1);
  // Called from userScroll, and first update.
  EXPECT_CALL(*scrollable_area, RegisterForAnimation()).Times(4);
  EXPECT_CALL(*scrollable_area, ScheduleAnimation())
      .Times(AtLeast(1))
      .WillRepeatedly(Return(true));

  EXPECT_FALSE(scroll_animator->HasAnimationThatRequiresService());

  // First user scroll.
  ScrollResult result =
      scroll_animator->UserScroll(kScrollByLine, FloatSize(100, 0));
  EXPECT_TRUE(scroll_animator->HasAnimationThatRequiresService());
  EXPECT_TRUE(result.did_scroll_x);
  EXPECT_FLOAT_EQ(0.0, result.unused_scroll_delta_x);
  EXPECT_TRUE(scroll_animator->HasRunningAnimation());
  EXPECT_EQ(100, scroll_animator->DesiredTargetOffset().Width());
  EXPECT_EQ(0, scroll_animator->DesiredTargetOffset().Height());

  // Update compositor animation.
  g_mocked_time += 0.05;
  scroll_animator->SetShouldSendToCompositor(true);
  scroll_animator->UpdateCompositorAnimations();
  EXPECT_EQ(
      scroll_animator->run_state_,
      ScrollAnimatorCompositorCoordinator::RunState::kRunningOnCompositor);

  // Cancel
  scroll_animator->CancelAnimation();
  EXPECT_EQ(scroll_animator->run_state_,
            ScrollAnimatorCompositorCoordinator::RunState::
                kWaitingToCancelOnCompositor);

  // Unrelated scroll offset update.
  scroll_animator->SetCurrentOffset(ScrollOffset(50, 0));

  // Desired target offset should be that of the second scroll.
  result = scroll_animator->UserScroll(kScrollByLine, FloatSize(100, 0));
  EXPECT_TRUE(scroll_animator->HasAnimationThatRequiresService());
  EXPECT_TRUE(result.did_scroll_x);
  EXPECT_FLOAT_EQ(0.0, result.unused_scroll_delta_x);
  EXPECT_EQ(scroll_animator->run_state_,
            ScrollAnimatorCompositorCoordinator::RunState::
                kWaitingToCancelOnCompositorButNewScroll);
  EXPECT_EQ(150, scroll_animator->DesiredTargetOffset().Width());
  EXPECT_EQ(0, scroll_animator->DesiredTargetOffset().Height());

  // Update compositor animation.
  g_mocked_time += 0.05;
  scroll_animator->UpdateCompositorAnimations();
  EXPECT_EQ(
      scroll_animator->run_state_,
      ScrollAnimatorCompositorCoordinator::RunState::kRunningOnCompositor);

  // Third user scroll after compositor update updates the target.
  result = scroll_animator->UserScroll(kScrollByLine, FloatSize(100, 0));
  EXPECT_TRUE(scroll_animator->HasAnimationThatRequiresService());
  EXPECT_TRUE(result.did_scroll_x);
  EXPECT_FLOAT_EQ(0.0, result.unused_scroll_delta_x);
  EXPECT_EQ(scroll_animator->run_state_,
            ScrollAnimatorCompositorCoordinator::RunState::
                kRunningOnCompositorButNeedsUpdate);
  EXPECT_EQ(250, scroll_animator->DesiredTargetOffset().Width());
  EXPECT_EQ(0, scroll_animator->DesiredTargetOffset().Height());
  Reset(*scroll_animator);

  // Forced GC in order to finalize objects depending on the mock object.
  ThreadState::Current()->CollectAllGarbage();
}

// This test verifies that impl only animation updates get cleared once they
// are pushed to compositor animation host.
TEST(ScrollAnimatorTest, ImplOnlyAnimationUpdatesCleared) {
  MockScrollableAreaForAnimatorTest* scrollable_area =
      MockScrollableAreaForAnimatorTest::Create(true, ScrollOffset(),
                                                ScrollOffset(1000, 1000));
  TestScrollAnimator* animator =
      MakeGarbageCollected<TestScrollAnimator>(scrollable_area, GetMockedTime);

  // From calls to adjust/takeoverImplOnlyScrollOffsetAnimation.
  EXPECT_CALL(*scrollable_area, RegisterForAnimation()).Times(3);

  // Verify that the adjustment update is cleared.
  EXPECT_EQ(animator->run_state_,
            ScrollAnimatorCompositorCoordinator::RunState::kIdle);
  EXPECT_FALSE(animator->HasAnimationThatRequiresService());
  EXPECT_TRUE(animator->ImplOnlyAnimationAdjustmentForTesting().IsZero());

  animator->AdjustImplOnlyScrollOffsetAnimation(IntSize(100, 100));
  animator->AdjustImplOnlyScrollOffsetAnimation(IntSize(10, -10));

  EXPECT_TRUE(animator->HasAnimationThatRequiresService());
  EXPECT_EQ(IntSize(110, 90),
            animator->ImplOnlyAnimationAdjustmentForTesting());

  animator->UpdateCompositorAnimations();

  EXPECT_EQ(animator->run_state_,
            ScrollAnimatorCompositorCoordinator::RunState::kIdle);
  EXPECT_FALSE(animator->HasAnimationThatRequiresService());
  EXPECT_TRUE(animator->ImplOnlyAnimationAdjustmentForTesting().IsZero());

  // Verify that the takeover update is cleared.
  animator->TakeOverImplOnlyScrollOffsetAnimation();
  EXPECT_FALSE(animator->HasAnimationThatRequiresService());

  // Forced GC in order to finalize objects depending on the mock object.
  ThreadState::Current()->CollectAllGarbage();
}

TEST(ScrollAnimatorTest, MainThreadAnimationTargetAdjustment) {
  MockScrollableAreaForAnimatorTest* scrollable_area =
      MockScrollableAreaForAnimatorTest::Create(true, ScrollOffset(-100, -100),
                                                ScrollOffset(1000, 1000));
  ScrollAnimator* animator =
      MakeGarbageCollected<ScrollAnimator>(scrollable_area, GetMockedTime);
  scrollable_area->SetScrollAnimator(animator);

  // Twice from tickAnimation, once from reset, and twice from
  // adjustAnimationAndSetScrollOffset.
  EXPECT_CALL(*scrollable_area, UpdateScrollOffset(_, _)).Times(5);
  // One from call to userScroll and one from updateCompositorAnimations.
  EXPECT_CALL(*scrollable_area, RegisterForAnimation()).Times(2);
  EXPECT_CALL(*scrollable_area, ScheduleAnimation())
      .Times(AtLeast(1))
      .WillRepeatedly(Return(true));

  // Idle
  EXPECT_FALSE(animator->HasAnimationThatRequiresService());
  EXPECT_EQ(ScrollOffset(), animator->CurrentOffset());

  // WaitingToSendToCompositor
  animator->UserScroll(kScrollByLine, ScrollOffset(100, 100));

  // RunningOnMainThread
  g_mocked_time += 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 new_offset = offset + ScrollOffset(10, -10);
  animator->AdjustAnimationAndSetScrollOffset(new_offset, kAnchoringScroll);
  EXPECT_EQ(ScrollOffset(110, 90), animator->DesiredTargetOffset());

  // Adjusting after finished animation should do nothing.
  g_mocked_time += 1.0;
  animator->UpdateCompositorAnimations();
  animator->TickAnimation(GetMockedTime());
  EXPECT_EQ(
      animator->RunStateForTesting(),
      ScrollAnimatorCompositorCoordinator::RunState::kPostAnimationCleanup);
  new_offset = animator->CurrentOffset() + ScrollOffset(10, -10);
  animator->AdjustAnimationAndSetScrollOffset(new_offset, kAnchoringScroll);
  EXPECT_EQ(
      animator->RunStateForTesting(),
      ScrollAnimatorCompositorCoordinator::RunState::kPostAnimationCleanup);
  EXPECT_EQ(ScrollOffset(110, 90), animator->DesiredTargetOffset());

  Reset(*animator);

  // Forced GC in order to finalize objects depending on the mock object.
  ThreadState::Current()->CollectAllGarbage();
}

}  // namespace blink
