This source file includes following definitions.
- expectNoMoreActions
- expectNextFrameAction
- expectDelayedAction
- SetUp
- TearDown
- updateClockAndService
- wake
- minimumDelay
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include "config.h"
#include "core/animation/DocumentTimeline.h"
#include "core/animation/Animation.h"
#include "core/animation/AnimationClock.h"
#include "core/animation/KeyframeEffectModel.h"
#include "core/animation/TimedItem.h"
#include "core/dom/Document.h"
#include "core/dom/Element.h"
#include "core/dom/QualifiedName.h"
#include "platform/weborigin/KURL.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
namespace WebCore {
class MockPlatformTiming : public DocumentTimeline::PlatformTiming {
public:
MOCK_METHOD1(wakeAfter, void(double));
MOCK_METHOD0(cancelWake, void());
MOCK_METHOD0(serviceOnNextFrame, void());
void expectNoMoreActions()
{
EXPECT_CALL(*this, cancelWake());
}
void expectNextFrameAction()
{
::testing::Sequence sequence;
EXPECT_CALL(*this, cancelWake()).InSequence(sequence);
EXPECT_CALL(*this, serviceOnNextFrame()).InSequence(sequence);
}
void expectDelayedAction(double when)
{
::testing::Sequence sequence;
EXPECT_CALL(*this, cancelWake()).InSequence(sequence);
EXPECT_CALL(*this, wakeAfter(when)).InSequence(sequence);
}
};
class AnimationDocumentTimelineTest : public ::testing::Test {
protected:
virtual void SetUp()
{
document = Document::create();
document->animationClock().resetTimeForTesting();
element = Element::create(nullQName() , document.get());
platformTiming = new MockPlatformTiming;
timeline = DocumentTimeline::create(document.get(), adoptPtr(platformTiming));
timeline->setZeroTime(0);
ASSERT_EQ(0, timeline->currentTime());
}
virtual void TearDown()
{
timeline.release();
document.release();
element.release();
}
void updateClockAndService(double time)
{
document->animationClock().updateTime(time);
timeline->serviceAnimations(AnimationPlayer::UpdateForAnimationFrame);
}
RefPtr<Document> document;
RefPtr<Element> element;
RefPtr<DocumentTimeline> timeline;
Timing timing;
MockPlatformTiming* platformTiming;
void wake()
{
timeline->wake();
}
double minimumDelay()
{
return DocumentTimeline::s_minimumDelay;
}
};
TEST_F(AnimationDocumentTimelineTest, HasStarted)
{
timeline = DocumentTimeline::create(document.get());
EXPECT_FALSE(timeline->hasStarted());
timeline->setZeroTime(0);
EXPECT_TRUE(timeline->hasStarted());
}
TEST_F(AnimationDocumentTimelineTest, EmptyKeyframeAnimation)
{
RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(AnimatableValueKeyframeVector());
RefPtr<Animation> anim = Animation::create(element.get(), effect, timing);
timeline->play(anim.get());
platformTiming->expectNoMoreActions();
updateClockAndService(0);
EXPECT_FLOAT_EQ(0, timeline->currentTime());
EXPECT_FALSE(anim->isInEffect());
platformTiming->expectNoMoreActions();
updateClockAndService(100);
EXPECT_FLOAT_EQ(100, timeline->currentTime());
}
TEST_F(AnimationDocumentTimelineTest, EmptyForwardsKeyframeAnimation)
{
RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(AnimatableValueKeyframeVector());
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->activeInterpolations().isEmpty());
platformTiming->expectNoMoreActions();
updateClockAndService(100);
EXPECT_FLOAT_EQ(100, timeline->currentTime());
}
TEST_F(AnimationDocumentTimelineTest, ZeroTime)
{
timeline = DocumentTimeline::create(document.get());
bool isNull;
document->animationClock().updateTime(100);
EXPECT_TRUE(std::isnan(timeline->currentTime()));
EXPECT_TRUE(std::isnan(timeline->currentTime(isNull)));
EXPECT_TRUE(isNull);
document->animationClock().updateTime(200);
EXPECT_TRUE(std::isnan(timeline->currentTime()));
timeline->setZeroTime(300);
document->animationClock().updateTime(300);
EXPECT_EQ(0, timeline->currentTime());
EXPECT_EQ(0, timeline->currentTime(isNull));
EXPECT_FALSE(isNull);
document->animationClock().updateTime(400);
EXPECT_EQ(100, timeline->currentTime());
}
TEST_F(AnimationDocumentTimelineTest, PauseForTesting)
{
float seekTime = 1;
timing.fillMode = Timing::FillModeForwards;
RefPtr<Animation> anim1 = Animation::create(element.get(), AnimatableValueKeyframeEffectModel::create(AnimatableValueKeyframeVector()), timing);
RefPtr<Animation> anim2 = Animation::create(element.get(), AnimatableValueKeyframeEffectModel::create(AnimatableValueKeyframeVector()), timing);
AnimationPlayer* player1 = timeline->play(anim1.get());
AnimationPlayer* player2 = timeline->play(anim2.get());
timeline->pauseAnimationsForTesting(seekTime);
EXPECT_FLOAT_EQ(seekTime, player1->currentTime());
EXPECT_FLOAT_EQ(seekTime, player2->currentTime());
}
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(), AnimatableValueKeyframeEffectModel::create(AnimatableValueKeyframeVector()), timingForwardFill);
RefPtr<Animation> anim2 = Animation::create(element.get(), AnimatableValueKeyframeEffectModel::create(AnimatableValueKeyframeVector()), timingNoFill);
RefPtr<Animation> anim3 = Animation::create(element.get(), AnimatableValueKeyframeEffectModel::create(AnimatableValueKeyframeVector()), timingBackwardFillDelay);
RefPtr<Animation> anim4 = Animation::create(element.get(), AnimatableValueKeyframeEffectModel::create(AnimatableValueKeyframeVector()), timingNoFillDelay);
RefPtr<Animation> anim5 = Animation::create(element.get(), AnimatableValueKeyframeEffectModel::create(AnimatableValueKeyframeVector()), 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(AnimationDocumentTimelineTest, DelayBeforeAnimationStart)
{
timing.iterationDuration = 2;
timing.startDelay = 5;
RefPtr<Animation> anim = Animation::create(element.get(), nullptr, timing);
timeline->play(anim.get());
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);
}
TEST_F(AnimationDocumentTimelineTest, PlayAfterDocumentDeref)
{
timing.iterationDuration = 2;
timing.startDelay = 5;
timeline = &document->timeline();
element = nullptr;
document = nullptr;
RefPtr<Animation> anim = Animation::create(nullptr, nullptr, timing);
timeline->play(anim.get());
}
TEST_F(AnimationDocumentTimelineTest, UseAnimationPlayerAfterTimelineDeref)
{
RefPtr<AnimationPlayer> player = timeline->createAnimationPlayer(0);
timeline.clear();
player->setStartTime(0);
}
}