Rename rendering/RenderFileUploadControl to layout/LayoutFileUploadControl.
[chromium-blink-merge.git] / third_party / WebKit / Source / core / animation / AnimationTest.cpp
blob8e43eb5f11942ae99afa0b146f9c8bfe7bbf59c7
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "config.h"
6 #include "core/animation/Animation.h"
8 #include "bindings/core/v8/Dictionary.h"
9 #include "bindings/core/v8/UnionTypesCore.h"
10 #include "core/animation/AnimationClock.h"
11 #include "core/animation/AnimationNodeTiming.h"
12 #include "core/animation/AnimationTestHelper.h"
13 #include "core/animation/AnimationTimeline.h"
14 #include "core/animation/KeyframeEffectModel.h"
15 #include "core/animation/Timing.h"
16 #include "core/dom/Document.h"
17 #include "core/dom/ExceptionCode.h"
18 #include "core/testing/DummyPageHolder.h"
19 #include <gtest/gtest.h>
20 #include <v8.h>
22 namespace blink {
24 class AnimationAnimationTest : public ::testing::Test {
25 protected:
26 AnimationAnimationTest()
27 : pageHolder(DummyPageHolder::create())
28 , document(pageHolder->document())
29 , element(document.createElement("foo", ASSERT_NO_EXCEPTION))
31 document.animationClock().resetTimeForTesting(document.timeline().zeroTime());
32 EXPECT_EQ(0, document.timeline().currentTime());
35 OwnPtr<DummyPageHolder> pageHolder;
36 Document& document;
37 RefPtrWillBePersistent<Element> element;
38 TrackExceptionState exceptionState;
41 class AnimationAnimationV8Test : public AnimationAnimationTest {
42 protected:
43 AnimationAnimationV8Test()
44 : m_isolate(v8::Isolate::GetCurrent())
45 , m_scope(m_isolate)
49 template<typename T>
50 static PassRefPtrWillBeRawPtr<Animation> createAnimation(Element* element, Vector<Dictionary> keyframeDictionaryVector, T timingInput, ExceptionState& exceptionState)
52 return Animation::create(element, EffectInput::convert(element, keyframeDictionaryVector, exceptionState), timingInput);
54 static PassRefPtrWillBeRawPtr<Animation> createAnimation(Element* element, Vector<Dictionary> keyframeDictionaryVector, ExceptionState& exceptionState)
56 return Animation::create(element, EffectInput::convert(element, keyframeDictionaryVector, exceptionState));
59 v8::Isolate* m_isolate;
61 private:
62 V8TestingScope m_scope;
65 TEST_F(AnimationAnimationV8Test, CanCreateAnAnimation)
67 Vector<Dictionary> jsKeyframes;
68 v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate);
69 v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate);
71 setV8ObjectPropertyAsString(keyframe1, "width", "100px");
72 setV8ObjectPropertyAsString(keyframe1, "offset", "0");
73 setV8ObjectPropertyAsString(keyframe1, "easing", "ease-in-out");
74 setV8ObjectPropertyAsString(keyframe2, "width", "0px");
75 setV8ObjectPropertyAsString(keyframe2, "offset", "1");
76 setV8ObjectPropertyAsString(keyframe2, "easing", "cubic-bezier(1, 1, 0.3, 0.3)");
78 jsKeyframes.append(Dictionary(keyframe1, m_isolate, exceptionState));
79 jsKeyframes.append(Dictionary(keyframe2, m_isolate, exceptionState));
81 String value1;
82 ASSERT_TRUE(DictionaryHelper::get(jsKeyframes[0], "width", value1));
83 ASSERT_EQ("100px", value1);
85 String value2;
86 ASSERT_TRUE(DictionaryHelper::get(jsKeyframes[1], "width", value2));
87 ASSERT_EQ("0px", value2);
89 RefPtrWillBeRawPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, 0, exceptionState);
91 Element* target = animation->target();
92 EXPECT_EQ(*element.get(), *target);
94 const KeyframeVector keyframes = toKeyframeEffectModelBase(animation->effect())->getFrames();
96 EXPECT_EQ(0, keyframes[0]->offset());
97 EXPECT_EQ(1, keyframes[1]->offset());
99 const CSSValue* keyframe1Width = toStringKeyframe(keyframes[0].get())->propertyValue(CSSPropertyWidth);
100 const CSSValue* keyframe2Width = toStringKeyframe(keyframes[1].get())->propertyValue(CSSPropertyWidth);
101 ASSERT(keyframe1Width);
102 ASSERT(keyframe2Width);
104 EXPECT_EQ("100px", keyframe1Width->cssText());
105 EXPECT_EQ("0px", keyframe2Width->cssText());
107 EXPECT_EQ(*(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut)), keyframes[0]->easing());
108 EXPECT_EQ(*(CubicBezierTimingFunction::create(1, 1, 0.3, 0.3).get()), keyframes[1]->easing());
111 TEST_F(AnimationAnimationV8Test, CanSetDuration)
113 Vector<Dictionary, 0> jsKeyframes;
114 double duration = 2000;
116 RefPtrWillBeRawPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, duration, exceptionState);
118 EXPECT_EQ(duration / 1000, animation->specifiedTiming().iterationDuration);
121 TEST_F(AnimationAnimationV8Test, CanOmitSpecifiedDuration)
123 Vector<Dictionary, 0> jsKeyframes;
124 RefPtrWillBeRawPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, exceptionState);
125 EXPECT_TRUE(std::isnan(animation->specifiedTiming().iterationDuration));
128 TEST_F(AnimationAnimationV8Test, NegativeDurationIsAuto)
130 Vector<Dictionary, 0> jsKeyframes;
131 RefPtrWillBeRawPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, -2, exceptionState);
132 EXPECT_TRUE(std::isnan(animation->specifiedTiming().iterationDuration));
135 TEST_F(AnimationAnimationV8Test, MismatchedKeyframePropertyRaisesException)
137 Vector<Dictionary> jsKeyframes;
138 v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate);
139 v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate);
141 setV8ObjectPropertyAsString(keyframe1, "width", "100px");
142 setV8ObjectPropertyAsString(keyframe1, "offset", "0");
144 // Height property appears only in keyframe2
145 setV8ObjectPropertyAsString(keyframe2, "height", "100px");
146 setV8ObjectPropertyAsString(keyframe2, "width", "0px");
147 setV8ObjectPropertyAsString(keyframe2, "offset", "1");
149 jsKeyframes.append(Dictionary(keyframe1, m_isolate, exceptionState));
150 jsKeyframes.append(Dictionary(keyframe2, m_isolate, exceptionState));
152 createAnimation(element.get(), jsKeyframes, 0, exceptionState);
154 EXPECT_TRUE(exceptionState.hadException());
155 EXPECT_EQ(NotSupportedError, exceptionState.code());
158 TEST_F(AnimationAnimationV8Test, MissingOffsetZeroRaisesException)
160 Vector<Dictionary> jsKeyframes;
161 v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate);
162 v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate);
164 setV8ObjectPropertyAsString(keyframe1, "width", "100px");
165 setV8ObjectPropertyAsString(keyframe1, "offset", "0.1");
166 setV8ObjectPropertyAsString(keyframe2, "width", "0px");
167 setV8ObjectPropertyAsString(keyframe2, "offset", "1");
169 jsKeyframes.append(Dictionary(keyframe1, m_isolate, exceptionState));
170 jsKeyframes.append(Dictionary(keyframe2, m_isolate, exceptionState));
172 createAnimation(element.get(), jsKeyframes, 0, exceptionState);
174 EXPECT_TRUE(exceptionState.hadException());
175 EXPECT_EQ(NotSupportedError, exceptionState.code());
178 TEST_F(AnimationAnimationV8Test, MissingOffsetOneRaisesException)
180 Vector<Dictionary> jsKeyframes;
181 v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate);
182 v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate);
184 setV8ObjectPropertyAsString(keyframe1, "width", "100px");
185 setV8ObjectPropertyAsString(keyframe1, "offset", "0");
186 setV8ObjectPropertyAsString(keyframe2, "width", "0px");
187 setV8ObjectPropertyAsString(keyframe2, "offset", "0.1");
189 jsKeyframes.append(Dictionary(keyframe1, m_isolate, exceptionState));
190 jsKeyframes.append(Dictionary(keyframe2, m_isolate, exceptionState));
192 createAnimation(element.get(), jsKeyframes, 0, exceptionState);
194 EXPECT_TRUE(exceptionState.hadException());
195 EXPECT_EQ(NotSupportedError, exceptionState.code());
198 TEST_F(AnimationAnimationV8Test, MissingOffsetZeroAndOneRaisesException)
200 Vector<Dictionary> jsKeyframes;
201 v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate);
202 v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate);
204 setV8ObjectPropertyAsString(keyframe1, "width", "100px");
205 setV8ObjectPropertyAsString(keyframe1, "offset", "0.1");
206 setV8ObjectPropertyAsString(keyframe2, "width", "0px");
207 setV8ObjectPropertyAsString(keyframe2, "offset", "0.2");
209 jsKeyframes.append(Dictionary(keyframe1, m_isolate, exceptionState));
210 jsKeyframes.append(Dictionary(keyframe2, m_isolate, exceptionState));
212 createAnimation(element.get(), jsKeyframes, 0, exceptionState);
214 EXPECT_TRUE(exceptionState.hadException());
215 EXPECT_EQ(NotSupportedError, exceptionState.code());
218 TEST_F(AnimationAnimationV8Test, SpecifiedGetters)
220 Vector<Dictionary, 0> jsKeyframes;
222 v8::Handle<v8::Object> timingInput = v8::Object::New(m_isolate);
223 setV8ObjectPropertyAsNumber(timingInput, "delay", 2);
224 setV8ObjectPropertyAsNumber(timingInput, "endDelay", 0.5);
225 setV8ObjectPropertyAsString(timingInput, "fill", "backwards");
226 setV8ObjectPropertyAsNumber(timingInput, "iterationStart", 2);
227 setV8ObjectPropertyAsNumber(timingInput, "iterations", 10);
228 setV8ObjectPropertyAsNumber(timingInput, "playbackRate", 2);
229 setV8ObjectPropertyAsString(timingInput, "direction", "reverse");
230 setV8ObjectPropertyAsString(timingInput, "easing", "step-start");
231 Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), m_isolate, exceptionState);
233 RefPtrWillBeRawPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, timingInputDictionary, exceptionState);
235 RefPtrWillBeRawPtr<AnimationNodeTiming> specified = animation->timing();
236 EXPECT_EQ(2, specified->delay());
237 EXPECT_EQ(0.5, specified->endDelay());
238 EXPECT_EQ("backwards", specified->fill());
239 EXPECT_EQ(2, specified->iterationStart());
240 EXPECT_EQ(10, specified->iterations());
241 EXPECT_EQ(2, specified->playbackRate());
242 EXPECT_EQ("reverse", specified->direction());
243 EXPECT_EQ("step-start", specified->easing());
246 TEST_F(AnimationAnimationV8Test, SpecifiedDurationGetter)
248 Vector<Dictionary, 0> jsKeyframes;
250 v8::Handle<v8::Object> timingInputWithDuration = v8::Object::New(m_isolate);
251 setV8ObjectPropertyAsNumber(timingInputWithDuration, "duration", 2.5);
252 Dictionary timingInputDictionaryWithDuration = Dictionary(v8::Handle<v8::Value>::Cast(timingInputWithDuration), m_isolate, exceptionState);
254 RefPtrWillBeRawPtr<Animation> animationWithDuration = createAnimation(element.get(), jsKeyframes, timingInputDictionaryWithDuration, exceptionState);
256 RefPtrWillBeRawPtr<AnimationNodeTiming> specifiedWithDuration = animationWithDuration->timing();
257 UnrestrictedDoubleOrString duration;
258 specifiedWithDuration->duration(duration);
259 EXPECT_TRUE(duration.isUnrestrictedDouble());
260 EXPECT_EQ(2.5, duration.getAsUnrestrictedDouble());
261 EXPECT_FALSE(duration.isString());
264 v8::Handle<v8::Object> timingInputNoDuration = v8::Object::New(m_isolate);
265 Dictionary timingInputDictionaryNoDuration = Dictionary(v8::Handle<v8::Value>::Cast(timingInputNoDuration), m_isolate, exceptionState);
267 RefPtrWillBeRawPtr<Animation> animationNoDuration = createAnimation(element.get(), jsKeyframes, timingInputDictionaryNoDuration, exceptionState);
269 RefPtrWillBeRawPtr<AnimationNodeTiming> specifiedNoDuration = animationNoDuration->timing();
270 UnrestrictedDoubleOrString duration2;
271 specifiedNoDuration->duration(duration2);
272 EXPECT_FALSE(duration2.isUnrestrictedDouble());
273 EXPECT_TRUE(duration2.isString());
274 EXPECT_EQ("auto", duration2.getAsString());
277 TEST_F(AnimationAnimationV8Test, SpecifiedSetters)
279 Vector<Dictionary, 0> jsKeyframes;
280 v8::Handle<v8::Object> timingInput = v8::Object::New(m_isolate);
281 Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), m_isolate, exceptionState);
282 RefPtrWillBeRawPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, timingInputDictionary, exceptionState);
284 RefPtrWillBeRawPtr<AnimationNodeTiming> specified = animation->timing();
286 EXPECT_EQ(0, specified->delay());
287 specified->setDelay(2);
288 EXPECT_EQ(2, specified->delay());
290 EXPECT_EQ(0, specified->endDelay());
291 specified->setEndDelay(0.5);
292 EXPECT_EQ(0.5, specified->endDelay());
294 EXPECT_EQ("auto", specified->fill());
295 specified->setFill("backwards");
296 EXPECT_EQ("backwards", specified->fill());
298 EXPECT_EQ(0, specified->iterationStart());
299 specified->setIterationStart(2);
300 EXPECT_EQ(2, specified->iterationStart());
302 EXPECT_EQ(1, specified->iterations());
303 specified->setIterations(10);
304 EXPECT_EQ(10, specified->iterations());
306 EXPECT_EQ(1, specified->playbackRate());
307 specified->setPlaybackRate(2);
308 EXPECT_EQ(2, specified->playbackRate());
310 EXPECT_EQ("normal", specified->direction());
311 specified->setDirection("reverse");
312 EXPECT_EQ("reverse", specified->direction());
314 EXPECT_EQ("linear", specified->easing());
315 specified->setEasing("step-start");
316 EXPECT_EQ("step-start", specified->easing());
319 TEST_F(AnimationAnimationV8Test, SetSpecifiedDuration)
321 Vector<Dictionary, 0> jsKeyframes;
322 v8::Handle<v8::Object> timingInput = v8::Object::New(m_isolate);
323 Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), m_isolate, exceptionState);
324 RefPtrWillBeRawPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, timingInputDictionary, exceptionState);
326 RefPtrWillBeRawPtr<AnimationNodeTiming> specified = animation->timing();
328 UnrestrictedDoubleOrString duration;
329 specified->duration(duration);
330 EXPECT_FALSE(duration.isUnrestrictedDouble());
331 EXPECT_TRUE(duration.isString());
332 EXPECT_EQ("auto", duration.getAsString());
334 UnrestrictedDoubleOrString inDuration;
335 inDuration.setUnrestrictedDouble(2.5);
336 specified->setDuration(inDuration);
337 UnrestrictedDoubleOrString duration2;
338 specified->duration(duration2);
339 EXPECT_TRUE(duration2.isUnrestrictedDouble());
340 EXPECT_EQ(2.5, duration2.getAsUnrestrictedDouble());
341 EXPECT_FALSE(duration2.isString());
344 TEST_F(AnimationAnimationTest, TimeToEffectChange)
346 Timing timing;
347 timing.iterationDuration = 100;
348 timing.startDelay = 100;
349 timing.endDelay = 100;
350 timing.fillMode = Timing::FillModeNone;
351 RefPtrWillBeRawPtr<Animation> animation = Animation::create(0, nullptr, timing);
352 RefPtrWillBeRawPtr<AnimationPlayer> player = document.timeline().play(animation.get());
353 double inf = std::numeric_limits<double>::infinity();
355 EXPECT_EQ(100, animation->timeToForwardsEffectChange());
356 EXPECT_EQ(inf, animation->timeToReverseEffectChange());
358 player->setCurrentTimeInternal(100);
359 EXPECT_EQ(100, animation->timeToForwardsEffectChange());
360 EXPECT_EQ(0, animation->timeToReverseEffectChange());
362 player->setCurrentTimeInternal(199);
363 EXPECT_EQ(1, animation->timeToForwardsEffectChange());
364 EXPECT_EQ(0, animation->timeToReverseEffectChange());
366 player->setCurrentTimeInternal(200);
367 // End-exclusive.
368 EXPECT_EQ(inf, animation->timeToForwardsEffectChange());
369 EXPECT_EQ(0, animation->timeToReverseEffectChange());
371 player->setCurrentTimeInternal(300);
372 EXPECT_EQ(inf, animation->timeToForwardsEffectChange());
373 EXPECT_EQ(100, animation->timeToReverseEffectChange());
376 TEST_F(AnimationAnimationTest, TimeToEffectChangeWithPlaybackRate)
378 Timing timing;
379 timing.iterationDuration = 100;
380 timing.startDelay = 100;
381 timing.endDelay = 100;
382 timing.playbackRate = 2;
383 timing.fillMode = Timing::FillModeNone;
384 RefPtrWillBeRawPtr<Animation> animation = Animation::create(0, nullptr, timing);
385 RefPtrWillBeRawPtr<AnimationPlayer> player = document.timeline().play(animation.get());
386 double inf = std::numeric_limits<double>::infinity();
388 EXPECT_EQ(100, animation->timeToForwardsEffectChange());
389 EXPECT_EQ(inf, animation->timeToReverseEffectChange());
391 player->setCurrentTimeInternal(100);
392 EXPECT_EQ(50, animation->timeToForwardsEffectChange());
393 EXPECT_EQ(0, animation->timeToReverseEffectChange());
395 player->setCurrentTimeInternal(149);
396 EXPECT_EQ(1, animation->timeToForwardsEffectChange());
397 EXPECT_EQ(0, animation->timeToReverseEffectChange());
399 player->setCurrentTimeInternal(150);
400 // End-exclusive.
401 EXPECT_EQ(inf, animation->timeToForwardsEffectChange());
402 EXPECT_EQ(0, animation->timeToReverseEffectChange());
404 player->setCurrentTimeInternal(200);
405 EXPECT_EQ(inf, animation->timeToForwardsEffectChange());
406 EXPECT_EQ(50, animation->timeToReverseEffectChange());
409 TEST_F(AnimationAnimationTest, TimeToEffectChangeWithNegativePlaybackRate)
411 Timing timing;
412 timing.iterationDuration = 100;
413 timing.startDelay = 100;
414 timing.endDelay = 100;
415 timing.playbackRate = -2;
416 timing.fillMode = Timing::FillModeNone;
417 RefPtrWillBeRawPtr<Animation> animation = Animation::create(0, nullptr, timing);
418 RefPtrWillBeRawPtr<AnimationPlayer> player = document.timeline().play(animation.get());
419 double inf = std::numeric_limits<double>::infinity();
421 EXPECT_EQ(100, animation->timeToForwardsEffectChange());
422 EXPECT_EQ(inf, animation->timeToReverseEffectChange());
424 player->setCurrentTimeInternal(100);
425 EXPECT_EQ(50, animation->timeToForwardsEffectChange());
426 EXPECT_EQ(0, animation->timeToReverseEffectChange());
428 player->setCurrentTimeInternal(149);
429 EXPECT_EQ(1, animation->timeToForwardsEffectChange());
430 EXPECT_EQ(0, animation->timeToReverseEffectChange());
432 player->setCurrentTimeInternal(150);
433 EXPECT_EQ(inf, animation->timeToForwardsEffectChange());
434 EXPECT_EQ(0, animation->timeToReverseEffectChange());
436 player->setCurrentTimeInternal(200);
437 EXPECT_EQ(inf, animation->timeToForwardsEffectChange());
438 EXPECT_EQ(50, animation->timeToReverseEffectChange());
441 TEST_F(AnimationAnimationTest, ElementDestructorClearsAnimationTarget)
443 // This test expects incorrect behaviour should be removed once Element
444 // and Animation are moved to Oilpan. See crbug.com/362404 for context.
445 Timing timing;
446 timing.iterationDuration = 5;
447 RefPtrWillBeRawPtr<Animation> animation = Animation::create(element.get(), nullptr, timing);
448 EXPECT_EQ(element.get(), animation->target());
449 document.timeline().play(animation.get());
450 pageHolder.clear();
451 element.clear();
452 #if !ENABLE(OILPAN)
453 EXPECT_EQ(0, animation->target());
454 #endif
457 } // namespace blink