Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / animation / AnimationTest.cpp
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.
4
5 #include "config.h"
6 #include "core/animation/Animation.h"
7
8 #include "bindings/v8/Dictionary.h"
9 #include "core/animation/AnimatableLength.h"
10 #include "core/animation/AnimationClock.h"
11 #include "core/animation/AnimationHelpers.h"
12 #include "core/animation/DocumentTimeline.h"
13 #include "core/animation/KeyframeEffectModel.h"
14 #include "core/animation/TimedItemTiming.h"
15 #include "platform/animation/TimingFunctionTestHelper.h"
16
17 #include <gtest/gtest.h>
18
19 namespace WebCore {
20
21 namespace {
22
23 v8::Handle<v8::Value> stringToV8Value(String string)
24 {
25     return v8::Handle<v8::Value>::Cast(v8String(v8::Isolate::GetCurrent(), string));
26 }
27
28 v8::Handle<v8::Value> doubleToV8Value(double number)
29 {
30     return v8::Handle<v8::Value>::Cast(v8::Number::New(v8::Isolate::GetCurrent(), number));
31 }
32
33 void setV8ObjectPropertyAsString(v8::Handle<v8::Object> object, String name, String value)
34 {
35     object->Set(stringToV8Value(name), stringToV8Value(value));
36 }
37
38 void setV8ObjectPropertyAsNumber(v8::Handle<v8::Object> object, String name, double value)
39 {
40     object->Set(stringToV8Value(name), doubleToV8Value(value));
41 }
42
43 } // namespace
44
45 class AnimationAnimationTest : public ::testing::Test {
46 protected:
47     virtual void SetUp()
48     {
49         document = Document::create();
50         document->animationClock().resetTimeForTesting();
51         element = document->createElement("foo", ASSERT_NO_EXCEPTION);
52         document->timeline()->setZeroTime(0);
53         ASSERT_EQ(0, document->timeline()->currentTime());
54     }
55
56     RefPtr<Document> document;
57     RefPtr<Element> element;
58
59     PassRefPtr<Animation> createAnimation(Element* element, Vector<Dictionary> keyframeDictionaryVector, Dictionary timingInput)
60     {
61         return Animation::createUnsafe(element, keyframeDictionaryVector, timingInput);
62     }
63
64     PassRefPtr<Animation> createAnimation(Element* element, Vector<Dictionary> keyframeDictionaryVector, double timingInput)
65     {
66         return Animation::createUnsafe(element, keyframeDictionaryVector, timingInput);
67     }
68
69     PassRefPtr<Animation> createAnimation(Element* element, Vector<Dictionary> keyframeDictionaryVector)
70     {
71         return Animation::createUnsafe(element, keyframeDictionaryVector);
72     }
73
74     void populateTiming(Timing& timing, Dictionary timingInputDictionary)
75     {
76         Animation::populateTiming(timing, timingInputDictionary);
77     }
78
79     void applyTimingInputNumber(Timing& timing, v8::Isolate* isolate, String timingProperty, double timingPropertyValue)
80     {
81         v8::Handle<v8::Object> timingInput = v8::Object::New(isolate);
82         setV8ObjectPropertyAsNumber(timingInput, timingProperty, timingPropertyValue);
83         Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), isolate);
84         populateTiming(timing, timingInputDictionary);
85     }
86
87     void applyTimingInputString(Timing& timing, v8::Isolate* isolate, String timingProperty, String timingPropertyValue)
88     {
89         v8::Handle<v8::Object> timingInput = v8::Object::New(isolate);
90         setV8ObjectPropertyAsString(timingInput, timingProperty, timingPropertyValue);
91         Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), isolate);
92         populateTiming(timing, timingInputDictionary);
93     }
94 };
95
96 TEST_F(AnimationAnimationTest, CanCreateAnAnimation)
97 {
98     v8::Isolate* isolate = v8::Isolate::GetCurrent();
99     v8::HandleScope scope(isolate);
100     v8::Local<v8::Context> context = v8::Context::New(isolate);
101     v8::Context::Scope contextScope(context);
102
103     Vector<Dictionary> jsKeyframes;
104     v8::Handle<v8::Object> keyframe1 = v8::Object::New(isolate);
105     v8::Handle<v8::Object> keyframe2 = v8::Object::New(isolate);
106
107     setV8ObjectPropertyAsString(keyframe1, "width", "100px");
108     setV8ObjectPropertyAsString(keyframe1, "offset", "0");
109     setV8ObjectPropertyAsString(keyframe1, "easing", "ease-in-out");
110     setV8ObjectPropertyAsString(keyframe2, "width", "0px");
111     setV8ObjectPropertyAsString(keyframe2, "offset", "1");
112     setV8ObjectPropertyAsString(keyframe2, "easing", "cubic-bezier(1, 1, 0.3, 0.3)");
113
114     jsKeyframes.append(Dictionary(keyframe1, isolate));
115     jsKeyframes.append(Dictionary(keyframe2, isolate));
116
117     String value1;
118     ASSERT_TRUE(jsKeyframes[0].get("width", value1));
119     ASSERT_EQ("100px", value1);
120
121     String value2;
122     ASSERT_TRUE(jsKeyframes[1].get("width", value2));
123     ASSERT_EQ("0px", value2);
124
125     RefPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, 0);
126
127     Element* target = animation->target();
128     EXPECT_EQ(*element.get(), *target);
129
130     const KeyframeEffectModel::KeyframeVector keyframes =
131         toKeyframeEffectModel(animation->effect())->getFrames();
132
133     EXPECT_EQ(0, keyframes[0]->offset());
134     EXPECT_EQ(1, keyframes[1]->offset());
135
136     const AnimatableValue* keyframe1Width = keyframes[0]->propertyValue(CSSPropertyWidth);
137     const AnimatableValue* keyframe2Width = keyframes[1]->propertyValue(CSSPropertyWidth);
138     ASSERT(keyframe1Width);
139     ASSERT(keyframe2Width);
140
141     EXPECT_TRUE(keyframe1Width->isLength());
142     EXPECT_TRUE(keyframe2Width->isLength());
143
144     EXPECT_EQ("100px", toAnimatableLength(keyframe1Width)->toCSSValue()->cssText());
145     EXPECT_EQ("0px", toAnimatableLength(keyframe2Width)->toCSSValue()->cssText());
146
147     EXPECT_EQ(*(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut)), *keyframes[0]->easing());
148     EXPECT_EQ(*(CubicBezierTimingFunction::create(1, 1, 0.3, 0.3).get()), *keyframes[1]->easing());
149 }
150
151 TEST_F(AnimationAnimationTest, CanSetDuration)
152 {
153     v8::Isolate* isolate = v8::Isolate::GetCurrent();
154     v8::HandleScope scope(isolate);
155     v8::Local<v8::Context> context = v8::Context::New(isolate);
156     v8::Context::Scope contextScope(context);
157
158     Vector<Dictionary, 0> jsKeyframes;
159     double duration = 2;
160
161     RefPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, duration);
162
163     EXPECT_EQ(duration, animation->specifiedTiming().iterationDuration);
164 }
165
166 TEST_F(AnimationAnimationTest, CanOmitSpecifiedDuration)
167 {
168     v8::Isolate* isolate = v8::Isolate::GetCurrent();
169     v8::HandleScope scope(isolate);
170     v8::Local<v8::Context> context = v8::Context::New(isolate);
171     v8::Context::Scope contextScope(context);
172
173     Vector<Dictionary, 0> jsKeyframes;
174
175     RefPtr<Animation> animation = createAnimation(element.get(), jsKeyframes);
176
177     EXPECT_TRUE(std::isnan(animation->specifiedTiming().iterationDuration));
178 }
179
180 TEST_F(AnimationAnimationTest, ClipNegativeDurationToZero)
181 {
182     v8::Isolate* isolate = v8::Isolate::GetCurrent();
183     v8::HandleScope scope(isolate);
184     v8::Local<v8::Context> context = v8::Context::New(isolate);
185     v8::Context::Scope contextScope(context);
186
187     Vector<Dictionary, 0> jsKeyframes;
188
189     RefPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, -2);
190
191     EXPECT_EQ(0, animation->specifiedTiming().iterationDuration);
192 }
193
194 TEST_F(AnimationAnimationTest, SpecifiedGetters)
195 {
196     v8::Isolate* isolate = v8::Isolate::GetCurrent();
197     v8::HandleScope scope(isolate);
198     v8::Local<v8::Context> context = v8::Context::New(isolate);
199     v8::Context::Scope contextScope(context);
200
201     Vector<Dictionary, 0> jsKeyframes;
202
203     v8::Handle<v8::Object> timingInput = v8::Object::New(isolate);
204     setV8ObjectPropertyAsNumber(timingInput, "delay", 2);
205     setV8ObjectPropertyAsNumber(timingInput, "endDelay", 0.5);
206     setV8ObjectPropertyAsString(timingInput, "fill", "backwards");
207     setV8ObjectPropertyAsNumber(timingInput, "iterationStart", 2);
208     setV8ObjectPropertyAsNumber(timingInput, "iterations", 10);
209     setV8ObjectPropertyAsNumber(timingInput, "playbackRate", 2);
210     setV8ObjectPropertyAsString(timingInput, "direction", "reverse");
211     setV8ObjectPropertyAsString(timingInput, "easing", "step-start");
212     Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), isolate);
213
214     RefPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, timingInputDictionary);
215
216     RefPtr<TimedItemTiming> specified = animation->specified();
217     EXPECT_EQ(2, specified->delay());
218     EXPECT_EQ(0.5, specified->endDelay());
219     EXPECT_EQ("backwards", specified->fill());
220     EXPECT_EQ(2, specified->iterationStart());
221     EXPECT_EQ(10, specified->iterations());
222     EXPECT_EQ(2, specified->playbackRate());
223     EXPECT_EQ("reverse", specified->direction());
224     EXPECT_EQ("step-start", specified->easing());
225 }
226
227 TEST_F(AnimationAnimationTest, SpecifiedDurationGetter)
228 {
229     v8::Isolate* isolate = v8::Isolate::GetCurrent();
230     v8::HandleScope scope(isolate);
231     v8::Local<v8::Context> context = v8::Context::New(isolate);
232     v8::Context::Scope contextScope(context);
233
234     Vector<Dictionary, 0> jsKeyframes;
235
236     v8::Handle<v8::Object> timingInputWithDuration = v8::Object::New(isolate);
237     setV8ObjectPropertyAsNumber(timingInputWithDuration, "duration", 2.5);
238     Dictionary timingInputDictionaryWithDuration = Dictionary(v8::Handle<v8::Value>::Cast(timingInputWithDuration), isolate);
239
240     RefPtr<Animation> animationWithDuration = createAnimation(element.get(), jsKeyframes, timingInputDictionaryWithDuration);
241
242     RefPtr<TimedItemTiming> specifiedWithDuration = animationWithDuration->specified();
243     bool isNumber = false;
244     double numberDuration = std::numeric_limits<double>::quiet_NaN();
245     bool isString = false;
246     String stringDuration = "";
247     specifiedWithDuration->getDuration("duration", isNumber, numberDuration, isString, stringDuration);
248     EXPECT_TRUE(isNumber);
249     EXPECT_EQ(2.5, numberDuration);
250     EXPECT_FALSE(isString);
251     EXPECT_EQ("", stringDuration);
252
253
254     v8::Handle<v8::Object> timingInputNoDuration = v8::Object::New(isolate);
255     Dictionary timingInputDictionaryNoDuration = Dictionary(v8::Handle<v8::Value>::Cast(timingInputNoDuration), isolate);
256
257     RefPtr<Animation> animationNoDuration = createAnimation(element.get(), jsKeyframes, timingInputDictionaryNoDuration);
258
259     RefPtr<TimedItemTiming> specifiedNoDuration = animationNoDuration->specified();
260     isNumber = false;
261     numberDuration = std::numeric_limits<double>::quiet_NaN();
262     isString = false;
263     stringDuration = "";
264     specifiedNoDuration->getDuration("duration", isNumber, numberDuration, isString, stringDuration);
265     EXPECT_FALSE(isNumber);
266     EXPECT_TRUE(std::isnan(numberDuration));
267     EXPECT_TRUE(isString);
268     EXPECT_EQ("auto", stringDuration);
269 }
270
271 TEST_F(AnimationAnimationTest, SpecifiedSetters)
272 {
273     v8::Isolate* isolate = v8::Isolate::GetCurrent();
274     v8::HandleScope scope(isolate);
275     v8::Local<v8::Context> context = v8::Context::New(isolate);
276     v8::Context::Scope contextScope(context);
277
278     Vector<Dictionary, 0> jsKeyframes;
279     v8::Handle<v8::Object> timingInput = v8::Object::New(isolate);
280     Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), isolate);
281     RefPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, timingInputDictionary);
282
283     RefPtr<TimedItemTiming> specified = animation->specified();
284
285     EXPECT_EQ(0, specified->delay());
286     specified->setDelay(2);
287     EXPECT_EQ(2, specified->delay());
288
289     EXPECT_EQ(0, specified->endDelay());
290     specified->setEndDelay(0.5);
291     EXPECT_EQ(0.5, specified->endDelay());
292
293     EXPECT_EQ("auto", specified->fill());
294     specified->setFill("backwards");
295     EXPECT_EQ("backwards", specified->fill());
296
297     EXPECT_EQ(0, specified->iterationStart());
298     specified->setIterationStart(2);
299     EXPECT_EQ(2, specified->iterationStart());
300
301     EXPECT_EQ(1, specified->iterations());
302     specified->setIterations(10);
303     EXPECT_EQ(10, specified->iterations());
304
305     EXPECT_EQ(1, specified->playbackRate());
306     specified->setPlaybackRate(2);
307     EXPECT_EQ(2, specified->playbackRate());
308
309     EXPECT_EQ("normal", specified->direction());
310     specified->setDirection("reverse");
311     EXPECT_EQ("reverse", specified->direction());
312
313     EXPECT_EQ("linear", specified->easing());
314     specified->setEasing("step-start");
315     EXPECT_EQ("step-start", specified->easing());
316 }
317
318 TEST_F(AnimationAnimationTest, SetSpecifiedDuration)
319 {
320     v8::Isolate* isolate = v8::Isolate::GetCurrent();
321     v8::HandleScope scope(isolate);
322     v8::Local<v8::Context> context = v8::Context::New(isolate);
323     v8::Context::Scope contextScope(context);
324
325     Vector<Dictionary, 0> jsKeyframes;
326     v8::Handle<v8::Object> timingInput = v8::Object::New(isolate);
327     Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), isolate);
328     RefPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, timingInputDictionary);
329
330     RefPtr<TimedItemTiming> specified = animation->specified();
331
332     bool isNumber = false;
333     double numberDuration = std::numeric_limits<double>::quiet_NaN();
334     bool isString = false;
335     String stringDuration = "";
336     specified->getDuration("duration", isNumber, numberDuration, isString, stringDuration);
337     EXPECT_FALSE(isNumber);
338     EXPECT_TRUE(std::isnan(numberDuration));
339     EXPECT_TRUE(isString);
340     EXPECT_EQ("auto", stringDuration);
341
342     specified->setDuration("duration", 2.5);
343     isNumber = false;
344     numberDuration = std::numeric_limits<double>::quiet_NaN();
345     isString = false;
346     stringDuration = "";
347     specified->getDuration("duration", isNumber, numberDuration, isString, stringDuration);
348     EXPECT_TRUE(isNumber);
349     EXPECT_EQ(2.5, numberDuration);
350     EXPECT_FALSE(isString);
351     EXPECT_EQ("", stringDuration);
352 }
353
354 TEST_F(AnimationAnimationTest, TimingInputStartDelay)
355 {
356     v8::Isolate* isolate = v8::Isolate::GetCurrent();
357     v8::HandleScope scope(isolate);
358     v8::Local<v8::Context> context = v8::Context::New(isolate);
359     v8::Context::Scope contextScope(context);
360
361     Timing timing;
362     EXPECT_EQ(0, timing.startDelay);
363
364     applyTimingInputNumber(timing, isolate, "delay", 1.1);
365     EXPECT_EQ(1.1, timing.startDelay);
366     timing.startDelay = 0;
367
368     applyTimingInputNumber(timing, isolate, "delay", -1);
369     EXPECT_EQ(-1, timing.startDelay);
370     timing.startDelay = 0;
371
372     applyTimingInputString(timing, isolate, "delay", "1");
373     EXPECT_EQ(1, timing.startDelay);
374     timing.startDelay = 0;
375
376     applyTimingInputString(timing, isolate, "delay", "1s");
377     EXPECT_EQ(0, timing.startDelay);
378     timing.startDelay = 0;
379
380     applyTimingInputString(timing, isolate, "delay", "Infinity");
381     EXPECT_EQ(0, timing.startDelay);
382     timing.startDelay = 0;
383
384     applyTimingInputString(timing, isolate, "delay", "-Infinity");
385     EXPECT_EQ(0, timing.startDelay);
386     timing.startDelay = 0;
387
388     applyTimingInputString(timing, isolate, "delay", "NaN");
389     EXPECT_EQ(0, timing.startDelay);
390     timing.startDelay = 0;
391
392     applyTimingInputString(timing, isolate, "delay", "rubbish");
393     EXPECT_EQ(0, timing.startDelay);
394     timing.startDelay = 0;
395 }
396
397 TEST_F(AnimationAnimationTest, TimingInputEndDelay)
398 {
399     v8::Isolate* isolate = v8::Isolate::GetCurrent();
400     v8::HandleScope scope(isolate);
401     v8::Local<v8::Context> context = v8::Context::New(isolate);
402     v8::Context::Scope contextScope(context);
403
404     Timing timing;
405     applyTimingInputNumber(timing, isolate, "endDelay", 10);
406     EXPECT_EQ(10, timing.endDelay);
407     applyTimingInputNumber(timing, isolate, "endDelay", -2.5);
408     EXPECT_EQ(-2.5, timing.endDelay);
409 }
410
411 TEST_F(AnimationAnimationTest, TimingInputFillMode)
412 {
413     v8::Isolate* isolate = v8::Isolate::GetCurrent();
414     v8::HandleScope scope(isolate);
415     v8::Local<v8::Context> context = v8::Context::New(isolate);
416     v8::Context::Scope contextScope(context);
417
418     Timing timing;
419     Timing::FillMode defaultFillMode = Timing::FillModeAuto;
420     EXPECT_EQ(defaultFillMode, timing.fillMode);
421
422     applyTimingInputString(timing, isolate, "fill", "auto");
423     EXPECT_EQ(Timing::FillModeAuto, timing.fillMode);
424     timing.fillMode = defaultFillMode;
425
426     applyTimingInputString(timing, isolate, "fill", "forwards");
427     EXPECT_EQ(Timing::FillModeForwards, timing.fillMode);
428     timing.fillMode = defaultFillMode;
429
430     applyTimingInputString(timing, isolate, "fill", "none");
431     EXPECT_EQ(Timing::FillModeNone, timing.fillMode);
432     timing.fillMode = defaultFillMode;
433
434     applyTimingInputString(timing, isolate, "fill", "backwards");
435     EXPECT_EQ(Timing::FillModeBackwards, timing.fillMode);
436     timing.fillMode = defaultFillMode;
437
438     applyTimingInputString(timing, isolate, "fill", "both");
439     EXPECT_EQ(Timing::FillModeBoth, timing.fillMode);
440     timing.fillMode = defaultFillMode;
441
442     applyTimingInputString(timing, isolate, "fill", "everything!");
443     EXPECT_EQ(defaultFillMode, timing.fillMode);
444     timing.fillMode = defaultFillMode;
445
446     applyTimingInputString(timing, isolate, "fill", "backwardsandforwards");
447     EXPECT_EQ(defaultFillMode, timing.fillMode);
448     timing.fillMode = defaultFillMode;
449
450     applyTimingInputNumber(timing, isolate, "fill", 2);
451     EXPECT_EQ(defaultFillMode, timing.fillMode);
452     timing.fillMode = defaultFillMode;
453 }
454
455 TEST_F(AnimationAnimationTest, TimingInputIterationStart)
456 {
457     v8::Isolate* isolate = v8::Isolate::GetCurrent();
458     v8::HandleScope scope(isolate);
459     v8::Local<v8::Context> context = v8::Context::New(isolate);
460     v8::Context::Scope contextScope(context);
461
462     Timing timing;
463     EXPECT_EQ(0, timing.iterationStart);
464
465     applyTimingInputNumber(timing, isolate, "iterationStart", 1.1);
466     EXPECT_EQ(1.1, timing.iterationStart);
467     timing.iterationStart = 0;
468
469     applyTimingInputNumber(timing, isolate, "iterationStart", -1);
470     EXPECT_EQ(0, timing.iterationStart);
471     timing.iterationStart = 0;
472
473     applyTimingInputString(timing, isolate, "iterationStart", "Infinity");
474     EXPECT_EQ(0, timing.iterationStart);
475     timing.iterationStart = 0;
476
477     applyTimingInputString(timing, isolate, "iterationStart", "-Infinity");
478     EXPECT_EQ(0, timing.iterationStart);
479     timing.iterationStart = 0;
480
481     applyTimingInputString(timing, isolate, "iterationStart", "NaN");
482     EXPECT_EQ(0, timing.iterationStart);
483     timing.iterationStart = 0;
484
485     applyTimingInputString(timing, isolate, "iterationStart", "rubbish");
486     EXPECT_EQ(0, timing.iterationStart);
487     timing.iterationStart = 0;
488 }
489
490 TEST_F(AnimationAnimationTest, TimingInputIterationCount)
491 {
492     v8::Isolate* isolate = v8::Isolate::GetCurrent();
493     v8::HandleScope scope(isolate);
494     v8::Local<v8::Context> context = v8::Context::New(isolate);
495     v8::Context::Scope contextScope(context);
496
497     Timing timing;
498     EXPECT_EQ(1, timing.iterationCount);
499
500     applyTimingInputNumber(timing, isolate, "iterations", 2.1);
501     EXPECT_EQ(2.1, timing.iterationCount);
502     timing.iterationCount = 1;
503
504     applyTimingInputNumber(timing, isolate, "iterations", -1);
505     EXPECT_EQ(0, timing.iterationCount);
506     timing.iterationCount = 1;
507
508     applyTimingInputString(timing, isolate, "iterations", "Infinity");
509     EXPECT_TRUE(std::isinf(timing.iterationCount) && (timing.iterationCount > 0));
510     timing.iterationCount = 1;
511
512     applyTimingInputString(timing, isolate, "iterations", "-Infinity");
513     EXPECT_EQ(0, timing.iterationCount);
514     timing.iterationCount = 1;
515
516     applyTimingInputString(timing, isolate, "iterations", "NaN");
517     EXPECT_EQ(1, timing.iterationCount);
518     timing.iterationCount = 1;
519
520     applyTimingInputString(timing, isolate, "iterations", "rubbish");
521     EXPECT_EQ(1, timing.iterationCount);
522     timing.iterationCount = 1;
523 }
524
525 TEST_F(AnimationAnimationTest, TimingInputIterationDuration)
526 {
527     v8::Isolate* isolate = v8::Isolate::GetCurrent();
528     v8::HandleScope scope(isolate);
529     v8::Local<v8::Context> context = v8::Context::New(isolate);
530     v8::Context::Scope contextScope(context);
531
532     Timing timing;
533     EXPECT_TRUE(std::isnan(timing.iterationDuration));
534
535     applyTimingInputNumber(timing, isolate, "duration", 1.1);
536     EXPECT_EQ(1.1, timing.iterationDuration);
537     timing.iterationDuration = std::numeric_limits<double>::quiet_NaN();
538
539     applyTimingInputNumber(timing, isolate, "duration", -1);
540     EXPECT_TRUE(std::isnan(timing.iterationDuration));
541     timing.iterationDuration = std::numeric_limits<double>::quiet_NaN();
542
543     applyTimingInputString(timing, isolate, "duration", "1");
544     EXPECT_EQ(1, timing.iterationDuration);
545     timing.iterationDuration = std::numeric_limits<double>::quiet_NaN();
546
547     applyTimingInputString(timing, isolate, "duration", "Infinity");
548     EXPECT_TRUE(std::isinf(timing.iterationDuration) && (timing.iterationDuration > 0));
549     timing.iterationDuration = std::numeric_limits<double>::quiet_NaN();
550
551     applyTimingInputString(timing, isolate, "duration", "-Infinity");
552     EXPECT_TRUE(std::isnan(timing.iterationDuration));
553     timing.iterationDuration = std::numeric_limits<double>::quiet_NaN();
554
555     applyTimingInputString(timing, isolate, "duration", "NaN");
556     EXPECT_TRUE(std::isnan(timing.iterationDuration));
557     timing.iterationDuration = std::numeric_limits<double>::quiet_NaN();
558
559     applyTimingInputString(timing, isolate, "duration", "auto");
560     EXPECT_TRUE(std::isnan(timing.iterationDuration));
561     timing.iterationDuration = std::numeric_limits<double>::quiet_NaN();
562
563     applyTimingInputString(timing, isolate, "duration", "rubbish");
564     EXPECT_TRUE(std::isnan(timing.iterationDuration));
565     timing.iterationDuration = std::numeric_limits<double>::quiet_NaN();
566 }
567
568 TEST_F(AnimationAnimationTest, TimingInputPlaybackRate)
569 {
570     v8::Isolate* isolate = v8::Isolate::GetCurrent();
571     v8::HandleScope scope(isolate);
572     v8::Local<v8::Context> context = v8::Context::New(isolate);
573     v8::Context::Scope contextScope(context);
574
575     Timing timing;
576     EXPECT_EQ(1, timing.playbackRate);
577
578     applyTimingInputNumber(timing, isolate, "playbackRate", 2.1);
579     EXPECT_EQ(2.1, timing.playbackRate);
580     timing.playbackRate = 1;
581
582     applyTimingInputNumber(timing, isolate, "playbackRate", -1);
583     EXPECT_EQ(-1, timing.playbackRate);
584     timing.playbackRate = 1;
585
586     applyTimingInputString(timing, isolate, "playbackRate", "Infinity");
587     EXPECT_EQ(1, timing.playbackRate);
588     timing.playbackRate = 1;
589
590     applyTimingInputString(timing, isolate, "playbackRate", "-Infinity");
591     EXPECT_EQ(1, timing.playbackRate);
592     timing.playbackRate = 1;
593
594     applyTimingInputString(timing, isolate, "playbackRate", "NaN");
595     EXPECT_EQ(1, timing.playbackRate);
596     timing.playbackRate = 1;
597
598     applyTimingInputString(timing, isolate, "playbackRate", "rubbish");
599     EXPECT_EQ(1, timing.playbackRate);
600     timing.playbackRate = 1;
601 }
602
603 TEST_F(AnimationAnimationTest, TimingInputDirection)
604 {
605     v8::Isolate* isolate = v8::Isolate::GetCurrent();
606     v8::HandleScope scope(isolate);
607     v8::Local<v8::Context> context = v8::Context::New(isolate);
608     v8::Context::Scope contextScope(context);
609
610     Timing timing;
611     Timing::PlaybackDirection defaultPlaybackDirection = Timing::PlaybackDirectionNormal;
612     EXPECT_EQ(defaultPlaybackDirection, timing.direction);
613
614     applyTimingInputString(timing, isolate, "direction", "normal");
615     EXPECT_EQ(Timing::PlaybackDirectionNormal, timing.direction);
616     timing.direction = defaultPlaybackDirection;
617
618     applyTimingInputString(timing, isolate, "direction", "reverse");
619     EXPECT_EQ(Timing::PlaybackDirectionReverse, timing.direction);
620     timing.direction = defaultPlaybackDirection;
621
622     applyTimingInputString(timing, isolate, "direction", "alternate");
623     EXPECT_EQ(Timing::PlaybackDirectionAlternate, timing.direction);
624     timing.direction = defaultPlaybackDirection;
625
626     applyTimingInputString(timing, isolate, "direction", "alternate-reverse");
627     EXPECT_EQ(Timing::PlaybackDirectionAlternateReverse, timing.direction);
628     timing.direction = defaultPlaybackDirection;
629
630     applyTimingInputString(timing, isolate, "direction", "rubbish");
631     EXPECT_EQ(defaultPlaybackDirection, timing.direction);
632     timing.direction = defaultPlaybackDirection;
633
634     applyTimingInputNumber(timing, isolate, "direction", 2);
635     EXPECT_EQ(defaultPlaybackDirection, timing.direction);
636     timing.direction = defaultPlaybackDirection;
637 }
638
639 TEST_F(AnimationAnimationTest, TimingInputTimingFunction)
640 {
641     v8::Isolate* isolate = v8::Isolate::GetCurrent();
642     v8::HandleScope scope(isolate);
643     v8::Local<v8::Context> context = v8::Context::New(isolate);
644     v8::Context::Scope contextScope(context);
645
646     Timing timing;
647     const RefPtr<TimingFunction> defaultTimingFunction = LinearTimingFunction::create();
648     EXPECT_EQ(*defaultTimingFunction.get(), *timing.timingFunction.get());
649
650     applyTimingInputString(timing, isolate, "easing", "ease");
651     EXPECT_EQ(*(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease)), *timing.timingFunction.get());
652     timing.timingFunction = defaultTimingFunction;
653
654     applyTimingInputString(timing, isolate, "easing", "ease-in");
655     EXPECT_EQ(*(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn)), *timing.timingFunction.get());
656     timing.timingFunction = defaultTimingFunction;
657
658     applyTimingInputString(timing, isolate, "easing", "ease-out");
659     EXPECT_EQ(*(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseOut)), *timing.timingFunction.get());
660     timing.timingFunction = defaultTimingFunction;
661
662     applyTimingInputString(timing, isolate, "easing", "ease-in-out");
663     EXPECT_EQ(*(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut)), *timing.timingFunction.get());
664     timing.timingFunction = defaultTimingFunction;
665
666     applyTimingInputString(timing, isolate, "easing", "linear");
667     EXPECT_EQ(*(LinearTimingFunction::create()), *timing.timingFunction.get());
668     timing.timingFunction = defaultTimingFunction;
669
670     applyTimingInputString(timing, isolate, "easing", "initial");
671     EXPECT_EQ(*defaultTimingFunction.get(), *timing.timingFunction.get());
672     timing.timingFunction = defaultTimingFunction;
673
674     applyTimingInputString(timing, isolate, "easing", "step-start");
675     EXPECT_EQ(*(StepsTimingFunction::preset(StepsTimingFunction::Start)), *timing.timingFunction.get());
676     timing.timingFunction = defaultTimingFunction;
677
678     applyTimingInputString(timing, isolate, "easing", "step-end");
679     EXPECT_EQ(*(StepsTimingFunction::preset(StepsTimingFunction::End)), *timing.timingFunction.get());
680     timing.timingFunction = defaultTimingFunction;
681
682     applyTimingInputString(timing, isolate, "easing", "cubic-bezier(1, 1, 0.3, 0.3)");
683     EXPECT_EQ(*(CubicBezierTimingFunction::create(1, 1, 0.3, 0.3).get()), *timing.timingFunction.get());
684     timing.timingFunction = defaultTimingFunction;
685
686     applyTimingInputString(timing, isolate, "easing", "steps(3, start)");
687     EXPECT_EQ(*(StepsTimingFunction::create(3, true).get()), *timing.timingFunction.get());
688     timing.timingFunction = defaultTimingFunction;
689
690     applyTimingInputString(timing, isolate, "easing", "steps(5, end)");
691     EXPECT_EQ(*(StepsTimingFunction::create(5, false).get()), *timing.timingFunction.get());
692     timing.timingFunction = defaultTimingFunction;
693
694     applyTimingInputString(timing, isolate, "easing", "steps(5.6, end)");
695     EXPECT_EQ(*defaultTimingFunction.get(), *timing.timingFunction.get());
696     timing.timingFunction = defaultTimingFunction;
697
698     // FIXME: Step-middle not yet implemented. Change this test when it is working.
699     applyTimingInputString(timing, isolate, "easing", "steps(5, middle)");
700     EXPECT_EQ(*defaultTimingFunction.get(), *timing.timingFunction.get());
701     timing.timingFunction = defaultTimingFunction;
702
703     applyTimingInputString(timing, isolate, "easing", "cubic-bezier(2, 2, 0.3, 0.3)");
704     EXPECT_EQ(*defaultTimingFunction.get(), *timing.timingFunction.get());
705     timing.timingFunction = defaultTimingFunction;
706
707     applyTimingInputString(timing, isolate, "easing", "rubbish");
708     EXPECT_EQ(*defaultTimingFunction.get(), *timing.timingFunction.get());
709     timing.timingFunction = defaultTimingFunction;
710
711     applyTimingInputNumber(timing, isolate, "easing", 2);
712     EXPECT_EQ(*defaultTimingFunction.get(), *timing.timingFunction.get());
713     timing.timingFunction = defaultTimingFunction;
714 }
715
716 TEST_F(AnimationAnimationTest, TimingInputEmpty)
717 {
718     v8::Isolate* isolate = v8::Isolate::GetCurrent();
719     v8::HandleScope scope(isolate);
720     v8::Local<v8::Context> context = v8::Context::New(isolate);
721     v8::Context::Scope contextScope(context);
722
723     Timing updatedTiming;
724     Timing controlTiming;
725
726     v8::Handle<v8::Object> timingInput = v8::Object::New(isolate);
727     Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), isolate);
728     populateTiming(updatedTiming, timingInputDictionary);
729
730     EXPECT_EQ(controlTiming.startDelay, updatedTiming.startDelay);
731     EXPECT_EQ(controlTiming.fillMode, updatedTiming.fillMode);
732     EXPECT_EQ(controlTiming.iterationStart, updatedTiming.iterationStart);
733     EXPECT_EQ(controlTiming.iterationCount, updatedTiming.iterationCount);
734     EXPECT_TRUE(std::isnan(updatedTiming.iterationDuration));
735     EXPECT_EQ(controlTiming.playbackRate, updatedTiming.playbackRate);
736     EXPECT_EQ(controlTiming.direction, updatedTiming.direction);
737     EXPECT_EQ(*controlTiming.timingFunction.get(), *updatedTiming.timingFunction.get());
738 }
739
740 TEST_F(AnimationAnimationTest, TimeToEffectChange)
741 {
742     Timing timing;
743     timing.iterationDuration = 100;
744     timing.startDelay = 100;
745     timing.endDelay = 100;
746     timing.fillMode = Timing::FillModeNone;
747     RefPtr<Animation> animation = Animation::create(0, 0, timing);
748     RefPtr<Player> player = document->timeline()->play(animation.get());
749     double inf = std::numeric_limits<double>::infinity();
750
751     EXPECT_EQ(100, animation->timeToForwardsEffectChange());
752     EXPECT_EQ(inf, animation->timeToReverseEffectChange());
753
754     player->setCurrentTime(100);
755     EXPECT_EQ(0, animation->timeToForwardsEffectChange());
756     EXPECT_EQ(0, animation->timeToReverseEffectChange());
757
758     player->setCurrentTime(199);
759     EXPECT_EQ(0, animation->timeToForwardsEffectChange());
760     EXPECT_EQ(0, animation->timeToReverseEffectChange());
761
762     player->setCurrentTime(200);
763     // End-exclusive.
764     EXPECT_EQ(inf, animation->timeToForwardsEffectChange());
765     EXPECT_EQ(0, animation->timeToReverseEffectChange());
766
767     player->setCurrentTime(300);
768     EXPECT_EQ(inf, animation->timeToForwardsEffectChange());
769     EXPECT_EQ(100, animation->timeToReverseEffectChange());
770 }
771
772 TEST_F(AnimationAnimationTest, TimeToEffectChangeWithPlaybackRate)
773 {
774     Timing timing;
775     timing.iterationDuration = 100;
776     timing.startDelay = 100;
777     timing.endDelay = 100;
778     timing.playbackRate = 2;
779     timing.fillMode = Timing::FillModeNone;
780     RefPtr<Animation> animation = Animation::create(0, 0, timing);
781     RefPtr<Player> player = document->timeline()->play(animation.get());
782     double inf = std::numeric_limits<double>::infinity();
783
784     EXPECT_EQ(100, animation->timeToForwardsEffectChange());
785     EXPECT_EQ(inf, animation->timeToReverseEffectChange());
786
787     player->setCurrentTime(100);
788     EXPECT_EQ(0, animation->timeToForwardsEffectChange());
789     EXPECT_EQ(0, animation->timeToReverseEffectChange());
790
791     player->setCurrentTime(149);
792     EXPECT_EQ(0, animation->timeToForwardsEffectChange());
793     EXPECT_EQ(0, animation->timeToReverseEffectChange());
794
795     player->setCurrentTime(150);
796     // End-exclusive.
797     EXPECT_EQ(inf, animation->timeToForwardsEffectChange());
798     EXPECT_EQ(0, animation->timeToReverseEffectChange());
799
800     player->setCurrentTime(200);
801     EXPECT_EQ(inf, animation->timeToForwardsEffectChange());
802     EXPECT_EQ(50, animation->timeToReverseEffectChange());
803 }
804
805 TEST_F(AnimationAnimationTest, TimeToEffectChangeWithNegativePlaybackRate)
806 {
807     Timing timing;
808     timing.iterationDuration = 100;
809     timing.startDelay = 100;
810     timing.endDelay = 100;
811     timing.playbackRate = -2;
812     timing.fillMode = Timing::FillModeNone;
813     RefPtr<Animation> animation = Animation::create(0, 0, timing);
814     RefPtr<Player> player = document->timeline()->play(animation.get());
815     double inf = std::numeric_limits<double>::infinity();
816
817     EXPECT_EQ(100, animation->timeToForwardsEffectChange());
818     EXPECT_EQ(inf, animation->timeToReverseEffectChange());
819
820     player->setCurrentTime(100);
821     EXPECT_EQ(0, animation->timeToForwardsEffectChange());
822     EXPECT_EQ(0, animation->timeToReverseEffectChange());
823
824     player->setCurrentTime(149);
825     EXPECT_EQ(0, animation->timeToForwardsEffectChange());
826     EXPECT_EQ(0, animation->timeToReverseEffectChange());
827
828     player->setCurrentTime(150);
829     EXPECT_EQ(inf, animation->timeToForwardsEffectChange());
830     EXPECT_EQ(0, animation->timeToReverseEffectChange());
831
832     player->setCurrentTime(200);
833     EXPECT_EQ(inf, animation->timeToForwardsEffectChange());
834     EXPECT_EQ(50, animation->timeToReverseEffectChange());
835 }
836
837 } // namespace WebCore