TEST_F(AnimationAnimationTimelineTest, EmptyKeyframeAnimation)
{
    AnimatableValueKeyframeEffectModel* effect = AnimatableValueKeyframeEffectModel::create(AnimatableValueKeyframeVector());
    KeyframeEffect* keyframeEffect = KeyframeEffect::create(element.get(), effect, timing);

    timeline->play(keyframeEffect);

    updateClockAndService(0);
    EXPECT_FLOAT_EQ(0, timeline->currentTimeInternal());
    EXPECT_FALSE(keyframeEffect->isInEffect());

    updateClockAndService(100);
    EXPECT_FLOAT_EQ(100, timeline->currentTimeInternal());
}
TEST_F(AnimationDocumentTimelineTest, NumberOfActiveAnimations)
{
    Timing timingForwardFill;
    timingForwardFill.iterationDuration = 2;
    timingForwardFill.fillMode = Timing::FillModeForwards;

    Timing timingNoFill;
    timingNoFill.iterationDuration = 2;
    timingNoFill.fillMode = Timing::FillModeNone;

    Timing timingBackwardFillDelay;
    timingBackwardFillDelay.iterationDuration = 1;
    timingBackwardFillDelay.fillMode = Timing::FillModeBackwards;
    timingBackwardFillDelay.startDelay = 1;

    Timing timingNoFillDelay;
    timingNoFillDelay.iterationDuration = 1;
    timingNoFillDelay.fillMode = Timing::FillModeNone;
    timingNoFillDelay.startDelay = 1;

    Timing timingAutoFill;
    timingAutoFill.iterationDuration = 2;

    RefPtr<Animation> anim1 = Animation::create(element.get(), KeyframeEffectModel::create(KeyframeEffectModel::KeyframeVector()), timingForwardFill);
    RefPtr<Animation> anim2 = Animation::create(element.get(), KeyframeEffectModel::create(KeyframeEffectModel::KeyframeVector()), timingNoFill);
    RefPtr<Animation> anim3 = Animation::create(element.get(), KeyframeEffectModel::create(KeyframeEffectModel::KeyframeVector()), timingBackwardFillDelay);
    RefPtr<Animation> anim4 = Animation::create(element.get(), KeyframeEffectModel::create(KeyframeEffectModel::KeyframeVector()), timingNoFillDelay);
    RefPtr<Animation> anim5 = Animation::create(element.get(), KeyframeEffectModel::create(KeyframeEffectModel::KeyframeVector()), timingAutoFill);

    timeline->play(anim1.get());
    timeline->play(anim2.get());
    timeline->play(anim3.get());
    timeline->play(anim4.get());
    timeline->play(anim5.get());

    platformTiming->expectNextFrameAction();
    updateClockAndService(0);
    EXPECT_EQ(5U, timeline->numberOfActiveAnimationsForTesting());
    platformTiming->expectNextFrameAction();
    updateClockAndService(0.5);
    EXPECT_EQ(5U, timeline->numberOfActiveAnimationsForTesting());
    platformTiming->expectNextFrameAction();
    updateClockAndService(1.5);
    EXPECT_EQ(5U, timeline->numberOfActiveAnimationsForTesting());
    platformTiming->expectNoMoreActions();
    updateClockAndService(3);
    EXPECT_EQ(1U, timeline->numberOfActiveAnimationsForTesting());
}
TEST_F(AnimationAnimationTimelineTest, EmptyKeyframeAnimation)
{
    RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(AnimatableValueKeyframeVector());
    RefPtrWillBeRawPtr<Animation> anim = Animation::create(element.get(), effect, timing);

    timeline->play(anim.get());

    platformTiming->expectNoMoreActions();
    updateClockAndService(0);
    EXPECT_FLOAT_EQ(0, timeline->currentTimeInternal());
    EXPECT_FALSE(anim->isInEffect());

    platformTiming->expectNoMoreActions();
    updateClockAndService(100);
    EXPECT_FLOAT_EQ(100, timeline->currentTimeInternal());
}
TEST_F(AnimationAnimationTimelineTest, EmptyForwardsKeyframeAnimation)
{
    AnimatableValueKeyframeEffectModel* effect = AnimatableValueKeyframeEffectModel::create(AnimatableValueKeyframeVector());
    timing.fillMode = Timing::FillModeForwards;
    KeyframeEffect* keyframeEffect = KeyframeEffect::create(element.get(), effect, timing);

    timeline->play(keyframeEffect);

    platformTiming->expectNoMoreActions();
    updateClockAndService(0);
    EXPECT_FLOAT_EQ(0, timeline->currentTimeInternal());
    EXPECT_TRUE(keyframeEffect->isInEffect());

    platformTiming->expectNoMoreActions();
    updateClockAndService(100);
    EXPECT_FLOAT_EQ(100, timeline->currentTimeInternal());
}
TEST_F(AnimationDocumentTimelineTest, EmptyForwardsKeyframeAnimation)
{
    RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(KeyframeEffectModel::KeyframeVector());
    timing.fillMode = Timing::FillModeForwards;
    RefPtr<Animation> anim = Animation::create(element.get(), effect, timing);

    timeline->play(anim.get());

    platformTiming->expectNoMoreActions();
    updateClockAndService(0);
    EXPECT_FLOAT_EQ(0, timeline->currentTime());
    EXPECT_TRUE(anim->isInEffect());
    EXPECT_TRUE(anim->compositableValues()->isEmpty());

    platformTiming->expectNoMoreActions();
    updateClockAndService(100);
    EXPECT_FLOAT_EQ(100, timeline->currentTime());
}
TEST_F(AnimationAnimationTimelineTest, DelayBeforeAnimationStart)
{
    timing.iterationDuration = 2;
    timing.startDelay = 5;

    KeyframeEffect* keyframeEffect = KeyframeEffect::create(element.get(), nullptr, timing);

    timeline->play(keyframeEffect);

    // TODO: Put the animation startTime in the future when we add the capability to change animation startTime
    EXPECT_CALL(*platformTiming, wakeAfter(timing.startDelay - minimumDelay()));
    updateClockAndService(0);

    EXPECT_CALL(*platformTiming, wakeAfter(timing.startDelay - minimumDelay() - 1.5));
    updateClockAndService(1.5);

    EXPECT_CALL(*platformTiming, serviceOnNextFrame());
    wake();

    EXPECT_CALL(*platformTiming, serviceOnNextFrame());
    updateClockAndService(4.98);
}
TEST_F(AnimationAnimationTimelineTest, DelayBeforeAnimationStart)
{
    timing.iterationDuration = 2;
    timing.startDelay = 5;

    RefPtrWillBeRawPtr<Animation> anim = Animation::create(element.get(), nullptr, timing);

    timeline->play(anim.get());

    // TODO: Put the player startTime in the future when we add the capability to change player startTime
    platformTiming->expectDelayedAction(timing.startDelay - minimumDelay());
    updateClockAndService(0);

    platformTiming->expectDelayedAction(timing.startDelay - minimumDelay() - 1.5);
    updateClockAndService(1.5);

    EXPECT_CALL(*platformTiming, serviceOnNextFrame());
    wake();

    platformTiming->expectNextFrameAction();
    updateClockAndService(4.98);
}