Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / animation / DocumentTimelineTest.cpp
1 /*
2  * Copyright (c) 2013, Google Inc. All rights reserved.
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  */
30
31 #include "config.h"
32 #include "core/animation/DocumentTimeline.h"
33
34 #include "core/animation/Animation.h"
35 #include "core/animation/AnimationClock.h"
36 #include "core/animation/KeyframeEffectModel.h"
37 #include "core/animation/TimedItem.h"
38 #include "core/dom/Document.h"
39 #include "core/dom/Element.h"
40 #include "core/dom/QualifiedName.h"
41 #include "platform/weborigin/KURL.h"
42
43 #include <gmock/gmock.h>
44 #include <gtest/gtest.h>
45
46 namespace WebCore {
47
48 class MockPlatformTiming : public DocumentTimeline::PlatformTiming {
49 public:
50
51     MOCK_METHOD1(wakeAfter, void(double));
52     MOCK_METHOD0(cancelWake, void());
53     MOCK_METHOD0(serviceOnNextFrame, void());
54
55     /**
56      * DocumentTimelines should do one of the following things after servicing animations:
57      *  - cancel the timer and not request to be woken again (expectNoMoreActions)
58      *  - cancel the timer and request to be woken on the next frame (expectNextFrameAction)
59      *  - cancel the timer and request to be woken at some point in the future (expectDelayedAction)
60      */
61
62     void expectNoMoreActions()
63     {
64         EXPECT_CALL(*this, cancelWake());
65     }
66
67     void expectNextFrameAction()
68     {
69         ::testing::Sequence sequence;
70         EXPECT_CALL(*this, cancelWake()).InSequence(sequence);
71         EXPECT_CALL(*this, serviceOnNextFrame()).InSequence(sequence);
72     }
73
74     void expectDelayedAction(double when)
75     {
76         ::testing::Sequence sequence;
77         EXPECT_CALL(*this, cancelWake()).InSequence(sequence);
78         EXPECT_CALL(*this, wakeAfter(when)).InSequence(sequence);
79     }
80 };
81
82 class AnimationDocumentTimelineTest : public ::testing::Test {
83 protected:
84     virtual void SetUp()
85     {
86         document = Document::create();
87         document->animationClock().resetTimeForTesting();
88         element = Element::create(nullQName() , document.get());
89         platformTiming = new MockPlatformTiming;
90         timeline = DocumentTimeline::create(document.get(), adoptPtr(platformTiming));
91         timeline->setZeroTime(0);
92         ASSERT_EQ(0, timeline->currentTime());
93     }
94
95     virtual void TearDown()
96     {
97         timeline.release();
98         document.release();
99         element.release();
100     }
101
102     void updateClockAndService(double time)
103     {
104         document->animationClock().updateTime(time);
105         timeline->serviceAnimations();
106     }
107
108     RefPtr<Document> document;
109     RefPtr<Element> element;
110     RefPtr<DocumentTimeline> timeline;
111     Timing timing;
112     MockPlatformTiming* platformTiming;
113
114     void wake()
115     {
116         timeline->wake();
117     }
118
119     double minimumDelay()
120     {
121         return DocumentTimeline::s_minimumDelay;
122     }
123 };
124
125 TEST_F(AnimationDocumentTimelineTest, HasStarted)
126 {
127     timeline = DocumentTimeline::create(document.get());
128     EXPECT_FALSE(timeline->hasStarted());
129     timeline->setZeroTime(0);
130     EXPECT_TRUE(timeline->hasStarted());
131 }
132
133 TEST_F(AnimationDocumentTimelineTest, EmptyKeyframeAnimation)
134 {
135     RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(KeyframeEffectModel::KeyframeVector());
136     RefPtr<Animation> anim = Animation::create(element.get(), effect, timing);
137
138     timeline->play(anim.get());
139
140     platformTiming->expectNoMoreActions();
141     updateClockAndService(0);
142     EXPECT_FLOAT_EQ(0, timeline->currentTime());
143     EXPECT_FALSE(anim->isInEffect());
144
145     platformTiming->expectNoMoreActions();
146     updateClockAndService(100);
147     EXPECT_FLOAT_EQ(100, timeline->currentTime());
148 }
149
150 TEST_F(AnimationDocumentTimelineTest, EmptyForwardsKeyframeAnimation)
151 {
152     RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(KeyframeEffectModel::KeyframeVector());
153     timing.fillMode = Timing::FillModeForwards;
154     RefPtr<Animation> anim = Animation::create(element.get(), effect, timing);
155
156     timeline->play(anim.get());
157
158     platformTiming->expectNoMoreActions();
159     updateClockAndService(0);
160     EXPECT_FLOAT_EQ(0, timeline->currentTime());
161     EXPECT_TRUE(anim->isInEffect());
162     EXPECT_TRUE(anim->compositableValues()->isEmpty());
163
164     platformTiming->expectNoMoreActions();
165     updateClockAndService(100);
166     EXPECT_FLOAT_EQ(100, timeline->currentTime());
167 }
168
169 TEST_F(AnimationDocumentTimelineTest, EmptyTimelineDoesNotTriggerStyleRecalc)
170 {
171     document->animationClock().updateTime(100);
172     EXPECT_FALSE(timeline->serviceAnimations());
173 }
174
175 TEST_F(AnimationDocumentTimelineTest, EmptyPlayerDoesNotTriggerStyleRecalc)
176 {
177     timeline->play(0);
178     document->animationClock().updateTime(100);
179     EXPECT_FALSE(timeline->serviceAnimations());
180 }
181
182 TEST_F(AnimationDocumentTimelineTest, EmptyTargetDoesNotTriggerStyleRecalc)
183 {
184     timing.iterationDuration = 200;
185     timeline->play(Animation::create(0, KeyframeEffectModel::create(KeyframeEffectModel::KeyframeVector()), timing).get());
186     document->animationClock().updateTime(100);
187     EXPECT_FALSE(timeline->serviceAnimations());
188 }
189
190 TEST_F(AnimationDocumentTimelineTest, EmptyEffectDoesNotTriggerStyleRecalc)
191 {
192     timeline->play(Animation::create(element.get(), 0, timing).get());
193     document->animationClock().updateTime(100);
194     EXPECT_FALSE(timeline->serviceAnimations());
195 }
196
197 TEST_F(AnimationDocumentTimelineTest, TriggerStyleRecalc)
198 {
199     timing.iterationDuration = 200;
200     timeline->play(Animation::create(element.get(), KeyframeEffectModel::create(KeyframeEffectModel::KeyframeVector()), timing).get());
201     document->animationClock().updateTime(100);
202     EXPECT_TRUE(timeline->serviceAnimations());
203 }
204
205 TEST_F(AnimationDocumentTimelineTest, ZeroTime)
206 {
207     timeline = DocumentTimeline::create(document.get());
208
209     document->animationClock().updateTime(100);
210     EXPECT_TRUE(isNull(timeline->currentTime()));
211
212     document->animationClock().updateTime(200);
213     EXPECT_TRUE(isNull(timeline->currentTime()));
214
215     timeline->setZeroTime(300);
216     document->animationClock().updateTime(300);
217     EXPECT_EQ(0, timeline->currentTime());
218
219     document->animationClock().updateTime(400);
220     EXPECT_EQ(100, timeline->currentTime());
221 }
222
223 TEST_F(AnimationDocumentTimelineTest, PauseForTesting)
224 {
225     float seekTime = 1;
226     timing.fillMode = Timing::FillModeForwards;
227     RefPtr<Animation> anim1 = Animation::create(element.get(), KeyframeEffectModel::create(KeyframeEffectModel::KeyframeVector()), timing);
228     RefPtr<Animation> anim2  = Animation::create(element.get(), KeyframeEffectModel::create(KeyframeEffectModel::KeyframeVector()), timing);
229     Player* player1 = timeline->play(anim1.get());
230     Player* player2 = timeline->play(anim2.get());
231     timeline->pauseAnimationsForTesting(seekTime);
232
233     EXPECT_FLOAT_EQ(seekTime, player1->currentTime());
234     EXPECT_FLOAT_EQ(seekTime, player2->currentTime());
235 }
236
237 TEST_F(AnimationDocumentTimelineTest, NumberOfActiveAnimations)
238 {
239     Timing timingForwardFill;
240     timingForwardFill.iterationDuration = 2;
241     timingForwardFill.fillMode = Timing::FillModeForwards;
242
243     Timing timingNoFill;
244     timingNoFill.iterationDuration = 2;
245     timingNoFill.fillMode = Timing::FillModeNone;
246
247     Timing timingBackwardFillDelay;
248     timingBackwardFillDelay.iterationDuration = 1;
249     timingBackwardFillDelay.fillMode = Timing::FillModeBackwards;
250     timingBackwardFillDelay.startDelay = 1;
251
252     Timing timingNoFillDelay;
253     timingNoFillDelay.iterationDuration = 1;
254     timingNoFillDelay.fillMode = Timing::FillModeNone;
255     timingNoFillDelay.startDelay = 1;
256
257     Timing timingAutoFill;
258     timingAutoFill.iterationDuration = 2;
259
260     RefPtr<Animation> anim1 = Animation::create(element.get(), KeyframeEffectModel::create(KeyframeEffectModel::KeyframeVector()), timingForwardFill);
261     RefPtr<Animation> anim2 = Animation::create(element.get(), KeyframeEffectModel::create(KeyframeEffectModel::KeyframeVector()), timingNoFill);
262     RefPtr<Animation> anim3 = Animation::create(element.get(), KeyframeEffectModel::create(KeyframeEffectModel::KeyframeVector()), timingBackwardFillDelay);
263     RefPtr<Animation> anim4 = Animation::create(element.get(), KeyframeEffectModel::create(KeyframeEffectModel::KeyframeVector()), timingNoFillDelay);
264     RefPtr<Animation> anim5 = Animation::create(element.get(), KeyframeEffectModel::create(KeyframeEffectModel::KeyframeVector()), timingAutoFill);
265
266     timeline->play(anim1.get());
267     timeline->play(anim2.get());
268     timeline->play(anim3.get());
269     timeline->play(anim4.get());
270     timeline->play(anim5.get());
271
272     platformTiming->expectNextFrameAction();
273     updateClockAndService(0);
274     EXPECT_EQ(5U, timeline->numberOfActiveAnimationsForTesting());
275     platformTiming->expectNextFrameAction();
276     updateClockAndService(0.5);
277     EXPECT_EQ(5U, timeline->numberOfActiveAnimationsForTesting());
278     platformTiming->expectNextFrameAction();
279     updateClockAndService(1.5);
280     EXPECT_EQ(5U, timeline->numberOfActiveAnimationsForTesting());
281     platformTiming->expectNoMoreActions();
282     updateClockAndService(3);
283     EXPECT_EQ(1U, timeline->numberOfActiveAnimationsForTesting());
284 }
285
286 TEST_F(AnimationDocumentTimelineTest, DelayBeforeAnimationStart)
287 {
288     timing.iterationDuration = 2;
289     timing.startDelay = 5;
290
291     RefPtr<Animation> anim = Animation::create(element.get(), 0, timing);
292
293     timeline->play(anim.get());
294
295     // TODO: Put the player startTime in the future when we add the capability to change player startTime
296     platformTiming->expectDelayedAction(timing.startDelay - minimumDelay());
297     updateClockAndService(0);
298
299     platformTiming->expectDelayedAction(timing.startDelay - minimumDelay() - 1.5);
300     updateClockAndService(1.5);
301
302     EXPECT_CALL(*platformTiming, serviceOnNextFrame());
303     wake();
304
305     platformTiming->expectNextFrameAction();
306     updateClockAndService(4.98);
307 }
308
309 TEST_F(AnimationDocumentTimelineTest, PlayAfterDocumentDeref)
310 {
311     timing.iterationDuration = 2;
312     timing.startDelay = 5;
313
314     timeline = document->timeline();
315     element = 0;
316     document = 0;
317
318     RefPtr<Animation> anim = Animation::create(0, 0, timing);
319     // Test passes if this does not crash.
320     timeline->play(anim.get());
321 }
322
323 TEST_F(AnimationDocumentTimelineTest, UsePlayerAfterTimelineDeref)
324 {
325     RefPtr<Player> player = timeline->createPlayer(0);
326     timeline.clear();
327     // Test passes if this does not crash.
328     player->setStartTime(0);
329 }
330
331 }