Chromium Code Reviews| Index: Source/core/animation/AnimationTest.cpp |
| diff --git a/Source/core/animation/AnimationTest.cpp b/Source/core/animation/AnimationTest.cpp |
| index d271e83b23bfc35c5f338f913aa73050d3d7fcd7..0bd9ab7b43c38050b7db873c3270ccb7451801db 100644 |
| --- a/Source/core/animation/AnimationTest.cpp |
| +++ b/Source/core/animation/AnimationTest.cpp |
| @@ -1,464 +1,882 @@ |
| -// Copyright 2014 The Chromium Authors. All rights reserved. |
| -// Use of this source code is governed by a BSD-style license that can be |
| -// found in the LICENSE file. |
| +/* |
| + * Copyright (c) 2013, 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: |
| + * |
| + * * Redistributions of source code must retain the above copyright |
| + * notice, this list of conditions and the following disclaimer. |
| + * * 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. |
| + * * Neither the name of Google Inc. nor the names of its |
| + * contributors may be used to endorse or promote products derived from |
| + * this software without specific prior written permission. |
| + * |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT |
| + * OWNER OR 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. |
| + */ |
| #include "config.h" |
| #include "core/animation/Animation.h" |
| -#include "bindings/core/v8/Dictionary.h" |
| -#include "bindings/core/v8/UnionTypesCore.h" |
| -#include "bindings/core/v8/V8AnimationTimingProperties.h" |
| -#include "bindings/core/v8/V8BindingForTesting.h" |
| #include "core/animation/AnimationClock.h" |
| -#include "core/animation/AnimationNodeTiming.h" |
| -#include "core/animation/AnimationTestHelper.h" |
| #include "core/animation/AnimationTimeline.h" |
| -#include "core/animation/KeyframeEffectModel.h" |
| -#include "core/animation/Timing.h" |
| +#include "core/animation/ElementAnimations.h" |
| +#include "core/animation/KeyframeEffect.h" |
| #include "core/dom/Document.h" |
| #include "core/dom/ExceptionCode.h" |
| -#include "core/testing/DummyPageHolder.h" |
| +#include "core/dom/QualifiedName.h" |
| +#include "platform/weborigin/KURL.h" |
| #include <gtest/gtest.h> |
| -#include <v8.h> |
| -namespace blink { |
| +using namespace blink; |
| + |
| +namespace { |
| class AnimationAnimationTest : public ::testing::Test { |
| protected: |
| - AnimationAnimationTest() |
| - : pageHolder(DummyPageHolder::create()) |
| - , document(pageHolder->document()) |
| - , element(document.createElement("foo", ASSERT_NO_EXCEPTION)) |
| + virtual void SetUp() |
| { |
| - document.animationClock().resetTimeForTesting(document.timeline().zeroTime()); |
| - EXPECT_EQ(0, document.timeline().currentTime()); |
| + setUpWithoutStartingTimeline(); |
| + startTimeline(); |
| } |
| - OwnPtr<DummyPageHolder> pageHolder; |
| - Document& document; |
| - RefPtrWillBePersistent<Element> element; |
| - TrackExceptionState exceptionState; |
| -}; |
| - |
| -class AnimationAnimationV8Test : public AnimationAnimationTest { |
| -protected: |
| - AnimationAnimationV8Test() |
| - : m_isolate(v8::Isolate::GetCurrent()) |
| - , m_scope(m_isolate) |
| + void setUpWithoutStartingTimeline() |
| { |
| + document = Document::create(); |
| + document->animationClock().resetTimeForTesting(); |
| + timeline = AnimationTimeline::create(document.get()); |
| + player = timeline->play(0); |
| + player->setStartTime(0); |
| + player->setSource(makeAnimation().get()); |
| } |
| - template<typename T> |
| - static PassRefPtrWillBeRawPtr<Animation> createAnimation(Element* element, Vector<Dictionary> keyframeDictionaryVector, T timingInput, ExceptionState& exceptionState) |
| + void startTimeline() |
| { |
| - return Animation::create(element, keyframeDictionaryVector, timingInput, exceptionState); |
| + simulateFrame(0); |
| } |
| - static PassRefPtrWillBeRawPtr<Animation> createAnimation(Element* element, Vector<Dictionary> keyframeDictionaryVector, ExceptionState& exceptionState) |
| + |
| + PassRefPtrWillBeRawPtr<KeyframeEffect> makeAnimation(double duration = 30, double playbackRate = 1) |
| { |
| - return Animation::create(element, keyframeDictionaryVector, exceptionState); |
| + Timing timing; |
| + timing.iterationDuration = duration; |
| + timing.playbackRate = playbackRate; |
| + return KeyframeEffect::create(0, nullptr, timing); |
| } |
| - v8::Isolate* m_isolate; |
| + bool simulateFrame(double time) |
| + { |
| + document->animationClock().updateTime(time); |
| + document->compositorPendingAnimations().update(false); |
| + // The timeline does not know about our player, so we have to explicitly call update(). |
| + return player->update(TimingUpdateForAnimationFrame); |
| + } |
| -private: |
| - V8TestingScope m_scope; |
| + RefPtrWillBePersistent<Document> document; |
| + RefPtrWillBePersistent<AnimationTimeline> timeline; |
| + RefPtrWillBePersistent<Animation> player; |
|
alancutter (OOO until 2018)
2015/05/05 01:04:51
s/player/animation/
dstockwell
2015/05/05 03:33:25
Done!
|
| + TrackExceptionState exceptionState; |
| }; |
| -TEST_F(AnimationAnimationV8Test, CanCreateAnAnimation) |
| +TEST_F(AnimationAnimationTest, InitialState) |
| { |
| - Vector<Dictionary> jsKeyframes; |
| - v8::Local<v8::Object> keyframe1 = v8::Object::New(m_isolate); |
| - v8::Local<v8::Object> keyframe2 = v8::Object::New(m_isolate); |
| - |
| - setV8ObjectPropertyAsString(keyframe1, "width", "100px"); |
| - setV8ObjectPropertyAsString(keyframe1, "offset", "0"); |
| - setV8ObjectPropertyAsString(keyframe1, "easing", "ease-in-out"); |
| - setV8ObjectPropertyAsString(keyframe2, "width", "0px"); |
| - setV8ObjectPropertyAsString(keyframe2, "offset", "1"); |
| - setV8ObjectPropertyAsString(keyframe2, "easing", "cubic-bezier(1, 1, 0.3, 0.3)"); |
| - |
| - jsKeyframes.append(Dictionary(keyframe1, m_isolate, exceptionState)); |
| - jsKeyframes.append(Dictionary(keyframe2, m_isolate, exceptionState)); |
| + setUpWithoutStartingTimeline(); |
| + player = timeline->play(0); |
| + EXPECT_EQ(Animation::Pending, player->playStateInternal()); |
| + EXPECT_EQ(0, player->currentTimeInternal()); |
| + EXPECT_FALSE(player->paused()); |
| + EXPECT_EQ(1, player->playbackRate()); |
| + EXPECT_FALSE(player->hasStartTime()); |
| + EXPECT_TRUE(isNull(player->startTimeInternal())); |
| + |
| + startTimeline(); |
| + EXPECT_EQ(Animation::Finished, player->playStateInternal()); |
| + EXPECT_EQ(0, timeline->currentTimeInternal()); |
| + EXPECT_EQ(0, player->currentTimeInternal()); |
| + EXPECT_FALSE(player->paused()); |
| + EXPECT_EQ(1, player->playbackRate()); |
| + EXPECT_EQ(0, player->startTimeInternal()); |
| + EXPECT_TRUE(player->hasStartTime()); |
| +} |
| - String value1; |
| - ASSERT_TRUE(DictionaryHelper::get(jsKeyframes[0], "width", value1)); |
| - ASSERT_EQ("100px", value1); |
| - String value2; |
| - ASSERT_TRUE(DictionaryHelper::get(jsKeyframes[1], "width", value2)); |
| - ASSERT_EQ("0px", value2); |
| +TEST_F(AnimationAnimationTest, CurrentTimeDoesNotSetOutdated) |
| +{ |
| + EXPECT_FALSE(player->outdated()); |
| + EXPECT_EQ(0, player->currentTimeInternal()); |
| + EXPECT_FALSE(player->outdated()); |
| + // FIXME: We should split simulateFrame into a version that doesn't update |
| + // the player and one that does, as most of the tests don't require update() |
| + // to be called. |
| + document->animationClock().updateTime(10); |
| + EXPECT_EQ(10, player->currentTimeInternal()); |
| + EXPECT_FALSE(player->outdated()); |
| +} |
| - RefPtrWillBeRawPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, 0, exceptionState); |
| +TEST_F(AnimationAnimationTest, SetCurrentTime) |
| +{ |
| + EXPECT_EQ(Animation::Running, player->playStateInternal()); |
| + player->setCurrentTimeInternal(10); |
| + EXPECT_EQ(Animation::Running, player->playStateInternal()); |
| + EXPECT_EQ(10, player->currentTimeInternal()); |
| + simulateFrame(10); |
| + EXPECT_EQ(Animation::Running, player->playStateInternal()); |
| + EXPECT_EQ(20, player->currentTimeInternal()); |
| +} |
| - Element* target = animation->target(); |
| - EXPECT_EQ(*element.get(), *target); |
| +TEST_F(AnimationAnimationTest, SetCurrentTimeNegative) |
| +{ |
| + player->setCurrentTimeInternal(-10); |
| + EXPECT_EQ(Animation::Running, player->playStateInternal()); |
| + EXPECT_EQ(-10, player->currentTimeInternal()); |
| + simulateFrame(20); |
| + EXPECT_EQ(10, player->currentTimeInternal()); |
| + |
| + player->setPlaybackRate(-2); |
| + player->setCurrentTimeInternal(-10); |
| + EXPECT_EQ(Animation::Pending, player->playStateInternal()); |
| + EXPECT_EQ(-10, player->currentTimeInternal()); |
| + simulateFrame(40); |
| + EXPECT_EQ(Animation::Finished, player->playStateInternal()); |
| + EXPECT_EQ(-10, player->currentTimeInternal()); |
| +} |
| - const KeyframeVector keyframes = toKeyframeEffectModelBase(animation->effect())->getFrames(); |
| +TEST_F(AnimationAnimationTest, SetCurrentTimeNegativeWithoutSimultaneousPlaybackRateChange) |
| +{ |
| + simulateFrame(20); |
| + EXPECT_EQ(20, player->currentTimeInternal()); |
| + EXPECT_EQ(Animation::Running, player->playStateInternal()); |
| + player->setPlaybackRate(-1); |
| + EXPECT_EQ(Animation::Pending, player->playStateInternal()); |
| + simulateFrame(30); |
| + EXPECT_EQ(20, player->currentTimeInternal()); |
| + EXPECT_EQ(Animation::Running, player->playStateInternal()); |
| + player->setCurrentTime(-10 * 1000); |
| + EXPECT_EQ(Animation::Finished, player->playStateInternal()); |
| +} |
| - EXPECT_EQ(0, keyframes[0]->offset()); |
| - EXPECT_EQ(1, keyframes[1]->offset()); |
| +TEST_F(AnimationAnimationTest, SetCurrentTimePastContentEnd) |
| +{ |
| + player->setCurrentTime(50 * 1000); |
| + EXPECT_EQ(Animation::Finished, player->playStateInternal()); |
| + EXPECT_EQ(50, player->currentTimeInternal()); |
| + simulateFrame(20); |
| + EXPECT_EQ(Animation::Finished, player->playStateInternal()); |
| + EXPECT_EQ(50, player->currentTimeInternal()); |
| + |
| + player->setPlaybackRate(-2); |
| + player->setCurrentTime(50 * 1000); |
| + EXPECT_EQ(Animation::Pending, player->playStateInternal()); |
| + EXPECT_EQ(50, player->currentTimeInternal()); |
| + simulateFrame(20); |
| + EXPECT_EQ(Animation::Running, player->playStateInternal()); |
| + simulateFrame(40); |
| + EXPECT_EQ(10, player->currentTimeInternal()); |
| +} |
| - const CSSValue* keyframe1Width = toStringKeyframe(keyframes[0].get())->cssPropertyValue(CSSPropertyWidth); |
| - const CSSValue* keyframe2Width = toStringKeyframe(keyframes[1].get())->cssPropertyValue(CSSPropertyWidth); |
| - ASSERT(keyframe1Width); |
| - ASSERT(keyframe2Width); |
| +TEST_F(AnimationAnimationTest, SetCurrentTimeBeforeTimelineStarted) |
| +{ |
| + setUpWithoutStartingTimeline(); |
| + player->setCurrentTimeInternal(5); |
| + EXPECT_EQ(5, player->currentTimeInternal()); |
| + startTimeline(); |
| + simulateFrame(10); |
| + EXPECT_EQ(15, player->currentTimeInternal()); |
| +} |
| - EXPECT_EQ("100px", keyframe1Width->cssText()); |
| - EXPECT_EQ("0px", keyframe2Width->cssText()); |
| +TEST_F(AnimationAnimationTest, SetCurrentTimePastContentEndBeforeTimelineStarted) |
| +{ |
| + setUpWithoutStartingTimeline(); |
| + player->setCurrentTime(250 * 1000); |
| + EXPECT_EQ(250, player->currentTimeInternal()); |
| + startTimeline(); |
| + simulateFrame(10); |
| + EXPECT_EQ(250, player->currentTimeInternal()); |
| +} |
| - EXPECT_EQ(*(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut)), keyframes[0]->easing()); |
| - EXPECT_EQ(*(CubicBezierTimingFunction::create(1, 1, 0.3, 0.3).get()), keyframes[1]->easing()); |
| +TEST_F(AnimationAnimationTest, SetCurrentTimeMax) |
| +{ |
| + player->setCurrentTimeInternal(std::numeric_limits<double>::max()); |
| + EXPECT_EQ(std::numeric_limits<double>::max(), player->currentTimeInternal()); |
| + simulateFrame(100); |
| + EXPECT_EQ(std::numeric_limits<double>::max(), player->currentTimeInternal()); |
| } |
| -TEST_F(AnimationAnimationV8Test, CanSetDuration) |
| +TEST_F(AnimationAnimationTest, SetCurrentTimeSetsStartTime) |
| { |
| - Vector<Dictionary, 0> jsKeyframes; |
| - double duration = 2000; |
| + EXPECT_EQ(0, player->startTime()); |
| + player->setCurrentTime(1000); |
| + EXPECT_EQ(-1000, player->startTime()); |
| + simulateFrame(1); |
| + EXPECT_EQ(-1000, player->startTime()); |
| + EXPECT_EQ(2000, player->currentTime()); |
| +} |
| - RefPtrWillBeRawPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, duration, exceptionState); |
| +TEST_F(AnimationAnimationTest, SetStartTime) |
| +{ |
| + simulateFrame(20); |
| + EXPECT_EQ(Animation::Running, player->playStateInternal()); |
| + EXPECT_EQ(0, player->startTimeInternal()); |
| + EXPECT_EQ(20 * 1000, player->currentTime()); |
| + player->setStartTime(10 * 1000); |
| + EXPECT_EQ(Animation::Running, player->playStateInternal()); |
| + EXPECT_EQ(10, player->startTimeInternal()); |
| + EXPECT_EQ(10 * 1000, player->currentTime()); |
| + simulateFrame(30); |
| + EXPECT_EQ(10, player->startTimeInternal()); |
| + EXPECT_EQ(20 * 1000, player->currentTime()); |
| + player->setStartTime(-20 * 1000); |
| + EXPECT_EQ(Animation::Finished, player->playStateInternal()); |
| +} |
| - EXPECT_EQ(duration / 1000, animation->specifiedTiming().iterationDuration); |
| +TEST_F(AnimationAnimationTest, SetStartTimeLimitsAnimation) |
| +{ |
| + player->setStartTime(-50 * 1000); |
| + EXPECT_EQ(Animation::Finished, player->playStateInternal()); |
| + EXPECT_EQ(30, player->currentTimeInternal()); |
| + player->setPlaybackRate(-1); |
| + EXPECT_EQ(Animation::Pending, player->playStateInternal()); |
| + player->setStartTime(-100 * 1000); |
| + EXPECT_EQ(Animation::Finished, player->playStateInternal()); |
| + EXPECT_EQ(0, player->currentTimeInternal()); |
| + EXPECT_TRUE(player->limited()); |
| } |
| -TEST_F(AnimationAnimationV8Test, CanOmitSpecifiedDuration) |
| +TEST_F(AnimationAnimationTest, SetStartTimeOnLimitedAnimation) |
| { |
| - Vector<Dictionary, 0> jsKeyframes; |
| - RefPtrWillBeRawPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, exceptionState); |
| - EXPECT_TRUE(std::isnan(animation->specifiedTiming().iterationDuration)); |
| + simulateFrame(30); |
| + player->setStartTime(-10 * 1000); |
| + EXPECT_EQ(Animation::Finished, player->playStateInternal()); |
| + EXPECT_EQ(30, player->currentTimeInternal()); |
| + player->setCurrentTimeInternal(50); |
| + player->setStartTime(-40 * 1000); |
| + EXPECT_EQ(30, player->currentTimeInternal()); |
| + EXPECT_EQ(Animation::Finished, player->playStateInternal()); |
| + EXPECT_TRUE(player->limited()); |
| } |
| -TEST_F(AnimationAnimationV8Test, NegativeDurationIsAuto) |
| +TEST_F(AnimationAnimationTest, StartTimePauseFinish) |
| { |
| - Vector<Dictionary, 0> jsKeyframes; |
| - RefPtrWillBeRawPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, -2, exceptionState); |
| - EXPECT_TRUE(std::isnan(animation->specifiedTiming().iterationDuration)); |
| + player->pause(); |
| + EXPECT_EQ(Animation::Pending, player->playStateInternal()); |
| + EXPECT_TRUE(std::isnan(player->startTime())); |
| + player->finish(exceptionState); |
| + EXPECT_EQ(Animation::Paused, player->playStateInternal()); |
| + EXPECT_TRUE(std::isnan(player->startTime())); |
| } |
| -TEST_F(AnimationAnimationV8Test, MismatchedKeyframePropertyRaisesException) |
| +TEST_F(AnimationAnimationTest, PauseBeatsFinish) |
| { |
| - Vector<Dictionary> jsKeyframes; |
| - v8::Local<v8::Object> keyframe1 = v8::Object::New(m_isolate); |
| - v8::Local<v8::Object> keyframe2 = v8::Object::New(m_isolate); |
| + player->pause(); |
| + EXPECT_EQ(Animation::Pending, player->playStateInternal()); |
| + simulateFrame(10); |
| + EXPECT_EQ(Animation::Paused, player->playStateInternal()); |
| + player->finish(exceptionState); |
| + EXPECT_EQ(Animation::Paused, player->playStateInternal()); |
| +} |
| - setV8ObjectPropertyAsString(keyframe1, "width", "100px"); |
| - setV8ObjectPropertyAsString(keyframe1, "offset", "0"); |
| +TEST_F(AnimationAnimationTest, StartTimeFinishPause) |
| +{ |
| + player->finish(exceptionState); |
| + EXPECT_EQ(-30 * 1000, player->startTime()); |
| + player->pause(); |
| + EXPECT_TRUE(std::isnan(player->startTime())); |
| +} |
| - // Height property appears only in keyframe2 |
| - setV8ObjectPropertyAsString(keyframe2, "height", "100px"); |
| - setV8ObjectPropertyAsString(keyframe2, "width", "0px"); |
| - setV8ObjectPropertyAsString(keyframe2, "offset", "1"); |
| +TEST_F(AnimationAnimationTest, StartTimeWithZeroPlaybackRate) |
| +{ |
| + player->setPlaybackRate(0); |
| + EXPECT_EQ(Animation::Pending, player->playStateInternal()); |
| + EXPECT_TRUE(std::isnan(player->startTime())); |
| + simulateFrame(10); |
| + EXPECT_EQ(Animation::Running, player->playStateInternal()); |
| +} |
| - jsKeyframes.append(Dictionary(keyframe1, m_isolate, exceptionState)); |
| - jsKeyframes.append(Dictionary(keyframe2, m_isolate, exceptionState)); |
| +TEST_F(AnimationAnimationTest, PausePlay) |
| +{ |
| + simulateFrame(10); |
| + player->pause(); |
| + EXPECT_EQ(Animation::Pending, player->playStateInternal()); |
| + EXPECT_TRUE(player->paused()); |
| + EXPECT_EQ(10, player->currentTimeInternal()); |
| + simulateFrame(20); |
| + EXPECT_EQ(Animation::Paused, player->playStateInternal()); |
| + player->play(); |
| + EXPECT_EQ(Animation::Pending, player->playStateInternal()); |
| + simulateFrame(20); |
| + EXPECT_EQ(Animation::Running, player->playStateInternal()); |
| + EXPECT_FALSE(player->paused()); |
| + EXPECT_EQ(10, player->currentTimeInternal()); |
| + simulateFrame(30); |
| + EXPECT_EQ(20, player->currentTimeInternal()); |
| +} |
| - createAnimation(element.get(), jsKeyframes, 0, exceptionState); |
| +TEST_F(AnimationAnimationTest, PauseBeforeTimelineStarted) |
| +{ |
| + setUpWithoutStartingTimeline(); |
| + player->pause(); |
| + EXPECT_TRUE(player->paused()); |
| + player->play(); |
| + EXPECT_FALSE(player->paused()); |
| + |
| + player->pause(); |
| + startTimeline(); |
| + simulateFrame(100); |
| + EXPECT_TRUE(player->paused()); |
| + EXPECT_EQ(0, player->currentTimeInternal()); |
| +} |
| - EXPECT_TRUE(exceptionState.hadException()); |
| - EXPECT_EQ(NotSupportedError, exceptionState.code()); |
| +TEST_F(AnimationAnimationTest, PlayRewindsToStart) |
| +{ |
| + player->setCurrentTimeInternal(30); |
| + player->play(); |
| + EXPECT_EQ(0, player->currentTimeInternal()); |
| + |
| + player->setCurrentTimeInternal(40); |
| + player->play(); |
| + EXPECT_EQ(0, player->currentTimeInternal()); |
| + EXPECT_EQ(Animation::Pending, player->playStateInternal()); |
| + simulateFrame(10); |
| + EXPECT_EQ(Animation::Running, player->playStateInternal()); |
| + |
| + player->setCurrentTimeInternal(-10); |
| + EXPECT_EQ(Animation::Running, player->playStateInternal()); |
| + player->play(); |
| + EXPECT_EQ(0, player->currentTimeInternal()); |
| + EXPECT_EQ(Animation::Pending, player->playStateInternal()); |
| + simulateFrame(10); |
| + EXPECT_EQ(Animation::Running, player->playStateInternal()); |
| } |
| -TEST_F(AnimationAnimationV8Test, MissingOffsetZeroRaisesException) |
| +TEST_F(AnimationAnimationTest, PlayRewindsToEnd) |
| { |
| - Vector<Dictionary> jsKeyframes; |
| - v8::Local<v8::Object> keyframe1 = v8::Object::New(m_isolate); |
| - v8::Local<v8::Object> keyframe2 = v8::Object::New(m_isolate); |
| + player->setPlaybackRate(-1); |
| + player->play(); |
| + EXPECT_EQ(30, player->currentTimeInternal()); |
| + |
| + player->setCurrentTimeInternal(40); |
| + EXPECT_EQ(Animation::Pending, player->playStateInternal()); |
| + player->play(); |
| + EXPECT_EQ(30, player->currentTimeInternal()); |
| + EXPECT_EQ(Animation::Pending, player->playStateInternal()); |
| + simulateFrame(10); |
| + EXPECT_EQ(Animation::Running, player->playStateInternal()); |
| + |
| + player->setCurrentTimeInternal(-10); |
| + player->play(); |
| + EXPECT_EQ(30, player->currentTimeInternal()); |
| + EXPECT_EQ(Animation::Pending, player->playStateInternal()); |
| + simulateFrame(20); |
| + EXPECT_EQ(Animation::Running, player->playStateInternal()); |
| +} |
| - setV8ObjectPropertyAsString(keyframe1, "width", "100px"); |
| - setV8ObjectPropertyAsString(keyframe1, "offset", "0.1"); |
| - setV8ObjectPropertyAsString(keyframe2, "width", "0px"); |
| - setV8ObjectPropertyAsString(keyframe2, "offset", "1"); |
| +TEST_F(AnimationAnimationTest, PlayWithPlaybackRateZeroDoesNotSeek) |
| +{ |
| + player->setPlaybackRate(0); |
| + player->play(); |
| + EXPECT_EQ(0, player->currentTimeInternal()); |
| - jsKeyframes.append(Dictionary(keyframe1, m_isolate, exceptionState)); |
| - jsKeyframes.append(Dictionary(keyframe2, m_isolate, exceptionState)); |
| + player->setCurrentTimeInternal(40); |
| + player->play(); |
| + EXPECT_EQ(40, player->currentTimeInternal()); |
| - createAnimation(element.get(), jsKeyframes, 0, exceptionState); |
| + player->setCurrentTimeInternal(-10); |
| + player->play(); |
| + EXPECT_EQ(-10, player->currentTimeInternal()); |
| +} |
| - EXPECT_TRUE(exceptionState.hadException()); |
| - EXPECT_EQ(NotSupportedError, exceptionState.code()); |
| +TEST_F(AnimationAnimationTest, PlayAfterPauseWithPlaybackRateZeroUpdatesPlayState) |
| +{ |
| + player->pause(); |
| + player->setPlaybackRate(0); |
| + simulateFrame(1); |
| + EXPECT_EQ(Animation::Paused, player->playStateInternal()); |
| + player->play(); |
| + EXPECT_EQ(Animation::Running, player->playStateInternal()); |
| } |
| -TEST_F(AnimationAnimationV8Test, MissingOffsetOneRaisesException) |
| +TEST_F(AnimationAnimationTest, Reverse) |
| { |
| - Vector<Dictionary> jsKeyframes; |
| - v8::Local<v8::Object> keyframe1 = v8::Object::New(m_isolate); |
| - v8::Local<v8::Object> keyframe2 = v8::Object::New(m_isolate); |
| + player->setCurrentTimeInternal(10); |
| + player->pause(); |
| + player->reverse(); |
| + EXPECT_FALSE(player->paused()); |
| + EXPECT_EQ(-1, player->playbackRate()); |
| + EXPECT_EQ(10, player->currentTimeInternal()); |
| +} |
| - setV8ObjectPropertyAsString(keyframe1, "width", "100px"); |
| - setV8ObjectPropertyAsString(keyframe1, "offset", "0"); |
| - setV8ObjectPropertyAsString(keyframe2, "width", "0px"); |
| - setV8ObjectPropertyAsString(keyframe2, "offset", "0.1"); |
| +TEST_F(AnimationAnimationTest, ReverseDoesNothingWithPlaybackRateZero) |
| +{ |
| + player->setCurrentTimeInternal(10); |
| + player->setPlaybackRate(0); |
| + player->pause(); |
| + player->reverse(); |
| + EXPECT_TRUE(player->paused()); |
| + EXPECT_EQ(0, player->playbackRate()); |
| + EXPECT_EQ(10, player->currentTimeInternal()); |
| +} |
| - jsKeyframes.append(Dictionary(keyframe1, m_isolate, exceptionState)); |
| - jsKeyframes.append(Dictionary(keyframe2, m_isolate, exceptionState)); |
| +TEST_F(AnimationAnimationTest, ReverseDoesNotSeekWithNoSource) |
| +{ |
| + player->setSource(0); |
| + player->setCurrentTimeInternal(10); |
| + player->reverse(); |
| + EXPECT_EQ(10, player->currentTimeInternal()); |
| +} |
| - createAnimation(element.get(), jsKeyframes, 0, exceptionState); |
| +TEST_F(AnimationAnimationTest, ReverseSeeksToStart) |
| +{ |
| + player->setCurrentTimeInternal(-10); |
| + player->setPlaybackRate(-1); |
| + player->reverse(); |
| + EXPECT_EQ(0, player->currentTimeInternal()); |
| +} |
| - EXPECT_TRUE(exceptionState.hadException()); |
| - EXPECT_EQ(NotSupportedError, exceptionState.code()); |
| +TEST_F(AnimationAnimationTest, ReverseSeeksToEnd) |
| +{ |
| + player->setCurrentTime(40 * 1000); |
| + player->reverse(); |
| + EXPECT_EQ(30, player->currentTimeInternal()); |
| } |
| -TEST_F(AnimationAnimationV8Test, MissingOffsetZeroAndOneRaisesException) |
| +TEST_F(AnimationAnimationTest, ReverseBeyondLimit) |
| { |
| - Vector<Dictionary> jsKeyframes; |
| - v8::Local<v8::Object> keyframe1 = v8::Object::New(m_isolate); |
| - v8::Local<v8::Object> keyframe2 = v8::Object::New(m_isolate); |
| + player->setCurrentTimeInternal(40); |
| + player->setPlaybackRate(-1); |
| + player->reverse(); |
| + EXPECT_EQ(Animation::Pending, player->playStateInternal()); |
| + EXPECT_EQ(0, player->currentTimeInternal()); |
| + |
| + player->setCurrentTimeInternal(-10); |
| + player->reverse(); |
| + EXPECT_EQ(Animation::Pending, player->playStateInternal()); |
| + EXPECT_EQ(30, player->currentTimeInternal()); |
| +} |
| - setV8ObjectPropertyAsString(keyframe1, "width", "100px"); |
| - setV8ObjectPropertyAsString(keyframe1, "offset", "0.1"); |
| - setV8ObjectPropertyAsString(keyframe2, "width", "0px"); |
| - setV8ObjectPropertyAsString(keyframe2, "offset", "0.2"); |
| - jsKeyframes.append(Dictionary(keyframe1, m_isolate, exceptionState)); |
| - jsKeyframes.append(Dictionary(keyframe2, m_isolate, exceptionState)); |
| +TEST_F(AnimationAnimationTest, Finish) |
| +{ |
| + player->finish(exceptionState); |
| + EXPECT_EQ(30, player->currentTimeInternal()); |
| + EXPECT_EQ(Animation::Finished, player->playStateInternal()); |
| - createAnimation(element.get(), jsKeyframes, 0, exceptionState); |
| + player->setPlaybackRate(-1); |
| + player->finish(exceptionState); |
| + EXPECT_EQ(0, player->currentTimeInternal()); |
| + EXPECT_EQ(Animation::Finished, player->playStateInternal()); |
| - EXPECT_TRUE(exceptionState.hadException()); |
| - EXPECT_EQ(NotSupportedError, exceptionState.code()); |
| + EXPECT_FALSE(exceptionState.hadException()); |
| } |
| -TEST_F(AnimationAnimationV8Test, SpecifiedGetters) |
| +TEST_F(AnimationAnimationTest, FinishAfterSourceEnd) |
| { |
| - Vector<Dictionary, 0> jsKeyframes; |
| - |
| - v8::Local<v8::Object> timingInput = v8::Object::New(m_isolate); |
| - setV8ObjectPropertyAsNumber(timingInput, "delay", 2); |
| - setV8ObjectPropertyAsNumber(timingInput, "endDelay", 0.5); |
| - setV8ObjectPropertyAsString(timingInput, "fill", "backwards"); |
| - setV8ObjectPropertyAsNumber(timingInput, "iterationStart", 2); |
| - setV8ObjectPropertyAsNumber(timingInput, "iterations", 10); |
| - setV8ObjectPropertyAsNumber(timingInput, "playbackRate", 2); |
| - setV8ObjectPropertyAsString(timingInput, "direction", "reverse"); |
| - setV8ObjectPropertyAsString(timingInput, "easing", "step-start"); |
| - AnimationTimingProperties timingInputDictionary; |
| - V8AnimationTimingProperties::toImpl(m_isolate, timingInput, timingInputDictionary, exceptionState); |
| + player->setCurrentTime(40 * 1000); |
| + player->finish(exceptionState); |
| + EXPECT_EQ(30, player->currentTimeInternal()); |
| +} |
| - RefPtrWillBeRawPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, timingInputDictionary, exceptionState); |
| +TEST_F(AnimationAnimationTest, FinishBeforeStart) |
| +{ |
| + player->setCurrentTimeInternal(-10); |
| + player->setPlaybackRate(-1); |
| + player->finish(exceptionState); |
| + EXPECT_EQ(0, player->currentTimeInternal()); |
| +} |
| - RefPtrWillBeRawPtr<AnimationNodeTiming> specified = animation->timing(); |
| - EXPECT_EQ(2, specified->delay()); |
| - EXPECT_EQ(0.5, specified->endDelay()); |
| - EXPECT_EQ("backwards", specified->fill()); |
| - EXPECT_EQ(2, specified->iterationStart()); |
| - EXPECT_EQ(10, specified->iterations()); |
| - EXPECT_EQ(2, specified->playbackRate()); |
| - EXPECT_EQ("reverse", specified->direction()); |
| - EXPECT_EQ("step-start", specified->easing()); |
| +TEST_F(AnimationAnimationTest, FinishDoesNothingWithPlaybackRateZero) |
| +{ |
| + player->setCurrentTimeInternal(10); |
| + player->setPlaybackRate(0); |
| + player->finish(exceptionState); |
| + EXPECT_EQ(10, player->currentTimeInternal()); |
| } |
| -TEST_F(AnimationAnimationV8Test, SpecifiedDurationGetter) |
| +TEST_F(AnimationAnimationTest, FinishRaisesException) |
| { |
| - Vector<Dictionary, 0> jsKeyframes; |
| + Timing timing; |
| + timing.iterationDuration = 1; |
| + timing.iterationCount = std::numeric_limits<double>::infinity(); |
| + player->setSource(KeyframeEffect::create(0, nullptr, timing).get()); |
| + player->setCurrentTimeInternal(10); |
| - v8::Local<v8::Object> timingInputWithDuration = v8::Object::New(m_isolate); |
| - setV8ObjectPropertyAsNumber(timingInputWithDuration, "duration", 2.5); |
| - AnimationTimingProperties timingInputDictionaryWithDuration; |
| - V8AnimationTimingProperties::toImpl(m_isolate, timingInputWithDuration, timingInputDictionaryWithDuration, exceptionState); |
| + player->finish(exceptionState); |
| + EXPECT_EQ(10, player->currentTimeInternal()); |
| + EXPECT_TRUE(exceptionState.hadException()); |
| + EXPECT_EQ(InvalidStateError, exceptionState.code()); |
| +} |
| - RefPtrWillBeRawPtr<Animation> animationWithDuration = createAnimation(element.get(), jsKeyframes, timingInputDictionaryWithDuration, exceptionState); |
| - RefPtrWillBeRawPtr<AnimationNodeTiming> specifiedWithDuration = animationWithDuration->timing(); |
| - UnrestrictedDoubleOrString duration; |
| - specifiedWithDuration->duration(duration); |
| - EXPECT_TRUE(duration.isUnrestrictedDouble()); |
| - EXPECT_EQ(2.5, duration.getAsUnrestrictedDouble()); |
| - EXPECT_FALSE(duration.isString()); |
| +TEST_F(AnimationAnimationTest, LimitingAtSourceEnd) |
| +{ |
| + simulateFrame(30); |
| + EXPECT_EQ(30, player->currentTimeInternal()); |
| + EXPECT_TRUE(player->limited()); |
| + simulateFrame(40); |
| + EXPECT_EQ(30, player->currentTimeInternal()); |
| + EXPECT_FALSE(player->paused()); |
| +} |
| +TEST_F(AnimationAnimationTest, LimitingAtStart) |
| +{ |
| + simulateFrame(30); |
| + player->setPlaybackRate(-2); |
| + simulateFrame(30); |
| + simulateFrame(45); |
| + EXPECT_EQ(0, player->currentTimeInternal()); |
| + EXPECT_TRUE(player->limited()); |
| + simulateFrame(60); |
| + EXPECT_EQ(0, player->currentTimeInternal()); |
| + EXPECT_FALSE(player->paused()); |
| +} |
| - v8::Local<v8::Object> timingInputNoDuration = v8::Object::New(m_isolate); |
| - AnimationTimingProperties timingInputDictionaryNoDuration; |
| - V8AnimationTimingProperties::toImpl(m_isolate, timingInputNoDuration, timingInputDictionaryNoDuration, exceptionState); |
| +TEST_F(AnimationAnimationTest, LimitingWithNoSource) |
| +{ |
| + player->setSource(0); |
| + EXPECT_TRUE(player->limited()); |
| + simulateFrame(30); |
| + EXPECT_EQ(0, player->currentTimeInternal()); |
| +} |
| - RefPtrWillBeRawPtr<Animation> animationNoDuration = createAnimation(element.get(), jsKeyframes, timingInputDictionaryNoDuration, exceptionState); |
| - RefPtrWillBeRawPtr<AnimationNodeTiming> specifiedNoDuration = animationNoDuration->timing(); |
| - UnrestrictedDoubleOrString duration2; |
| - specifiedNoDuration->duration(duration2); |
| - EXPECT_FALSE(duration2.isUnrestrictedDouble()); |
| - EXPECT_TRUE(duration2.isString()); |
| - EXPECT_EQ("auto", duration2.getAsString()); |
| +TEST_F(AnimationAnimationTest, SetPlaybackRate) |
| +{ |
| + player->setPlaybackRate(2); |
| + simulateFrame(0); |
| + EXPECT_EQ(2, player->playbackRate()); |
| + EXPECT_EQ(0, player->currentTimeInternal()); |
| + simulateFrame(10); |
| + EXPECT_EQ(20, player->currentTimeInternal()); |
| } |
| -TEST_F(AnimationAnimationV8Test, SpecifiedSetters) |
| +TEST_F(AnimationAnimationTest, SetPlaybackRateBeforeTimelineStarted) |
| { |
| - Vector<Dictionary, 0> jsKeyframes; |
| - v8::Local<v8::Object> timingInput = v8::Object::New(m_isolate); |
| - AnimationTimingProperties timingInputDictionary; |
| - V8AnimationTimingProperties::toImpl(m_isolate, timingInput, timingInputDictionary, exceptionState); |
| - RefPtrWillBeRawPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, timingInputDictionary, exceptionState); |
| - |
| - RefPtrWillBeRawPtr<AnimationNodeTiming> specified = animation->timing(); |
| - |
| - EXPECT_EQ(0, specified->delay()); |
| - specified->setDelay(2); |
| - EXPECT_EQ(2, specified->delay()); |
| + setUpWithoutStartingTimeline(); |
| + player->setPlaybackRate(2); |
| + EXPECT_EQ(2, player->playbackRate()); |
| + EXPECT_EQ(0, player->currentTimeInternal()); |
| + startTimeline(); |
| + simulateFrame(10); |
| + EXPECT_EQ(20, player->currentTimeInternal()); |
| +} |
| - EXPECT_EQ(0, specified->endDelay()); |
| - specified->setEndDelay(0.5); |
| - EXPECT_EQ(0.5, specified->endDelay()); |
| +TEST_F(AnimationAnimationTest, SetPlaybackRateWhilePaused) |
| +{ |
| + simulateFrame(10); |
| + player->pause(); |
| + player->setPlaybackRate(2); |
| + simulateFrame(20); |
| + player->play(); |
| + EXPECT_EQ(10, player->currentTimeInternal()); |
| + simulateFrame(20); |
| + simulateFrame(25); |
| + EXPECT_EQ(20, player->currentTimeInternal()); |
| +} |
| - EXPECT_EQ("auto", specified->fill()); |
| - specified->setFill("backwards"); |
| - EXPECT_EQ("backwards", specified->fill()); |
| +TEST_F(AnimationAnimationTest, SetPlaybackRateWhileLimited) |
| +{ |
| + simulateFrame(40); |
| + EXPECT_EQ(30, player->currentTimeInternal()); |
| + player->setPlaybackRate(2); |
| + simulateFrame(50); |
| + EXPECT_EQ(30, player->currentTimeInternal()); |
| + player->setPlaybackRate(-2); |
| + simulateFrame(50); |
| + simulateFrame(60); |
| + EXPECT_FALSE(player->limited()); |
| + EXPECT_EQ(10, player->currentTimeInternal()); |
| +} |
| - EXPECT_EQ(0, specified->iterationStart()); |
| - specified->setIterationStart(2); |
| - EXPECT_EQ(2, specified->iterationStart()); |
| +TEST_F(AnimationAnimationTest, SetPlaybackRateZero) |
| +{ |
| + simulateFrame(0); |
| + simulateFrame(10); |
| + player->setPlaybackRate(0); |
| + simulateFrame(10); |
| + EXPECT_EQ(10, player->currentTimeInternal()); |
| + simulateFrame(20); |
| + EXPECT_EQ(10, player->currentTimeInternal()); |
| + player->setCurrentTimeInternal(20); |
| + EXPECT_EQ(20, player->currentTimeInternal()); |
| +} |
| - EXPECT_EQ(1, specified->iterations()); |
| - specified->setIterations(10); |
| - EXPECT_EQ(10, specified->iterations()); |
| +TEST_F(AnimationAnimationTest, SetPlaybackRateMax) |
| +{ |
| + player->setPlaybackRate(std::numeric_limits<double>::max()); |
| + simulateFrame(0); |
| + EXPECT_EQ(std::numeric_limits<double>::max(), player->playbackRate()); |
| + EXPECT_EQ(0, player->currentTimeInternal()); |
| + simulateFrame(1); |
| + EXPECT_EQ(30, player->currentTimeInternal()); |
| +} |
| - EXPECT_EQ(1, specified->playbackRate()); |
| - specified->setPlaybackRate(2); |
| - EXPECT_EQ(2, specified->playbackRate()); |
| - EXPECT_EQ("normal", specified->direction()); |
| - specified->setDirection("reverse"); |
| - EXPECT_EQ("reverse", specified->direction()); |
| +TEST_F(AnimationAnimationTest, SetSource) |
| +{ |
| + player = timeline->play(0); |
| + player->setStartTime(0); |
| + RefPtrWillBeRawPtr<AnimationEffect> source1 = makeAnimation(); |
| + RefPtrWillBeRawPtr<AnimationEffect> source2 = makeAnimation(); |
| + player->setSource(source1.get()); |
| + EXPECT_EQ(source1, player->source()); |
| + EXPECT_EQ(0, player->currentTimeInternal()); |
| + player->setCurrentTimeInternal(15); |
| + player->setSource(source2.get()); |
| + EXPECT_EQ(15, player->currentTimeInternal()); |
| + EXPECT_EQ(0, source1->animation()); |
| + EXPECT_EQ(player.get(), source2->animation()); |
| + EXPECT_EQ(source2, player->source()); |
| +} |
| - EXPECT_EQ("linear", specified->easing()); |
| - specified->setEasing("step-start"); |
| - EXPECT_EQ("step-start", specified->easing()); |
| +TEST_F(AnimationAnimationTest, SetSourceLimitsAnimation) |
| +{ |
| + player->setCurrentTimeInternal(20); |
| + player->setSource(makeAnimation(10).get()); |
| + EXPECT_EQ(20, player->currentTimeInternal()); |
| + EXPECT_TRUE(player->limited()); |
| + simulateFrame(10); |
| + EXPECT_EQ(20, player->currentTimeInternal()); |
| } |
| -TEST_F(AnimationAnimationV8Test, SetSpecifiedDuration) |
| +TEST_F(AnimationAnimationTest, SetSourceUnlimitsAnimation) |
| { |
| - Vector<Dictionary, 0> jsKeyframes; |
| - v8::Local<v8::Object> timingInput = v8::Object::New(m_isolate); |
| - AnimationTimingProperties timingInputDictionary; |
| - V8AnimationTimingProperties::toImpl(m_isolate, timingInput, timingInputDictionary, exceptionState); |
| - RefPtrWillBeRawPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, timingInputDictionary, exceptionState); |
| + player->setCurrentTimeInternal(40); |
| + player->setSource(makeAnimation(60).get()); |
| + EXPECT_FALSE(player->limited()); |
| + EXPECT_EQ(40, player->currentTimeInternal()); |
| + simulateFrame(10); |
| + EXPECT_EQ(50, player->currentTimeInternal()); |
| +} |
| - RefPtrWillBeRawPtr<AnimationNodeTiming> specified = animation->timing(); |
| - UnrestrictedDoubleOrString duration; |
| - specified->duration(duration); |
| - EXPECT_FALSE(duration.isUnrestrictedDouble()); |
| - EXPECT_TRUE(duration.isString()); |
| - EXPECT_EQ("auto", duration.getAsString()); |
| +TEST_F(AnimationAnimationTest, EmptyAnimationsDontUpdateEffects) |
| +{ |
| + player = timeline->play(0); |
| + player->update(TimingUpdateOnDemand); |
| + EXPECT_EQ(std::numeric_limits<double>::infinity(), player->timeToEffectChange()); |
| - UnrestrictedDoubleOrString inDuration; |
| - inDuration.setUnrestrictedDouble(2.5); |
| - specified->setDuration(inDuration); |
| - UnrestrictedDoubleOrString duration2; |
| - specified->duration(duration2); |
| - EXPECT_TRUE(duration2.isUnrestrictedDouble()); |
| - EXPECT_EQ(2.5, duration2.getAsUnrestrictedDouble()); |
| - EXPECT_FALSE(duration2.isString()); |
| + simulateFrame(1234); |
| + EXPECT_EQ(std::numeric_limits<double>::infinity(), player->timeToEffectChange()); |
| +} |
| + |
| +TEST_F(AnimationAnimationTest, AnimationsDisassociateFromSource) |
| +{ |
| + AnimationEffect* animationNode = player->source(); |
| + Animation* player2 = timeline->play(animationNode); |
| + EXPECT_EQ(0, player->source()); |
| + player->setSource(animationNode); |
| + EXPECT_EQ(0, player2->source()); |
| } |
| -TEST_F(AnimationAnimationTest, TimeToEffectChange) |
| +TEST_F(AnimationAnimationTest, AnimationsReturnTimeToNextEffect) |
| { |
| Timing timing; |
| - timing.iterationDuration = 100; |
| - timing.startDelay = 100; |
| - timing.endDelay = 100; |
| - timing.fillMode = Timing::FillModeNone; |
| - RefPtrWillBeRawPtr<Animation> animation = Animation::create(0, nullptr, timing); |
| - RefPtrWillBeRawPtr<AnimationPlayer> player = document.timeline().play(animation.get()); |
| - double inf = std::numeric_limits<double>::infinity(); |
| + timing.startDelay = 1; |
| + timing.iterationDuration = 1; |
| + timing.endDelay = 1; |
| + RefPtrWillBeRawPtr<KeyframeEffect> animation = KeyframeEffect::create(0, nullptr, timing); |
|
alancutter (OOO until 2018)
2015/05/05 01:04:51
s/animation/keyframeEffect/g
dstockwell
2015/05/05 03:33:25
Done!!!
|
| + player = timeline->play(animation.get()); |
| + player->setStartTime(0); |
| - EXPECT_EQ(100, animation->timeToForwardsEffectChange()); |
| - EXPECT_EQ(inf, animation->timeToReverseEffectChange()); |
| + simulateFrame(0); |
| + EXPECT_EQ(1, player->timeToEffectChange()); |
| - player->setCurrentTimeInternal(100); |
| - EXPECT_EQ(100, animation->timeToForwardsEffectChange()); |
| - EXPECT_EQ(0, animation->timeToReverseEffectChange()); |
| + simulateFrame(0.5); |
| + EXPECT_EQ(0.5, player->timeToEffectChange()); |
| - player->setCurrentTimeInternal(199); |
| - EXPECT_EQ(1, animation->timeToForwardsEffectChange()); |
| - EXPECT_EQ(0, animation->timeToReverseEffectChange()); |
| + simulateFrame(1); |
| + EXPECT_EQ(0, player->timeToEffectChange()); |
| - player->setCurrentTimeInternal(200); |
| - // End-exclusive. |
| - EXPECT_EQ(inf, animation->timeToForwardsEffectChange()); |
| - EXPECT_EQ(0, animation->timeToReverseEffectChange()); |
| + simulateFrame(1.5); |
| + EXPECT_EQ(0, player->timeToEffectChange()); |
| - player->setCurrentTimeInternal(300); |
| - EXPECT_EQ(inf, animation->timeToForwardsEffectChange()); |
| - EXPECT_EQ(100, animation->timeToReverseEffectChange()); |
| -} |
| + simulateFrame(2); |
| + EXPECT_EQ(std::numeric_limits<double>::infinity(), player->timeToEffectChange()); |
| -TEST_F(AnimationAnimationTest, TimeToEffectChangeWithPlaybackRate) |
| -{ |
| - Timing timing; |
| - timing.iterationDuration = 100; |
| - timing.startDelay = 100; |
| - timing.endDelay = 100; |
| - timing.playbackRate = 2; |
| - timing.fillMode = Timing::FillModeNone; |
| - RefPtrWillBeRawPtr<Animation> animation = Animation::create(0, nullptr, timing); |
| - RefPtrWillBeRawPtr<AnimationPlayer> player = document.timeline().play(animation.get()); |
| - double inf = std::numeric_limits<double>::infinity(); |
| + simulateFrame(3); |
| + EXPECT_EQ(std::numeric_limits<double>::infinity(), player->timeToEffectChange()); |
| + |
| + player->setCurrentTimeInternal(0); |
| + simulateFrame(3); |
| + EXPECT_EQ(1, player->timeToEffectChange()); |
| - EXPECT_EQ(100, animation->timeToForwardsEffectChange()); |
| - EXPECT_EQ(inf, animation->timeToReverseEffectChange()); |
| + player->setPlaybackRate(2); |
| + simulateFrame(3); |
| + EXPECT_EQ(0.5, player->timeToEffectChange()); |
| - player->setCurrentTimeInternal(100); |
| - EXPECT_EQ(50, animation->timeToForwardsEffectChange()); |
| - EXPECT_EQ(0, animation->timeToReverseEffectChange()); |
| + player->setPlaybackRate(0); |
| + player->update(TimingUpdateOnDemand); |
| + EXPECT_EQ(std::numeric_limits<double>::infinity(), player->timeToEffectChange()); |
| - player->setCurrentTimeInternal(149); |
| - EXPECT_EQ(1, animation->timeToForwardsEffectChange()); |
| - EXPECT_EQ(0, animation->timeToReverseEffectChange()); |
| + player->setCurrentTimeInternal(3); |
| + player->setPlaybackRate(-1); |
| + player->update(TimingUpdateOnDemand); |
| + simulateFrame(3); |
| + EXPECT_EQ(1, player->timeToEffectChange()); |
| - player->setCurrentTimeInternal(150); |
| - // End-exclusive. |
| - EXPECT_EQ(inf, animation->timeToForwardsEffectChange()); |
| - EXPECT_EQ(0, animation->timeToReverseEffectChange()); |
| + player->setPlaybackRate(-2); |
| + player->update(TimingUpdateOnDemand); |
| + simulateFrame(3); |
| + EXPECT_EQ(0.5, player->timeToEffectChange()); |
| +} |
| + |
| +TEST_F(AnimationAnimationTest, TimeToNextEffectWhenPaused) |
| +{ |
| + EXPECT_EQ(0, player->timeToEffectChange()); |
| + player->pause(); |
| + player->update(TimingUpdateOnDemand); |
| + EXPECT_EQ(std::numeric_limits<double>::infinity(), player->timeToEffectChange()); |
| +} |
| - player->setCurrentTimeInternal(200); |
| - EXPECT_EQ(inf, animation->timeToForwardsEffectChange()); |
| - EXPECT_EQ(50, animation->timeToReverseEffectChange()); |
| +TEST_F(AnimationAnimationTest, TimeToNextEffectWhenCancelledBeforeStart) |
| +{ |
| + EXPECT_EQ(0, player->timeToEffectChange()); |
| + player->setCurrentTimeInternal(-8); |
| + player->setPlaybackRate(2); |
| + EXPECT_EQ(Animation::Pending, player->playStateInternal()); |
| + player->cancel(); |
| + EXPECT_EQ(Animation::Idle, player->playStateInternal()); |
| + player->update(TimingUpdateOnDemand); |
| + // This frame will fire the finish event event though no start time has been |
| + // received from the compositor yet, as cancel() nukes start times. |
| + simulateFrame(0); |
| + EXPECT_EQ(std::numeric_limits<double>::infinity(), player->timeToEffectChange()); |
| +} |
| + |
| +TEST_F(AnimationAnimationTest, TimeToNextEffectWhenCancelledBeforeStartReverse) |
| +{ |
| + EXPECT_EQ(0, player->timeToEffectChange()); |
| + player->setCurrentTimeInternal(9); |
| + player->setPlaybackRate(-3); |
| + EXPECT_EQ(Animation::Pending, player->playStateInternal()); |
| + player->cancel(); |
| + EXPECT_EQ(Animation::Idle, player->playStateInternal()); |
| + player->update(TimingUpdateOnDemand); |
| + // This frame will fire the finish event event though no start time has been |
| + // received from the compositor yet, as cancel() nukes start times. |
| + simulateFrame(0); |
| + EXPECT_EQ(std::numeric_limits<double>::infinity(), player->timeToEffectChange()); |
| +} |
| + |
| +TEST_F(AnimationAnimationTest, TimeToNextEffectSimpleCancelledBeforeStart) |
| +{ |
| + EXPECT_EQ(0, player->timeToEffectChange()); |
| + EXPECT_EQ(Animation::Running, player->playStateInternal()); |
| + player->cancel(); |
| + player->update(TimingUpdateOnDemand); |
| + // This frame will fire the finish event event though no start time has been |
| + // received from the compositor yet, as cancel() nukes start times. |
| + simulateFrame(0); |
| + EXPECT_EQ(std::numeric_limits<double>::infinity(), player->timeToEffectChange()); |
| } |
| -TEST_F(AnimationAnimationTest, TimeToEffectChangeWithNegativePlaybackRate) |
| +TEST_F(AnimationAnimationTest, AttachedAnimations) |
| { |
| + RefPtrWillBePersistent<Element> element = document->createElement("foo", ASSERT_NO_EXCEPTION); |
| + |
| Timing timing; |
| - timing.iterationDuration = 100; |
| - timing.startDelay = 100; |
| - timing.endDelay = 100; |
| - timing.playbackRate = -2; |
| - timing.fillMode = Timing::FillModeNone; |
| - RefPtrWillBeRawPtr<Animation> animation = Animation::create(0, nullptr, timing); |
| - RefPtrWillBeRawPtr<AnimationPlayer> player = document.timeline().play(animation.get()); |
| - double inf = std::numeric_limits<double>::infinity(); |
| + RefPtrWillBeRawPtr<KeyframeEffect> animation = KeyframeEffect::create(element.get(), nullptr, timing); |
| + RefPtrWillBeRawPtr<Animation> player = timeline->play(animation.get()); |
| + simulateFrame(0); |
| + timeline->serviceAnimations(TimingUpdateForAnimationFrame); |
| + EXPECT_EQ(1U, element->elementAnimations()->animations().find(player.get())->value); |
| + |
| + player.release(); |
| + Heap::collectAllGarbage(); |
| + EXPECT_TRUE(element->elementAnimations()->animations().isEmpty()); |
| +} |
| - EXPECT_EQ(100, animation->timeToForwardsEffectChange()); |
| - EXPECT_EQ(inf, animation->timeToReverseEffectChange()); |
| +TEST_F(AnimationAnimationTest, HasLowerPriority) |
| +{ |
| + RefPtrWillBeRawPtr<Animation> player1 = timeline->play(0); |
| + RefPtrWillBeRawPtr<Animation> player2 = timeline->play(0); |
| + EXPECT_TRUE(Animation::hasLowerPriority(player1.get(), player2.get())); |
| +} |
| - player->setCurrentTimeInternal(100); |
| - EXPECT_EQ(50, animation->timeToForwardsEffectChange()); |
| - EXPECT_EQ(0, animation->timeToReverseEffectChange()); |
| +TEST_F(AnimationAnimationTest, PlayAfterCancel) |
| +{ |
| + player->cancel(); |
| + EXPECT_EQ(Animation::Idle, player->playStateInternal()); |
| + EXPECT_TRUE(std::isnan(player->currentTime())); |
| + EXPECT_TRUE(std::isnan(player->startTime())); |
| + player->play(); |
| + EXPECT_EQ(Animation::Pending, player->playStateInternal()); |
| + EXPECT_EQ(0, player->currentTime()); |
| + EXPECT_TRUE(std::isnan(player->startTime())); |
| + simulateFrame(10); |
| + EXPECT_EQ(Animation::Running, player->playStateInternal()); |
| + EXPECT_EQ(0, player->currentTime()); |
| + EXPECT_EQ(10 * 1000, player->startTime()); |
| +} |
| - player->setCurrentTimeInternal(149); |
| - EXPECT_EQ(1, animation->timeToForwardsEffectChange()); |
| - EXPECT_EQ(0, animation->timeToReverseEffectChange()); |
| +TEST_F(AnimationAnimationTest, PlayBackwardsAfterCancel) |
| +{ |
| + player->setPlaybackRate(-1); |
| + player->setCurrentTime(15 * 1000); |
| + simulateFrame(0); |
| + player->cancel(); |
| + EXPECT_EQ(Animation::Idle, player->playStateInternal()); |
| + EXPECT_TRUE(std::isnan(player->currentTime())); |
| + EXPECT_TRUE(std::isnan(player->startTime())); |
| + player->play(); |
| + EXPECT_EQ(Animation::Pending, player->playStateInternal()); |
| + EXPECT_EQ(30 * 1000, player->currentTime()); |
| + EXPECT_TRUE(std::isnan(player->startTime())); |
| + simulateFrame(10); |
| + EXPECT_EQ(Animation::Running, player->playStateInternal()); |
| + EXPECT_EQ(30 * 1000, player->currentTime()); |
| + EXPECT_EQ(40 * 1000, player->startTime()); |
| +} |
| - player->setCurrentTimeInternal(150); |
| - EXPECT_EQ(inf, animation->timeToForwardsEffectChange()); |
| - EXPECT_EQ(0, animation->timeToReverseEffectChange()); |
| +TEST_F(AnimationAnimationTest, ReverseAfterCancel) |
| +{ |
| + player->cancel(); |
| + EXPECT_EQ(Animation::Idle, player->playStateInternal()); |
| + EXPECT_TRUE(std::isnan(player->currentTime())); |
| + EXPECT_TRUE(std::isnan(player->startTime())); |
| + player->reverse(); |
| + EXPECT_EQ(Animation::Pending, player->playStateInternal()); |
| + EXPECT_EQ(30 * 1000, player->currentTime()); |
| + EXPECT_TRUE(std::isnan(player->startTime())); |
| + simulateFrame(10); |
| + EXPECT_EQ(Animation::Running, player->playStateInternal()); |
| + EXPECT_EQ(30 * 1000, player->currentTime()); |
| + EXPECT_EQ(40 * 1000, player->startTime()); |
| +} |
| - player->setCurrentTimeInternal(200); |
| - EXPECT_EQ(inf, animation->timeToForwardsEffectChange()); |
| - EXPECT_EQ(50, animation->timeToReverseEffectChange()); |
| +TEST_F(AnimationAnimationTest, FinishAfterCancel) |
| +{ |
| + player->cancel(); |
| + EXPECT_EQ(Animation::Idle, player->playStateInternal()); |
| + EXPECT_TRUE(std::isnan(player->currentTime())); |
| + EXPECT_TRUE(std::isnan(player->startTime())); |
| + player->finish(exceptionState); |
| + EXPECT_TRUE(std::isnan(player->currentTime())); |
| + EXPECT_TRUE(std::isnan(player->startTime())); |
| + EXPECT_EQ(Animation::Idle, player->playStateInternal()); |
| } |
| -TEST_F(AnimationAnimationTest, ElementDestructorClearsAnimationTarget) |
| +TEST_F(AnimationAnimationTest, PauseAfterCancel) |
| { |
| - // This test expects incorrect behaviour should be removed once Element |
| - // and Animation are moved to Oilpan. See crbug.com/362404 for context. |
| - Timing timing; |
| - timing.iterationDuration = 5; |
| - RefPtrWillBeRawPtr<Animation> animation = Animation::create(element.get(), nullptr, timing); |
| - EXPECT_EQ(element.get(), animation->target()); |
| - document.timeline().play(animation.get()); |
| - pageHolder.clear(); |
| - element.clear(); |
| -#if !ENABLE(OILPAN) |
| - EXPECT_EQ(0, animation->target()); |
| -#endif |
| -} |
| - |
| -} // namespace blink |
| + player->cancel(); |
| + EXPECT_EQ(Animation::Idle, player->playStateInternal()); |
| + EXPECT_TRUE(std::isnan(player->currentTime())); |
| + EXPECT_TRUE(std::isnan(player->startTime())); |
| + player->pause(); |
| + EXPECT_EQ(Animation::Idle, player->playStateInternal()); |
| + EXPECT_TRUE(std::isnan(player->currentTime())); |
| + EXPECT_TRUE(std::isnan(player->startTime())); |
| +} |
| + |
| +} |