OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 /* |
2 // Use of this source code is governed by a BSD-style license that can be | 2 * Copyright (c) 2013, Google Inc. All rights reserved. |
3 // found in the LICENSE file. | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are |
| 6 * met: |
| 7 * |
| 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above |
| 11 * copyright notice, this list of conditions and the following disclaimer |
| 12 * in the documentation and/or other materials provided with the |
| 13 * distribution. |
| 14 * * Neither the name of Google Inc. nor the names of its |
| 15 * contributors may be used to endorse or promote products derived from |
| 16 * this software without specific prior written permission. |
| 17 * |
| 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ |
4 | 30 |
5 #include "config.h" | 31 #include "config.h" |
6 #include "core/animation/Animation.h" | 32 #include "core/animation/Animation.h" |
7 | 33 |
8 #include "bindings/core/v8/Dictionary.h" | |
9 #include "bindings/core/v8/UnionTypesCore.h" | |
10 #include "bindings/core/v8/V8AnimationTimingProperties.h" | |
11 #include "bindings/core/v8/V8BindingForTesting.h" | |
12 #include "core/animation/AnimationClock.h" | 34 #include "core/animation/AnimationClock.h" |
13 #include "core/animation/AnimationNodeTiming.h" | |
14 #include "core/animation/AnimationTestHelper.h" | |
15 #include "core/animation/AnimationTimeline.h" | 35 #include "core/animation/AnimationTimeline.h" |
16 #include "core/animation/KeyframeEffectModel.h" | 36 #include "core/animation/ElementAnimations.h" |
17 #include "core/animation/Timing.h" | 37 #include "core/animation/KeyframeEffect.h" |
18 #include "core/dom/Document.h" | 38 #include "core/dom/Document.h" |
19 #include "core/dom/ExceptionCode.h" | 39 #include "core/dom/ExceptionCode.h" |
20 #include "core/testing/DummyPageHolder.h" | 40 #include "core/dom/QualifiedName.h" |
| 41 #include "platform/weborigin/KURL.h" |
21 #include <gtest/gtest.h> | 42 #include <gtest/gtest.h> |
22 #include <v8.h> | 43 |
23 | 44 using namespace blink; |
24 namespace blink { | 45 |
| 46 namespace { |
25 | 47 |
26 class AnimationAnimationTest : public ::testing::Test { | 48 class AnimationAnimationTest : public ::testing::Test { |
27 protected: | 49 protected: |
28 AnimationAnimationTest() | 50 virtual void SetUp() |
29 : pageHolder(DummyPageHolder::create()) | |
30 , document(pageHolder->document()) | |
31 , element(document.createElement("foo", ASSERT_NO_EXCEPTION)) | |
32 { | 51 { |
33 document.animationClock().resetTimeForTesting(document.timeline().zeroTi
me()); | 52 setUpWithoutStartingTimeline(); |
34 EXPECT_EQ(0, document.timeline().currentTime()); | 53 startTimeline(); |
35 } | 54 } |
36 | 55 |
37 OwnPtr<DummyPageHolder> pageHolder; | 56 void setUpWithoutStartingTimeline() |
38 Document& document; | 57 { |
39 RefPtrWillBePersistent<Element> element; | 58 document = Document::create(); |
| 59 document->animationClock().resetTimeForTesting(); |
| 60 timeline = AnimationTimeline::create(document.get()); |
| 61 animation = timeline->play(0); |
| 62 animation->setStartTime(0); |
| 63 animation->setSource(makeAnimation().get()); |
| 64 } |
| 65 |
| 66 void startTimeline() |
| 67 { |
| 68 simulateFrame(0); |
| 69 } |
| 70 |
| 71 PassRefPtrWillBeRawPtr<KeyframeEffect> makeAnimation(double duration = 30, d
ouble playbackRate = 1) |
| 72 { |
| 73 Timing timing; |
| 74 timing.iterationDuration = duration; |
| 75 timing.playbackRate = playbackRate; |
| 76 return KeyframeEffect::create(0, nullptr, timing); |
| 77 } |
| 78 |
| 79 bool simulateFrame(double time) |
| 80 { |
| 81 document->animationClock().updateTime(time); |
| 82 document->compositorPendingAnimations().update(false); |
| 83 // The timeline does not know about our animation, so we have to explici
tly call update(). |
| 84 return animation->update(TimingUpdateForAnimationFrame); |
| 85 } |
| 86 |
| 87 RefPtrWillBePersistent<Document> document; |
| 88 RefPtrWillBePersistent<AnimationTimeline> timeline; |
| 89 RefPtrWillBePersistent<Animation> animation; |
40 TrackExceptionState exceptionState; | 90 TrackExceptionState exceptionState; |
41 }; | 91 }; |
42 | 92 |
43 class AnimationAnimationV8Test : public AnimationAnimationTest { | 93 TEST_F(AnimationAnimationTest, InitialState) |
44 protected: | 94 { |
45 AnimationAnimationV8Test() | 95 setUpWithoutStartingTimeline(); |
46 : m_isolate(v8::Isolate::GetCurrent()) | 96 animation = timeline->play(0); |
47 , m_scope(m_isolate) | 97 EXPECT_EQ(Animation::Pending, animation->playStateInternal()); |
48 { | 98 EXPECT_EQ(0, animation->currentTimeInternal()); |
49 } | 99 EXPECT_FALSE(animation->paused()); |
50 | 100 EXPECT_EQ(1, animation->playbackRate()); |
51 template<typename T> | 101 EXPECT_FALSE(animation->hasStartTime()); |
52 static PassRefPtrWillBeRawPtr<Animation> createAnimation(Element* element, V
ector<Dictionary> keyframeDictionaryVector, T timingInput, ExceptionState& excep
tionState) | 102 EXPECT_TRUE(isNull(animation->startTimeInternal())); |
53 { | 103 |
54 return Animation::create(element, keyframeDictionaryVector, timingInput,
exceptionState); | 104 startTimeline(); |
55 } | 105 EXPECT_EQ(Animation::Finished, animation->playStateInternal()); |
56 static PassRefPtrWillBeRawPtr<Animation> createAnimation(Element* element, V
ector<Dictionary> keyframeDictionaryVector, ExceptionState& exceptionState) | 106 EXPECT_EQ(0, timeline->currentTimeInternal()); |
57 { | 107 EXPECT_EQ(0, animation->currentTimeInternal()); |
58 return Animation::create(element, keyframeDictionaryVector, exceptionSta
te); | 108 EXPECT_FALSE(animation->paused()); |
59 } | 109 EXPECT_EQ(1, animation->playbackRate()); |
60 | 110 EXPECT_EQ(0, animation->startTimeInternal()); |
61 v8::Isolate* m_isolate; | 111 EXPECT_TRUE(animation->hasStartTime()); |
62 | 112 } |
63 private: | 113 |
64 V8TestingScope m_scope; | 114 |
65 }; | 115 TEST_F(AnimationAnimationTest, CurrentTimeDoesNotSetOutdated) |
66 | 116 { |
67 TEST_F(AnimationAnimationV8Test, CanCreateAnAnimation) | 117 EXPECT_FALSE(animation->outdated()); |
68 { | 118 EXPECT_EQ(0, animation->currentTimeInternal()); |
69 Vector<Dictionary> jsKeyframes; | 119 EXPECT_FALSE(animation->outdated()); |
70 v8::Local<v8::Object> keyframe1 = v8::Object::New(m_isolate); | 120 // FIXME: We should split simulateFrame into a version that doesn't update |
71 v8::Local<v8::Object> keyframe2 = v8::Object::New(m_isolate); | 121 // the animation and one that does, as most of the tests don't require updat
e() |
72 | 122 // to be called. |
73 setV8ObjectPropertyAsString(keyframe1, "width", "100px"); | 123 document->animationClock().updateTime(10); |
74 setV8ObjectPropertyAsString(keyframe1, "offset", "0"); | 124 EXPECT_EQ(10, animation->currentTimeInternal()); |
75 setV8ObjectPropertyAsString(keyframe1, "easing", "ease-in-out"); | 125 EXPECT_FALSE(animation->outdated()); |
76 setV8ObjectPropertyAsString(keyframe2, "width", "0px"); | 126 } |
77 setV8ObjectPropertyAsString(keyframe2, "offset", "1"); | 127 |
78 setV8ObjectPropertyAsString(keyframe2, "easing", "cubic-bezier(1, 1, 0.3, 0.
3)"); | 128 TEST_F(AnimationAnimationTest, SetCurrentTime) |
79 | 129 { |
80 jsKeyframes.append(Dictionary(keyframe1, m_isolate, exceptionState)); | 130 EXPECT_EQ(Animation::Running, animation->playStateInternal()); |
81 jsKeyframes.append(Dictionary(keyframe2, m_isolate, exceptionState)); | 131 animation->setCurrentTimeInternal(10); |
82 | 132 EXPECT_EQ(Animation::Running, animation->playStateInternal()); |
83 String value1; | 133 EXPECT_EQ(10, animation->currentTimeInternal()); |
84 ASSERT_TRUE(DictionaryHelper::get(jsKeyframes[0], "width", value1)); | 134 simulateFrame(10); |
85 ASSERT_EQ("100px", value1); | 135 EXPECT_EQ(Animation::Running, animation->playStateInternal()); |
86 | 136 EXPECT_EQ(20, animation->currentTimeInternal()); |
87 String value2; | 137 } |
88 ASSERT_TRUE(DictionaryHelper::get(jsKeyframes[1], "width", value2)); | 138 |
89 ASSERT_EQ("0px", value2); | 139 TEST_F(AnimationAnimationTest, SetCurrentTimeNegative) |
90 | 140 { |
91 RefPtrWillBeRawPtr<Animation> animation = createAnimation(element.get(), jsK
eyframes, 0, exceptionState); | 141 animation->setCurrentTimeInternal(-10); |
92 | 142 EXPECT_EQ(Animation::Running, animation->playStateInternal()); |
93 Element* target = animation->target(); | 143 EXPECT_EQ(-10, animation->currentTimeInternal()); |
94 EXPECT_EQ(*element.get(), *target); | 144 simulateFrame(20); |
95 | 145 EXPECT_EQ(10, animation->currentTimeInternal()); |
96 const KeyframeVector keyframes = toKeyframeEffectModelBase(animation->effect
())->getFrames(); | 146 |
97 | 147 animation->setPlaybackRate(-2); |
98 EXPECT_EQ(0, keyframes[0]->offset()); | 148 animation->setCurrentTimeInternal(-10); |
99 EXPECT_EQ(1, keyframes[1]->offset()); | 149 EXPECT_EQ(Animation::Pending, animation->playStateInternal()); |
100 | 150 EXPECT_EQ(-10, animation->currentTimeInternal()); |
101 const CSSValue* keyframe1Width = toStringKeyframe(keyframes[0].get())->cssPr
opertyValue(CSSPropertyWidth); | 151 simulateFrame(40); |
102 const CSSValue* keyframe2Width = toStringKeyframe(keyframes[1].get())->cssPr
opertyValue(CSSPropertyWidth); | 152 EXPECT_EQ(Animation::Finished, animation->playStateInternal()); |
103 ASSERT(keyframe1Width); | 153 EXPECT_EQ(-10, animation->currentTimeInternal()); |
104 ASSERT(keyframe2Width); | 154 } |
105 | 155 |
106 EXPECT_EQ("100px", keyframe1Width->cssText()); | 156 TEST_F(AnimationAnimationTest, SetCurrentTimeNegativeWithoutSimultaneousPlayback
RateChange) |
107 EXPECT_EQ("0px", keyframe2Width->cssText()); | 157 { |
108 | 158 simulateFrame(20); |
109 EXPECT_EQ(*(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Eas
eInOut)), keyframes[0]->easing()); | 159 EXPECT_EQ(20, animation->currentTimeInternal()); |
110 EXPECT_EQ(*(CubicBezierTimingFunction::create(1, 1, 0.3, 0.3).get()), keyfra
mes[1]->easing()); | 160 EXPECT_EQ(Animation::Running, animation->playStateInternal()); |
111 } | 161 animation->setPlaybackRate(-1); |
112 | 162 EXPECT_EQ(Animation::Pending, animation->playStateInternal()); |
113 TEST_F(AnimationAnimationV8Test, CanSetDuration) | 163 simulateFrame(30); |
114 { | 164 EXPECT_EQ(20, animation->currentTimeInternal()); |
115 Vector<Dictionary, 0> jsKeyframes; | 165 EXPECT_EQ(Animation::Running, animation->playStateInternal()); |
116 double duration = 2000; | 166 animation->setCurrentTime(-10 * 1000); |
117 | 167 EXPECT_EQ(Animation::Finished, animation->playStateInternal()); |
118 RefPtrWillBeRawPtr<Animation> animation = createAnimation(element.get(), jsK
eyframes, duration, exceptionState); | 168 } |
119 | 169 |
120 EXPECT_EQ(duration / 1000, animation->specifiedTiming().iterationDuration); | 170 TEST_F(AnimationAnimationTest, SetCurrentTimePastContentEnd) |
121 } | 171 { |
122 | 172 animation->setCurrentTime(50 * 1000); |
123 TEST_F(AnimationAnimationV8Test, CanOmitSpecifiedDuration) | 173 EXPECT_EQ(Animation::Finished, animation->playStateInternal()); |
124 { | 174 EXPECT_EQ(50, animation->currentTimeInternal()); |
125 Vector<Dictionary, 0> jsKeyframes; | 175 simulateFrame(20); |
126 RefPtrWillBeRawPtr<Animation> animation = createAnimation(element.get(), jsK
eyframes, exceptionState); | 176 EXPECT_EQ(Animation::Finished, animation->playStateInternal()); |
127 EXPECT_TRUE(std::isnan(animation->specifiedTiming().iterationDuration)); | 177 EXPECT_EQ(50, animation->currentTimeInternal()); |
128 } | 178 |
129 | 179 animation->setPlaybackRate(-2); |
130 TEST_F(AnimationAnimationV8Test, NegativeDurationIsAuto) | 180 animation->setCurrentTime(50 * 1000); |
131 { | 181 EXPECT_EQ(Animation::Pending, animation->playStateInternal()); |
132 Vector<Dictionary, 0> jsKeyframes; | 182 EXPECT_EQ(50, animation->currentTimeInternal()); |
133 RefPtrWillBeRawPtr<Animation> animation = createAnimation(element.get(), jsK
eyframes, -2, exceptionState); | 183 simulateFrame(20); |
134 EXPECT_TRUE(std::isnan(animation->specifiedTiming().iterationDuration)); | 184 EXPECT_EQ(Animation::Running, animation->playStateInternal()); |
135 } | 185 simulateFrame(40); |
136 | 186 EXPECT_EQ(10, animation->currentTimeInternal()); |
137 TEST_F(AnimationAnimationV8Test, MismatchedKeyframePropertyRaisesException) | 187 } |
138 { | 188 |
139 Vector<Dictionary> jsKeyframes; | 189 TEST_F(AnimationAnimationTest, SetCurrentTimeBeforeTimelineStarted) |
140 v8::Local<v8::Object> keyframe1 = v8::Object::New(m_isolate); | 190 { |
141 v8::Local<v8::Object> keyframe2 = v8::Object::New(m_isolate); | 191 setUpWithoutStartingTimeline(); |
142 | 192 animation->setCurrentTimeInternal(5); |
143 setV8ObjectPropertyAsString(keyframe1, "width", "100px"); | 193 EXPECT_EQ(5, animation->currentTimeInternal()); |
144 setV8ObjectPropertyAsString(keyframe1, "offset", "0"); | 194 startTimeline(); |
145 | 195 simulateFrame(10); |
146 // Height property appears only in keyframe2 | 196 EXPECT_EQ(15, animation->currentTimeInternal()); |
147 setV8ObjectPropertyAsString(keyframe2, "height", "100px"); | 197 } |
148 setV8ObjectPropertyAsString(keyframe2, "width", "0px"); | 198 |
149 setV8ObjectPropertyAsString(keyframe2, "offset", "1"); | 199 TEST_F(AnimationAnimationTest, SetCurrentTimePastContentEndBeforeTimelineStarted
) |
150 | 200 { |
151 jsKeyframes.append(Dictionary(keyframe1, m_isolate, exceptionState)); | 201 setUpWithoutStartingTimeline(); |
152 jsKeyframes.append(Dictionary(keyframe2, m_isolate, exceptionState)); | 202 animation->setCurrentTime(250 * 1000); |
153 | 203 EXPECT_EQ(250, animation->currentTimeInternal()); |
154 createAnimation(element.get(), jsKeyframes, 0, exceptionState); | 204 startTimeline(); |
155 | 205 simulateFrame(10); |
| 206 EXPECT_EQ(250, animation->currentTimeInternal()); |
| 207 } |
| 208 |
| 209 TEST_F(AnimationAnimationTest, SetCurrentTimeMax) |
| 210 { |
| 211 animation->setCurrentTimeInternal(std::numeric_limits<double>::max()); |
| 212 EXPECT_EQ(std::numeric_limits<double>::max(), animation->currentTimeInternal
()); |
| 213 simulateFrame(100); |
| 214 EXPECT_EQ(std::numeric_limits<double>::max(), animation->currentTimeInternal
()); |
| 215 } |
| 216 |
| 217 TEST_F(AnimationAnimationTest, SetCurrentTimeSetsStartTime) |
| 218 { |
| 219 EXPECT_EQ(0, animation->startTime()); |
| 220 animation->setCurrentTime(1000); |
| 221 EXPECT_EQ(-1000, animation->startTime()); |
| 222 simulateFrame(1); |
| 223 EXPECT_EQ(-1000, animation->startTime()); |
| 224 EXPECT_EQ(2000, animation->currentTime()); |
| 225 } |
| 226 |
| 227 TEST_F(AnimationAnimationTest, SetStartTime) |
| 228 { |
| 229 simulateFrame(20); |
| 230 EXPECT_EQ(Animation::Running, animation->playStateInternal()); |
| 231 EXPECT_EQ(0, animation->startTimeInternal()); |
| 232 EXPECT_EQ(20 * 1000, animation->currentTime()); |
| 233 animation->setStartTime(10 * 1000); |
| 234 EXPECT_EQ(Animation::Running, animation->playStateInternal()); |
| 235 EXPECT_EQ(10, animation->startTimeInternal()); |
| 236 EXPECT_EQ(10 * 1000, animation->currentTime()); |
| 237 simulateFrame(30); |
| 238 EXPECT_EQ(10, animation->startTimeInternal()); |
| 239 EXPECT_EQ(20 * 1000, animation->currentTime()); |
| 240 animation->setStartTime(-20 * 1000); |
| 241 EXPECT_EQ(Animation::Finished, animation->playStateInternal()); |
| 242 } |
| 243 |
| 244 TEST_F(AnimationAnimationTest, SetStartTimeLimitsAnimation) |
| 245 { |
| 246 animation->setStartTime(-50 * 1000); |
| 247 EXPECT_EQ(Animation::Finished, animation->playStateInternal()); |
| 248 EXPECT_EQ(30, animation->currentTimeInternal()); |
| 249 animation->setPlaybackRate(-1); |
| 250 EXPECT_EQ(Animation::Pending, animation->playStateInternal()); |
| 251 animation->setStartTime(-100 * 1000); |
| 252 EXPECT_EQ(Animation::Finished, animation->playStateInternal()); |
| 253 EXPECT_EQ(0, animation->currentTimeInternal()); |
| 254 EXPECT_TRUE(animation->limited()); |
| 255 } |
| 256 |
| 257 TEST_F(AnimationAnimationTest, SetStartTimeOnLimitedAnimation) |
| 258 { |
| 259 simulateFrame(30); |
| 260 animation->setStartTime(-10 * 1000); |
| 261 EXPECT_EQ(Animation::Finished, animation->playStateInternal()); |
| 262 EXPECT_EQ(30, animation->currentTimeInternal()); |
| 263 animation->setCurrentTimeInternal(50); |
| 264 animation->setStartTime(-40 * 1000); |
| 265 EXPECT_EQ(30, animation->currentTimeInternal()); |
| 266 EXPECT_EQ(Animation::Finished, animation->playStateInternal()); |
| 267 EXPECT_TRUE(animation->limited()); |
| 268 } |
| 269 |
| 270 TEST_F(AnimationAnimationTest, StartTimePauseFinish) |
| 271 { |
| 272 animation->pause(); |
| 273 EXPECT_EQ(Animation::Pending, animation->playStateInternal()); |
| 274 EXPECT_TRUE(std::isnan(animation->startTime())); |
| 275 animation->finish(exceptionState); |
| 276 EXPECT_EQ(Animation::Paused, animation->playStateInternal()); |
| 277 EXPECT_TRUE(std::isnan(animation->startTime())); |
| 278 } |
| 279 |
| 280 TEST_F(AnimationAnimationTest, PauseBeatsFinish) |
| 281 { |
| 282 animation->pause(); |
| 283 EXPECT_EQ(Animation::Pending, animation->playStateInternal()); |
| 284 simulateFrame(10); |
| 285 EXPECT_EQ(Animation::Paused, animation->playStateInternal()); |
| 286 animation->finish(exceptionState); |
| 287 EXPECT_EQ(Animation::Paused, animation->playStateInternal()); |
| 288 } |
| 289 |
| 290 TEST_F(AnimationAnimationTest, StartTimeFinishPause) |
| 291 { |
| 292 animation->finish(exceptionState); |
| 293 EXPECT_EQ(-30 * 1000, animation->startTime()); |
| 294 animation->pause(); |
| 295 EXPECT_TRUE(std::isnan(animation->startTime())); |
| 296 } |
| 297 |
| 298 TEST_F(AnimationAnimationTest, StartTimeWithZeroPlaybackRate) |
| 299 { |
| 300 animation->setPlaybackRate(0); |
| 301 EXPECT_EQ(Animation::Pending, animation->playStateInternal()); |
| 302 EXPECT_TRUE(std::isnan(animation->startTime())); |
| 303 simulateFrame(10); |
| 304 EXPECT_EQ(Animation::Running, animation->playStateInternal()); |
| 305 } |
| 306 |
| 307 TEST_F(AnimationAnimationTest, PausePlay) |
| 308 { |
| 309 simulateFrame(10); |
| 310 animation->pause(); |
| 311 EXPECT_EQ(Animation::Pending, animation->playStateInternal()); |
| 312 EXPECT_TRUE(animation->paused()); |
| 313 EXPECT_EQ(10, animation->currentTimeInternal()); |
| 314 simulateFrame(20); |
| 315 EXPECT_EQ(Animation::Paused, animation->playStateInternal()); |
| 316 animation->play(); |
| 317 EXPECT_EQ(Animation::Pending, animation->playStateInternal()); |
| 318 simulateFrame(20); |
| 319 EXPECT_EQ(Animation::Running, animation->playStateInternal()); |
| 320 EXPECT_FALSE(animation->paused()); |
| 321 EXPECT_EQ(10, animation->currentTimeInternal()); |
| 322 simulateFrame(30); |
| 323 EXPECT_EQ(20, animation->currentTimeInternal()); |
| 324 } |
| 325 |
| 326 TEST_F(AnimationAnimationTest, PauseBeforeTimelineStarted) |
| 327 { |
| 328 setUpWithoutStartingTimeline(); |
| 329 animation->pause(); |
| 330 EXPECT_TRUE(animation->paused()); |
| 331 animation->play(); |
| 332 EXPECT_FALSE(animation->paused()); |
| 333 |
| 334 animation->pause(); |
| 335 startTimeline(); |
| 336 simulateFrame(100); |
| 337 EXPECT_TRUE(animation->paused()); |
| 338 EXPECT_EQ(0, animation->currentTimeInternal()); |
| 339 } |
| 340 |
| 341 TEST_F(AnimationAnimationTest, PlayRewindsToStart) |
| 342 { |
| 343 animation->setCurrentTimeInternal(30); |
| 344 animation->play(); |
| 345 EXPECT_EQ(0, animation->currentTimeInternal()); |
| 346 |
| 347 animation->setCurrentTimeInternal(40); |
| 348 animation->play(); |
| 349 EXPECT_EQ(0, animation->currentTimeInternal()); |
| 350 EXPECT_EQ(Animation::Pending, animation->playStateInternal()); |
| 351 simulateFrame(10); |
| 352 EXPECT_EQ(Animation::Running, animation->playStateInternal()); |
| 353 |
| 354 animation->setCurrentTimeInternal(-10); |
| 355 EXPECT_EQ(Animation::Running, animation->playStateInternal()); |
| 356 animation->play(); |
| 357 EXPECT_EQ(0, animation->currentTimeInternal()); |
| 358 EXPECT_EQ(Animation::Pending, animation->playStateInternal()); |
| 359 simulateFrame(10); |
| 360 EXPECT_EQ(Animation::Running, animation->playStateInternal()); |
| 361 } |
| 362 |
| 363 TEST_F(AnimationAnimationTest, PlayRewindsToEnd) |
| 364 { |
| 365 animation->setPlaybackRate(-1); |
| 366 animation->play(); |
| 367 EXPECT_EQ(30, animation->currentTimeInternal()); |
| 368 |
| 369 animation->setCurrentTimeInternal(40); |
| 370 EXPECT_EQ(Animation::Pending, animation->playStateInternal()); |
| 371 animation->play(); |
| 372 EXPECT_EQ(30, animation->currentTimeInternal()); |
| 373 EXPECT_EQ(Animation::Pending, animation->playStateInternal()); |
| 374 simulateFrame(10); |
| 375 EXPECT_EQ(Animation::Running, animation->playStateInternal()); |
| 376 |
| 377 animation->setCurrentTimeInternal(-10); |
| 378 animation->play(); |
| 379 EXPECT_EQ(30, animation->currentTimeInternal()); |
| 380 EXPECT_EQ(Animation::Pending, animation->playStateInternal()); |
| 381 simulateFrame(20); |
| 382 EXPECT_EQ(Animation::Running, animation->playStateInternal()); |
| 383 } |
| 384 |
| 385 TEST_F(AnimationAnimationTest, PlayWithPlaybackRateZeroDoesNotSeek) |
| 386 { |
| 387 animation->setPlaybackRate(0); |
| 388 animation->play(); |
| 389 EXPECT_EQ(0, animation->currentTimeInternal()); |
| 390 |
| 391 animation->setCurrentTimeInternal(40); |
| 392 animation->play(); |
| 393 EXPECT_EQ(40, animation->currentTimeInternal()); |
| 394 |
| 395 animation->setCurrentTimeInternal(-10); |
| 396 animation->play(); |
| 397 EXPECT_EQ(-10, animation->currentTimeInternal()); |
| 398 } |
| 399 |
| 400 TEST_F(AnimationAnimationTest, PlayAfterPauseWithPlaybackRateZeroUpdatesPlayStat
e) |
| 401 { |
| 402 animation->pause(); |
| 403 animation->setPlaybackRate(0); |
| 404 simulateFrame(1); |
| 405 EXPECT_EQ(Animation::Paused, animation->playStateInternal()); |
| 406 animation->play(); |
| 407 EXPECT_EQ(Animation::Running, animation->playStateInternal()); |
| 408 } |
| 409 |
| 410 TEST_F(AnimationAnimationTest, Reverse) |
| 411 { |
| 412 animation->setCurrentTimeInternal(10); |
| 413 animation->pause(); |
| 414 animation->reverse(); |
| 415 EXPECT_FALSE(animation->paused()); |
| 416 EXPECT_EQ(-1, animation->playbackRate()); |
| 417 EXPECT_EQ(10, animation->currentTimeInternal()); |
| 418 } |
| 419 |
| 420 TEST_F(AnimationAnimationTest, ReverseDoesNothingWithPlaybackRateZero) |
| 421 { |
| 422 animation->setCurrentTimeInternal(10); |
| 423 animation->setPlaybackRate(0); |
| 424 animation->pause(); |
| 425 animation->reverse(); |
| 426 EXPECT_TRUE(animation->paused()); |
| 427 EXPECT_EQ(0, animation->playbackRate()); |
| 428 EXPECT_EQ(10, animation->currentTimeInternal()); |
| 429 } |
| 430 |
| 431 TEST_F(AnimationAnimationTest, ReverseDoesNotSeekWithNoSource) |
| 432 { |
| 433 animation->setSource(0); |
| 434 animation->setCurrentTimeInternal(10); |
| 435 animation->reverse(); |
| 436 EXPECT_EQ(10, animation->currentTimeInternal()); |
| 437 } |
| 438 |
| 439 TEST_F(AnimationAnimationTest, ReverseSeeksToStart) |
| 440 { |
| 441 animation->setCurrentTimeInternal(-10); |
| 442 animation->setPlaybackRate(-1); |
| 443 animation->reverse(); |
| 444 EXPECT_EQ(0, animation->currentTimeInternal()); |
| 445 } |
| 446 |
| 447 TEST_F(AnimationAnimationTest, ReverseSeeksToEnd) |
| 448 { |
| 449 animation->setCurrentTime(40 * 1000); |
| 450 animation->reverse(); |
| 451 EXPECT_EQ(30, animation->currentTimeInternal()); |
| 452 } |
| 453 |
| 454 TEST_F(AnimationAnimationTest, ReverseBeyondLimit) |
| 455 { |
| 456 animation->setCurrentTimeInternal(40); |
| 457 animation->setPlaybackRate(-1); |
| 458 animation->reverse(); |
| 459 EXPECT_EQ(Animation::Pending, animation->playStateInternal()); |
| 460 EXPECT_EQ(0, animation->currentTimeInternal()); |
| 461 |
| 462 animation->setCurrentTimeInternal(-10); |
| 463 animation->reverse(); |
| 464 EXPECT_EQ(Animation::Pending, animation->playStateInternal()); |
| 465 EXPECT_EQ(30, animation->currentTimeInternal()); |
| 466 } |
| 467 |
| 468 |
| 469 TEST_F(AnimationAnimationTest, Finish) |
| 470 { |
| 471 animation->finish(exceptionState); |
| 472 EXPECT_EQ(30, animation->currentTimeInternal()); |
| 473 EXPECT_EQ(Animation::Finished, animation->playStateInternal()); |
| 474 |
| 475 animation->setPlaybackRate(-1); |
| 476 animation->finish(exceptionState); |
| 477 EXPECT_EQ(0, animation->currentTimeInternal()); |
| 478 EXPECT_EQ(Animation::Finished, animation->playStateInternal()); |
| 479 |
| 480 EXPECT_FALSE(exceptionState.hadException()); |
| 481 } |
| 482 |
| 483 TEST_F(AnimationAnimationTest, FinishAfterSourceEnd) |
| 484 { |
| 485 animation->setCurrentTime(40 * 1000); |
| 486 animation->finish(exceptionState); |
| 487 EXPECT_EQ(30, animation->currentTimeInternal()); |
| 488 } |
| 489 |
| 490 TEST_F(AnimationAnimationTest, FinishBeforeStart) |
| 491 { |
| 492 animation->setCurrentTimeInternal(-10); |
| 493 animation->setPlaybackRate(-1); |
| 494 animation->finish(exceptionState); |
| 495 EXPECT_EQ(0, animation->currentTimeInternal()); |
| 496 } |
| 497 |
| 498 TEST_F(AnimationAnimationTest, FinishDoesNothingWithPlaybackRateZero) |
| 499 { |
| 500 animation->setCurrentTimeInternal(10); |
| 501 animation->setPlaybackRate(0); |
| 502 animation->finish(exceptionState); |
| 503 EXPECT_EQ(10, animation->currentTimeInternal()); |
| 504 } |
| 505 |
| 506 TEST_F(AnimationAnimationTest, FinishRaisesException) |
| 507 { |
| 508 Timing timing; |
| 509 timing.iterationDuration = 1; |
| 510 timing.iterationCount = std::numeric_limits<double>::infinity(); |
| 511 animation->setSource(KeyframeEffect::create(0, nullptr, timing).get()); |
| 512 animation->setCurrentTimeInternal(10); |
| 513 |
| 514 animation->finish(exceptionState); |
| 515 EXPECT_EQ(10, animation->currentTimeInternal()); |
156 EXPECT_TRUE(exceptionState.hadException()); | 516 EXPECT_TRUE(exceptionState.hadException()); |
157 EXPECT_EQ(NotSupportedError, exceptionState.code()); | 517 EXPECT_EQ(InvalidStateError, exceptionState.code()); |
158 } | 518 } |
159 | 519 |
160 TEST_F(AnimationAnimationV8Test, MissingOffsetZeroRaisesException) | 520 |
161 { | 521 TEST_F(AnimationAnimationTest, LimitingAtSourceEnd) |
162 Vector<Dictionary> jsKeyframes; | 522 { |
163 v8::Local<v8::Object> keyframe1 = v8::Object::New(m_isolate); | 523 simulateFrame(30); |
164 v8::Local<v8::Object> keyframe2 = v8::Object::New(m_isolate); | 524 EXPECT_EQ(30, animation->currentTimeInternal()); |
165 | 525 EXPECT_TRUE(animation->limited()); |
166 setV8ObjectPropertyAsString(keyframe1, "width", "100px"); | 526 simulateFrame(40); |
167 setV8ObjectPropertyAsString(keyframe1, "offset", "0.1"); | 527 EXPECT_EQ(30, animation->currentTimeInternal()); |
168 setV8ObjectPropertyAsString(keyframe2, "width", "0px"); | 528 EXPECT_FALSE(animation->paused()); |
169 setV8ObjectPropertyAsString(keyframe2, "offset", "1"); | 529 } |
170 | 530 |
171 jsKeyframes.append(Dictionary(keyframe1, m_isolate, exceptionState)); | 531 TEST_F(AnimationAnimationTest, LimitingAtStart) |
172 jsKeyframes.append(Dictionary(keyframe2, m_isolate, exceptionState)); | 532 { |
173 | 533 simulateFrame(30); |
174 createAnimation(element.get(), jsKeyframes, 0, exceptionState); | 534 animation->setPlaybackRate(-2); |
175 | 535 simulateFrame(30); |
176 EXPECT_TRUE(exceptionState.hadException()); | 536 simulateFrame(45); |
177 EXPECT_EQ(NotSupportedError, exceptionState.code()); | 537 EXPECT_EQ(0, animation->currentTimeInternal()); |
178 } | 538 EXPECT_TRUE(animation->limited()); |
179 | 539 simulateFrame(60); |
180 TEST_F(AnimationAnimationV8Test, MissingOffsetOneRaisesException) | 540 EXPECT_EQ(0, animation->currentTimeInternal()); |
181 { | 541 EXPECT_FALSE(animation->paused()); |
182 Vector<Dictionary> jsKeyframes; | 542 } |
183 v8::Local<v8::Object> keyframe1 = v8::Object::New(m_isolate); | 543 |
184 v8::Local<v8::Object> keyframe2 = v8::Object::New(m_isolate); | 544 TEST_F(AnimationAnimationTest, LimitingWithNoSource) |
185 | 545 { |
186 setV8ObjectPropertyAsString(keyframe1, "width", "100px"); | 546 animation->setSource(0); |
187 setV8ObjectPropertyAsString(keyframe1, "offset", "0"); | 547 EXPECT_TRUE(animation->limited()); |
188 setV8ObjectPropertyAsString(keyframe2, "width", "0px"); | 548 simulateFrame(30); |
189 setV8ObjectPropertyAsString(keyframe2, "offset", "0.1"); | 549 EXPECT_EQ(0, animation->currentTimeInternal()); |
190 | 550 } |
191 jsKeyframes.append(Dictionary(keyframe1, m_isolate, exceptionState)); | 551 |
192 jsKeyframes.append(Dictionary(keyframe2, m_isolate, exceptionState)); | 552 |
193 | 553 TEST_F(AnimationAnimationTest, SetPlaybackRate) |
194 createAnimation(element.get(), jsKeyframes, 0, exceptionState); | 554 { |
195 | 555 animation->setPlaybackRate(2); |
196 EXPECT_TRUE(exceptionState.hadException()); | 556 simulateFrame(0); |
197 EXPECT_EQ(NotSupportedError, exceptionState.code()); | 557 EXPECT_EQ(2, animation->playbackRate()); |
198 } | 558 EXPECT_EQ(0, animation->currentTimeInternal()); |
199 | 559 simulateFrame(10); |
200 TEST_F(AnimationAnimationV8Test, MissingOffsetZeroAndOneRaisesException) | 560 EXPECT_EQ(20, animation->currentTimeInternal()); |
201 { | 561 } |
202 Vector<Dictionary> jsKeyframes; | 562 |
203 v8::Local<v8::Object> keyframe1 = v8::Object::New(m_isolate); | 563 TEST_F(AnimationAnimationTest, SetPlaybackRateBeforeTimelineStarted) |
204 v8::Local<v8::Object> keyframe2 = v8::Object::New(m_isolate); | 564 { |
205 | 565 setUpWithoutStartingTimeline(); |
206 setV8ObjectPropertyAsString(keyframe1, "width", "100px"); | 566 animation->setPlaybackRate(2); |
207 setV8ObjectPropertyAsString(keyframe1, "offset", "0.1"); | 567 EXPECT_EQ(2, animation->playbackRate()); |
208 setV8ObjectPropertyAsString(keyframe2, "width", "0px"); | 568 EXPECT_EQ(0, animation->currentTimeInternal()); |
209 setV8ObjectPropertyAsString(keyframe2, "offset", "0.2"); | 569 startTimeline(); |
210 | 570 simulateFrame(10); |
211 jsKeyframes.append(Dictionary(keyframe1, m_isolate, exceptionState)); | 571 EXPECT_EQ(20, animation->currentTimeInternal()); |
212 jsKeyframes.append(Dictionary(keyframe2, m_isolate, exceptionState)); | 572 } |
213 | 573 |
214 createAnimation(element.get(), jsKeyframes, 0, exceptionState); | 574 TEST_F(AnimationAnimationTest, SetPlaybackRateWhilePaused) |
215 | 575 { |
216 EXPECT_TRUE(exceptionState.hadException()); | 576 simulateFrame(10); |
217 EXPECT_EQ(NotSupportedError, exceptionState.code()); | 577 animation->pause(); |
218 } | 578 animation->setPlaybackRate(2); |
219 | 579 simulateFrame(20); |
220 TEST_F(AnimationAnimationV8Test, SpecifiedGetters) | 580 animation->play(); |
221 { | 581 EXPECT_EQ(10, animation->currentTimeInternal()); |
222 Vector<Dictionary, 0> jsKeyframes; | 582 simulateFrame(20); |
223 | 583 simulateFrame(25); |
224 v8::Local<v8::Object> timingInput = v8::Object::New(m_isolate); | 584 EXPECT_EQ(20, animation->currentTimeInternal()); |
225 setV8ObjectPropertyAsNumber(timingInput, "delay", 2); | 585 } |
226 setV8ObjectPropertyAsNumber(timingInput, "endDelay", 0.5); | 586 |
227 setV8ObjectPropertyAsString(timingInput, "fill", "backwards"); | 587 TEST_F(AnimationAnimationTest, SetPlaybackRateWhileLimited) |
228 setV8ObjectPropertyAsNumber(timingInput, "iterationStart", 2); | 588 { |
229 setV8ObjectPropertyAsNumber(timingInput, "iterations", 10); | 589 simulateFrame(40); |
230 setV8ObjectPropertyAsNumber(timingInput, "playbackRate", 2); | 590 EXPECT_EQ(30, animation->currentTimeInternal()); |
231 setV8ObjectPropertyAsString(timingInput, "direction", "reverse"); | 591 animation->setPlaybackRate(2); |
232 setV8ObjectPropertyAsString(timingInput, "easing", "step-start"); | 592 simulateFrame(50); |
233 AnimationTimingProperties timingInputDictionary; | 593 EXPECT_EQ(30, animation->currentTimeInternal()); |
234 V8AnimationTimingProperties::toImpl(m_isolate, timingInput, timingInputDicti
onary, exceptionState); | 594 animation->setPlaybackRate(-2); |
235 | 595 simulateFrame(50); |
236 RefPtrWillBeRawPtr<Animation> animation = createAnimation(element.get(), jsK
eyframes, timingInputDictionary, exceptionState); | 596 simulateFrame(60); |
237 | 597 EXPECT_FALSE(animation->limited()); |
238 RefPtrWillBeRawPtr<AnimationNodeTiming> specified = animation->timing(); | 598 EXPECT_EQ(10, animation->currentTimeInternal()); |
239 EXPECT_EQ(2, specified->delay()); | 599 } |
240 EXPECT_EQ(0.5, specified->endDelay()); | 600 |
241 EXPECT_EQ("backwards", specified->fill()); | 601 TEST_F(AnimationAnimationTest, SetPlaybackRateZero) |
242 EXPECT_EQ(2, specified->iterationStart()); | 602 { |
243 EXPECT_EQ(10, specified->iterations()); | 603 simulateFrame(0); |
244 EXPECT_EQ(2, specified->playbackRate()); | 604 simulateFrame(10); |
245 EXPECT_EQ("reverse", specified->direction()); | 605 animation->setPlaybackRate(0); |
246 EXPECT_EQ("step-start", specified->easing()); | 606 simulateFrame(10); |
247 } | 607 EXPECT_EQ(10, animation->currentTimeInternal()); |
248 | 608 simulateFrame(20); |
249 TEST_F(AnimationAnimationV8Test, SpecifiedDurationGetter) | 609 EXPECT_EQ(10, animation->currentTimeInternal()); |
250 { | 610 animation->setCurrentTimeInternal(20); |
251 Vector<Dictionary, 0> jsKeyframes; | 611 EXPECT_EQ(20, animation->currentTimeInternal()); |
252 | 612 } |
253 v8::Local<v8::Object> timingInputWithDuration = v8::Object::New(m_isolate); | 613 |
254 setV8ObjectPropertyAsNumber(timingInputWithDuration, "duration", 2.5); | 614 TEST_F(AnimationAnimationTest, SetPlaybackRateMax) |
255 AnimationTimingProperties timingInputDictionaryWithDuration; | 615 { |
256 V8AnimationTimingProperties::toImpl(m_isolate, timingInputWithDuration, timi
ngInputDictionaryWithDuration, exceptionState); | 616 animation->setPlaybackRate(std::numeric_limits<double>::max()); |
257 | 617 simulateFrame(0); |
258 RefPtrWillBeRawPtr<Animation> animationWithDuration = createAnimation(elemen
t.get(), jsKeyframes, timingInputDictionaryWithDuration, exceptionState); | 618 EXPECT_EQ(std::numeric_limits<double>::max(), animation->playbackRate()); |
259 | 619 EXPECT_EQ(0, animation->currentTimeInternal()); |
260 RefPtrWillBeRawPtr<AnimationNodeTiming> specifiedWithDuration = animationWit
hDuration->timing(); | 620 simulateFrame(1); |
261 UnrestrictedDoubleOrString duration; | 621 EXPECT_EQ(30, animation->currentTimeInternal()); |
262 specifiedWithDuration->duration(duration); | 622 } |
263 EXPECT_TRUE(duration.isUnrestrictedDouble()); | 623 |
264 EXPECT_EQ(2.5, duration.getAsUnrestrictedDouble()); | 624 |
265 EXPECT_FALSE(duration.isString()); | 625 TEST_F(AnimationAnimationTest, SetSource) |
266 | 626 { |
267 | 627 animation = timeline->play(0); |
268 v8::Local<v8::Object> timingInputNoDuration = v8::Object::New(m_isolate); | 628 animation->setStartTime(0); |
269 AnimationTimingProperties timingInputDictionaryNoDuration; | 629 RefPtrWillBeRawPtr<AnimationEffect> source1 = makeAnimation(); |
270 V8AnimationTimingProperties::toImpl(m_isolate, timingInputNoDuration, timing
InputDictionaryNoDuration, exceptionState); | 630 RefPtrWillBeRawPtr<AnimationEffect> source2 = makeAnimation(); |
271 | 631 animation->setSource(source1.get()); |
272 RefPtrWillBeRawPtr<Animation> animationNoDuration = createAnimation(element.
get(), jsKeyframes, timingInputDictionaryNoDuration, exceptionState); | 632 EXPECT_EQ(source1, animation->source()); |
273 | 633 EXPECT_EQ(0, animation->currentTimeInternal()); |
274 RefPtrWillBeRawPtr<AnimationNodeTiming> specifiedNoDuration = animationNoDur
ation->timing(); | 634 animation->setCurrentTimeInternal(15); |
275 UnrestrictedDoubleOrString duration2; | 635 animation->setSource(source2.get()); |
276 specifiedNoDuration->duration(duration2); | 636 EXPECT_EQ(15, animation->currentTimeInternal()); |
277 EXPECT_FALSE(duration2.isUnrestrictedDouble()); | 637 EXPECT_EQ(0, source1->animation()); |
278 EXPECT_TRUE(duration2.isString()); | 638 EXPECT_EQ(animation.get(), source2->animation()); |
279 EXPECT_EQ("auto", duration2.getAsString()); | 639 EXPECT_EQ(source2, animation->source()); |
280 } | 640 } |
281 | 641 |
282 TEST_F(AnimationAnimationV8Test, SpecifiedSetters) | 642 TEST_F(AnimationAnimationTest, SetSourceLimitsAnimation) |
283 { | 643 { |
284 Vector<Dictionary, 0> jsKeyframes; | 644 animation->setCurrentTimeInternal(20); |
285 v8::Local<v8::Object> timingInput = v8::Object::New(m_isolate); | 645 animation->setSource(makeAnimation(10).get()); |
286 AnimationTimingProperties timingInputDictionary; | 646 EXPECT_EQ(20, animation->currentTimeInternal()); |
287 V8AnimationTimingProperties::toImpl(m_isolate, timingInput, timingInputDicti
onary, exceptionState); | 647 EXPECT_TRUE(animation->limited()); |
288 RefPtrWillBeRawPtr<Animation> animation = createAnimation(element.get(), jsK
eyframes, timingInputDictionary, exceptionState); | 648 simulateFrame(10); |
289 | 649 EXPECT_EQ(20, animation->currentTimeInternal()); |
290 RefPtrWillBeRawPtr<AnimationNodeTiming> specified = animation->timing(); | 650 } |
291 | 651 |
292 EXPECT_EQ(0, specified->delay()); | 652 TEST_F(AnimationAnimationTest, SetSourceUnlimitsAnimation) |
293 specified->setDelay(2); | 653 { |
294 EXPECT_EQ(2, specified->delay()); | 654 animation->setCurrentTimeInternal(40); |
295 | 655 animation->setSource(makeAnimation(60).get()); |
296 EXPECT_EQ(0, specified->endDelay()); | 656 EXPECT_FALSE(animation->limited()); |
297 specified->setEndDelay(0.5); | 657 EXPECT_EQ(40, animation->currentTimeInternal()); |
298 EXPECT_EQ(0.5, specified->endDelay()); | 658 simulateFrame(10); |
299 | 659 EXPECT_EQ(50, animation->currentTimeInternal()); |
300 EXPECT_EQ("auto", specified->fill()); | 660 } |
301 specified->setFill("backwards"); | 661 |
302 EXPECT_EQ("backwards", specified->fill()); | 662 |
303 | 663 TEST_F(AnimationAnimationTest, EmptyAnimationsDontUpdateEffects) |
304 EXPECT_EQ(0, specified->iterationStart()); | 664 { |
305 specified->setIterationStart(2); | 665 animation = timeline->play(0); |
306 EXPECT_EQ(2, specified->iterationStart()); | 666 animation->update(TimingUpdateOnDemand); |
307 | 667 EXPECT_EQ(std::numeric_limits<double>::infinity(), animation->timeToEffectCh
ange()); |
308 EXPECT_EQ(1, specified->iterations()); | 668 |
309 specified->setIterations(10); | 669 simulateFrame(1234); |
310 EXPECT_EQ(10, specified->iterations()); | 670 EXPECT_EQ(std::numeric_limits<double>::infinity(), animation->timeToEffectCh
ange()); |
311 | 671 } |
312 EXPECT_EQ(1, specified->playbackRate()); | 672 |
313 specified->setPlaybackRate(2); | 673 TEST_F(AnimationAnimationTest, AnimationsDisassociateFromSource) |
314 EXPECT_EQ(2, specified->playbackRate()); | 674 { |
315 | 675 AnimationEffect* animationNode = animation->source(); |
316 EXPECT_EQ("normal", specified->direction()); | 676 Animation* animation2 = timeline->play(animationNode); |
317 specified->setDirection("reverse"); | 677 EXPECT_EQ(0, animation->source()); |
318 EXPECT_EQ("reverse", specified->direction()); | 678 animation->setSource(animationNode); |
319 | 679 EXPECT_EQ(0, animation2->source()); |
320 EXPECT_EQ("linear", specified->easing()); | 680 } |
321 specified->setEasing("step-start"); | 681 |
322 EXPECT_EQ("step-start", specified->easing()); | 682 TEST_F(AnimationAnimationTest, AnimationsReturnTimeToNextEffect) |
323 } | |
324 | |
325 TEST_F(AnimationAnimationV8Test, SetSpecifiedDuration) | |
326 { | |
327 Vector<Dictionary, 0> jsKeyframes; | |
328 v8::Local<v8::Object> timingInput = v8::Object::New(m_isolate); | |
329 AnimationTimingProperties timingInputDictionary; | |
330 V8AnimationTimingProperties::toImpl(m_isolate, timingInput, timingInputDicti
onary, exceptionState); | |
331 RefPtrWillBeRawPtr<Animation> animation = createAnimation(element.get(), jsK
eyframes, timingInputDictionary, exceptionState); | |
332 | |
333 RefPtrWillBeRawPtr<AnimationNodeTiming> specified = animation->timing(); | |
334 | |
335 UnrestrictedDoubleOrString duration; | |
336 specified->duration(duration); | |
337 EXPECT_FALSE(duration.isUnrestrictedDouble()); | |
338 EXPECT_TRUE(duration.isString()); | |
339 EXPECT_EQ("auto", duration.getAsString()); | |
340 | |
341 UnrestrictedDoubleOrString inDuration; | |
342 inDuration.setUnrestrictedDouble(2.5); | |
343 specified->setDuration(inDuration); | |
344 UnrestrictedDoubleOrString duration2; | |
345 specified->duration(duration2); | |
346 EXPECT_TRUE(duration2.isUnrestrictedDouble()); | |
347 EXPECT_EQ(2.5, duration2.getAsUnrestrictedDouble()); | |
348 EXPECT_FALSE(duration2.isString()); | |
349 } | |
350 | |
351 TEST_F(AnimationAnimationTest, TimeToEffectChange) | |
352 { | 683 { |
353 Timing timing; | 684 Timing timing; |
354 timing.iterationDuration = 100; | 685 timing.startDelay = 1; |
355 timing.startDelay = 100; | 686 timing.iterationDuration = 1; |
356 timing.endDelay = 100; | 687 timing.endDelay = 1; |
357 timing.fillMode = Timing::FillModeNone; | 688 RefPtrWillBeRawPtr<KeyframeEffect> keyframeEffect = KeyframeEffect::create(0
, nullptr, timing); |
358 RefPtrWillBeRawPtr<Animation> animation = Animation::create(0, nullptr, timi
ng); | 689 animation = timeline->play(keyframeEffect.get()); |
359 RefPtrWillBeRawPtr<AnimationPlayer> player = document.timeline().play(animat
ion.get()); | 690 animation->setStartTime(0); |
360 double inf = std::numeric_limits<double>::infinity(); | 691 |
361 | 692 simulateFrame(0); |
362 EXPECT_EQ(100, animation->timeToForwardsEffectChange()); | 693 EXPECT_EQ(1, animation->timeToEffectChange()); |
363 EXPECT_EQ(inf, animation->timeToReverseEffectChange()); | 694 |
364 | 695 simulateFrame(0.5); |
365 player->setCurrentTimeInternal(100); | 696 EXPECT_EQ(0.5, animation->timeToEffectChange()); |
366 EXPECT_EQ(100, animation->timeToForwardsEffectChange()); | 697 |
367 EXPECT_EQ(0, animation->timeToReverseEffectChange()); | 698 simulateFrame(1); |
368 | 699 EXPECT_EQ(0, animation->timeToEffectChange()); |
369 player->setCurrentTimeInternal(199); | 700 |
370 EXPECT_EQ(1, animation->timeToForwardsEffectChange()); | 701 simulateFrame(1.5); |
371 EXPECT_EQ(0, animation->timeToReverseEffectChange()); | 702 EXPECT_EQ(0, animation->timeToEffectChange()); |
372 | 703 |
373 player->setCurrentTimeInternal(200); | 704 simulateFrame(2); |
374 // End-exclusive. | 705 EXPECT_EQ(std::numeric_limits<double>::infinity(), animation->timeToEffectCh
ange()); |
375 EXPECT_EQ(inf, animation->timeToForwardsEffectChange()); | 706 |
376 EXPECT_EQ(0, animation->timeToReverseEffectChange()); | 707 simulateFrame(3); |
377 | 708 EXPECT_EQ(std::numeric_limits<double>::infinity(), animation->timeToEffectCh
ange()); |
378 player->setCurrentTimeInternal(300); | 709 |
379 EXPECT_EQ(inf, animation->timeToForwardsEffectChange()); | 710 animation->setCurrentTimeInternal(0); |
380 EXPECT_EQ(100, animation->timeToReverseEffectChange()); | 711 simulateFrame(3); |
381 } | 712 EXPECT_EQ(1, animation->timeToEffectChange()); |
382 | 713 |
383 TEST_F(AnimationAnimationTest, TimeToEffectChangeWithPlaybackRate) | 714 animation->setPlaybackRate(2); |
384 { | 715 simulateFrame(3); |
| 716 EXPECT_EQ(0.5, animation->timeToEffectChange()); |
| 717 |
| 718 animation->setPlaybackRate(0); |
| 719 animation->update(TimingUpdateOnDemand); |
| 720 EXPECT_EQ(std::numeric_limits<double>::infinity(), animation->timeToEffectCh
ange()); |
| 721 |
| 722 animation->setCurrentTimeInternal(3); |
| 723 animation->setPlaybackRate(-1); |
| 724 animation->update(TimingUpdateOnDemand); |
| 725 simulateFrame(3); |
| 726 EXPECT_EQ(1, animation->timeToEffectChange()); |
| 727 |
| 728 animation->setPlaybackRate(-2); |
| 729 animation->update(TimingUpdateOnDemand); |
| 730 simulateFrame(3); |
| 731 EXPECT_EQ(0.5, animation->timeToEffectChange()); |
| 732 } |
| 733 |
| 734 TEST_F(AnimationAnimationTest, TimeToNextEffectWhenPaused) |
| 735 { |
| 736 EXPECT_EQ(0, animation->timeToEffectChange()); |
| 737 animation->pause(); |
| 738 animation->update(TimingUpdateOnDemand); |
| 739 EXPECT_EQ(std::numeric_limits<double>::infinity(), animation->timeToEffectCh
ange()); |
| 740 } |
| 741 |
| 742 TEST_F(AnimationAnimationTest, TimeToNextEffectWhenCancelledBeforeStart) |
| 743 { |
| 744 EXPECT_EQ(0, animation->timeToEffectChange()); |
| 745 animation->setCurrentTimeInternal(-8); |
| 746 animation->setPlaybackRate(2); |
| 747 EXPECT_EQ(Animation::Pending, animation->playStateInternal()); |
| 748 animation->cancel(); |
| 749 EXPECT_EQ(Animation::Idle, animation->playStateInternal()); |
| 750 animation->update(TimingUpdateOnDemand); |
| 751 // This frame will fire the finish event event though no start time has been |
| 752 // received from the compositor yet, as cancel() nukes start times. |
| 753 simulateFrame(0); |
| 754 EXPECT_EQ(std::numeric_limits<double>::infinity(), animation->timeToEffectCh
ange()); |
| 755 } |
| 756 |
| 757 TEST_F(AnimationAnimationTest, TimeToNextEffectWhenCancelledBeforeStartReverse) |
| 758 { |
| 759 EXPECT_EQ(0, animation->timeToEffectChange()); |
| 760 animation->setCurrentTimeInternal(9); |
| 761 animation->setPlaybackRate(-3); |
| 762 EXPECT_EQ(Animation::Pending, animation->playStateInternal()); |
| 763 animation->cancel(); |
| 764 EXPECT_EQ(Animation::Idle, animation->playStateInternal()); |
| 765 animation->update(TimingUpdateOnDemand); |
| 766 // This frame will fire the finish event event though no start time has been |
| 767 // received from the compositor yet, as cancel() nukes start times. |
| 768 simulateFrame(0); |
| 769 EXPECT_EQ(std::numeric_limits<double>::infinity(), animation->timeToEffectCh
ange()); |
| 770 } |
| 771 |
| 772 TEST_F(AnimationAnimationTest, TimeToNextEffectSimpleCancelledBeforeStart) |
| 773 { |
| 774 EXPECT_EQ(0, animation->timeToEffectChange()); |
| 775 EXPECT_EQ(Animation::Running, animation->playStateInternal()); |
| 776 animation->cancel(); |
| 777 animation->update(TimingUpdateOnDemand); |
| 778 // This frame will fire the finish event event though no start time has been |
| 779 // received from the compositor yet, as cancel() nukes start times. |
| 780 simulateFrame(0); |
| 781 EXPECT_EQ(std::numeric_limits<double>::infinity(), animation->timeToEffectCh
ange()); |
| 782 } |
| 783 |
| 784 TEST_F(AnimationAnimationTest, AttachedAnimations) |
| 785 { |
| 786 RefPtrWillBePersistent<Element> element = document->createElement("foo", ASS
ERT_NO_EXCEPTION); |
| 787 |
385 Timing timing; | 788 Timing timing; |
386 timing.iterationDuration = 100; | 789 RefPtrWillBeRawPtr<KeyframeEffect> keyframeEffect = KeyframeEffect::create(e
lement.get(), nullptr, timing); |
387 timing.startDelay = 100; | 790 RefPtrWillBeRawPtr<Animation> animation = timeline->play(keyframeEffect.get(
)); |
388 timing.endDelay = 100; | 791 simulateFrame(0); |
389 timing.playbackRate = 2; | 792 timeline->serviceAnimations(TimingUpdateForAnimationFrame); |
390 timing.fillMode = Timing::FillModeNone; | 793 EXPECT_EQ(1U, element->elementAnimations()->animations().find(animation.get(
))->value); |
391 RefPtrWillBeRawPtr<Animation> animation = Animation::create(0, nullptr, timi
ng); | 794 |
392 RefPtrWillBeRawPtr<AnimationPlayer> player = document.timeline().play(animat
ion.get()); | 795 animation.release(); |
393 double inf = std::numeric_limits<double>::infinity(); | 796 Heap::collectAllGarbage(); |
394 | 797 EXPECT_TRUE(element->elementAnimations()->animations().isEmpty()); |
395 EXPECT_EQ(100, animation->timeToForwardsEffectChange()); | 798 } |
396 EXPECT_EQ(inf, animation->timeToReverseEffectChange()); | 799 |
397 | 800 TEST_F(AnimationAnimationTest, HasLowerPriority) |
398 player->setCurrentTimeInternal(100); | 801 { |
399 EXPECT_EQ(50, animation->timeToForwardsEffectChange()); | 802 RefPtrWillBeRawPtr<Animation> animation1 = timeline->play(0); |
400 EXPECT_EQ(0, animation->timeToReverseEffectChange()); | 803 RefPtrWillBeRawPtr<Animation> animation2 = timeline->play(0); |
401 | 804 EXPECT_TRUE(Animation::hasLowerPriority(animation1.get(), animation2.get()))
; |
402 player->setCurrentTimeInternal(149); | 805 } |
403 EXPECT_EQ(1, animation->timeToForwardsEffectChange()); | 806 |
404 EXPECT_EQ(0, animation->timeToReverseEffectChange()); | 807 TEST_F(AnimationAnimationTest, PlayAfterCancel) |
405 | 808 { |
406 player->setCurrentTimeInternal(150); | 809 animation->cancel(); |
407 // End-exclusive. | 810 EXPECT_EQ(Animation::Idle, animation->playStateInternal()); |
408 EXPECT_EQ(inf, animation->timeToForwardsEffectChange()); | 811 EXPECT_TRUE(std::isnan(animation->currentTime())); |
409 EXPECT_EQ(0, animation->timeToReverseEffectChange()); | 812 EXPECT_TRUE(std::isnan(animation->startTime())); |
410 | 813 animation->play(); |
411 player->setCurrentTimeInternal(200); | 814 EXPECT_EQ(Animation::Pending, animation->playStateInternal()); |
412 EXPECT_EQ(inf, animation->timeToForwardsEffectChange()); | 815 EXPECT_EQ(0, animation->currentTime()); |
413 EXPECT_EQ(50, animation->timeToReverseEffectChange()); | 816 EXPECT_TRUE(std::isnan(animation->startTime())); |
414 } | 817 simulateFrame(10); |
415 | 818 EXPECT_EQ(Animation::Running, animation->playStateInternal()); |
416 TEST_F(AnimationAnimationTest, TimeToEffectChangeWithNegativePlaybackRate) | 819 EXPECT_EQ(0, animation->currentTime()); |
417 { | 820 EXPECT_EQ(10 * 1000, animation->startTime()); |
418 Timing timing; | 821 } |
419 timing.iterationDuration = 100; | 822 |
420 timing.startDelay = 100; | 823 TEST_F(AnimationAnimationTest, PlayBackwardsAfterCancel) |
421 timing.endDelay = 100; | 824 { |
422 timing.playbackRate = -2; | 825 animation->setPlaybackRate(-1); |
423 timing.fillMode = Timing::FillModeNone; | 826 animation->setCurrentTime(15 * 1000); |
424 RefPtrWillBeRawPtr<Animation> animation = Animation::create(0, nullptr, timi
ng); | 827 simulateFrame(0); |
425 RefPtrWillBeRawPtr<AnimationPlayer> player = document.timeline().play(animat
ion.get()); | 828 animation->cancel(); |
426 double inf = std::numeric_limits<double>::infinity(); | 829 EXPECT_EQ(Animation::Idle, animation->playStateInternal()); |
427 | 830 EXPECT_TRUE(std::isnan(animation->currentTime())); |
428 EXPECT_EQ(100, animation->timeToForwardsEffectChange()); | 831 EXPECT_TRUE(std::isnan(animation->startTime())); |
429 EXPECT_EQ(inf, animation->timeToReverseEffectChange()); | 832 animation->play(); |
430 | 833 EXPECT_EQ(Animation::Pending, animation->playStateInternal()); |
431 player->setCurrentTimeInternal(100); | 834 EXPECT_EQ(30 * 1000, animation->currentTime()); |
432 EXPECT_EQ(50, animation->timeToForwardsEffectChange()); | 835 EXPECT_TRUE(std::isnan(animation->startTime())); |
433 EXPECT_EQ(0, animation->timeToReverseEffectChange()); | 836 simulateFrame(10); |
434 | 837 EXPECT_EQ(Animation::Running, animation->playStateInternal()); |
435 player->setCurrentTimeInternal(149); | 838 EXPECT_EQ(30 * 1000, animation->currentTime()); |
436 EXPECT_EQ(1, animation->timeToForwardsEffectChange()); | 839 EXPECT_EQ(40 * 1000, animation->startTime()); |
437 EXPECT_EQ(0, animation->timeToReverseEffectChange()); | 840 } |
438 | 841 |
439 player->setCurrentTimeInternal(150); | 842 TEST_F(AnimationAnimationTest, ReverseAfterCancel) |
440 EXPECT_EQ(inf, animation->timeToForwardsEffectChange()); | 843 { |
441 EXPECT_EQ(0, animation->timeToReverseEffectChange()); | 844 animation->cancel(); |
442 | 845 EXPECT_EQ(Animation::Idle, animation->playStateInternal()); |
443 player->setCurrentTimeInternal(200); | 846 EXPECT_TRUE(std::isnan(animation->currentTime())); |
444 EXPECT_EQ(inf, animation->timeToForwardsEffectChange()); | 847 EXPECT_TRUE(std::isnan(animation->startTime())); |
445 EXPECT_EQ(50, animation->timeToReverseEffectChange()); | 848 animation->reverse(); |
446 } | 849 EXPECT_EQ(Animation::Pending, animation->playStateInternal()); |
447 | 850 EXPECT_EQ(30 * 1000, animation->currentTime()); |
448 TEST_F(AnimationAnimationTest, ElementDestructorClearsAnimationTarget) | 851 EXPECT_TRUE(std::isnan(animation->startTime())); |
449 { | 852 simulateFrame(10); |
450 // This test expects incorrect behaviour should be removed once Element | 853 EXPECT_EQ(Animation::Running, animation->playStateInternal()); |
451 // and Animation are moved to Oilpan. See crbug.com/362404 for context. | 854 EXPECT_EQ(30 * 1000, animation->currentTime()); |
452 Timing timing; | 855 EXPECT_EQ(40 * 1000, animation->startTime()); |
453 timing.iterationDuration = 5; | 856 } |
454 RefPtrWillBeRawPtr<Animation> animation = Animation::create(element.get(), n
ullptr, timing); | 857 |
455 EXPECT_EQ(element.get(), animation->target()); | 858 TEST_F(AnimationAnimationTest, FinishAfterCancel) |
456 document.timeline().play(animation.get()); | 859 { |
457 pageHolder.clear(); | 860 animation->cancel(); |
458 element.clear(); | 861 EXPECT_EQ(Animation::Idle, animation->playStateInternal()); |
459 #if !ENABLE(OILPAN) | 862 EXPECT_TRUE(std::isnan(animation->currentTime())); |
460 EXPECT_EQ(0, animation->target()); | 863 EXPECT_TRUE(std::isnan(animation->startTime())); |
461 #endif | 864 animation->finish(exceptionState); |
462 } | 865 EXPECT_TRUE(std::isnan(animation->currentTime())); |
463 | 866 EXPECT_TRUE(std::isnan(animation->startTime())); |
464 } // namespace blink | 867 EXPECT_EQ(Animation::Idle, animation->playStateInternal()); |
| 868 } |
| 869 |
| 870 TEST_F(AnimationAnimationTest, PauseAfterCancel) |
| 871 { |
| 872 animation->cancel(); |
| 873 EXPECT_EQ(Animation::Idle, animation->playStateInternal()); |
| 874 EXPECT_TRUE(std::isnan(animation->currentTime())); |
| 875 EXPECT_TRUE(std::isnan(animation->startTime())); |
| 876 animation->pause(); |
| 877 EXPECT_EQ(Animation::Idle, animation->playStateInternal()); |
| 878 EXPECT_TRUE(std::isnan(animation->currentTime())); |
| 879 EXPECT_TRUE(std::isnan(animation->startTime())); |
| 880 } |
| 881 |
| 882 } |
OLD | NEW |