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/Player.h"
33
34#include "core/animation/DocumentTimeline.h"
35#include "core/dom/Document.h"
36#include "core/dom/QualifiedName.h"
37#include "weborigin/KURL.h"
38#include <gtest/gtest.h>
39
40using namespace WebCore;
41
42namespace {
43
44class PlayerTest : public ::testing::Test {
45protected:
46    virtual void SetUp()
47    {
48        document = Document::create();
49        timeline = DocumentTimeline::create(document.get());
50        player = Player::create(timeline.get(), 0);
51    }
52
53    bool updateTimeline(double time)
54    {
55        timeline->serviceAnimations(time);
56        // The timeline does not know about our player, so we have to explicitly call update().
57        return player->update();
58    }
59
60    RefPtr<Document> document;
61    RefPtr<DocumentTimeline> timeline;
62    RefPtr<Player> player;
63};
64
65TEST_F(PlayerTest, InitialState)
66{
67    EXPECT_TRUE(isNull(timeline->currentTime()));
68    EXPECT_EQ(0, player->currentTime());
69    EXPECT_FALSE(player->paused());
70    EXPECT_EQ(1, player->playbackRate());
71    EXPECT_EQ(0, player->startTime());
72    EXPECT_EQ(0, player->timeDrift());
73}
74
75TEST_F(PlayerTest, CreatePlayerAfterTimelineStarted)
76{
77    updateTimeline(1234);
78    EXPECT_EQ(1234, timeline->currentTime());
79    RefPtr<Player> player = Player::create(timeline.get(), 0);
80    EXPECT_EQ(1234, player->startTime());
81    EXPECT_EQ(0, player->currentTime());
82}
83
84TEST_F(PlayerTest, PauseUnpause)
85{
86    updateTimeline(200);
87    player->setPaused(true);
88    EXPECT_TRUE(player->paused());
89    EXPECT_EQ(200, player->currentTime());
90    EXPECT_EQ(0, player->timeDrift());
91
92    updateTimeline(400);
93    player->setPaused(false);
94    EXPECT_FALSE(player->paused());
95    EXPECT_EQ(200, player->currentTime());
96    EXPECT_EQ(200, player->timeDrift());
97
98    updateTimeline(600);
99    EXPECT_EQ(400, player->currentTime());
100    EXPECT_EQ(200, player->timeDrift());
101}
102
103TEST_F(PlayerTest, PauseBeforeTimelineStarted)
104{
105    player->setPaused(true);
106    EXPECT_TRUE(player->paused());
107    EXPECT_EQ(0, player->currentTime());
108    EXPECT_EQ(0, player->timeDrift());
109
110    player->setPaused(false);
111    EXPECT_FALSE(player->paused());
112    EXPECT_EQ(0, player->currentTime());
113    EXPECT_EQ(0, player->timeDrift());
114
115    player->setPaused(true);
116    updateTimeline(100);
117    EXPECT_TRUE(player->paused());
118    EXPECT_EQ(0, player->currentTime());
119    EXPECT_EQ(100, player->timeDrift());
120
121    player->setPaused(false);
122    EXPECT_EQ(0, player->currentTime());
123    EXPECT_EQ(100, player->timeDrift());
124}
125
126TEST_F(PlayerTest, SetCurrentTime)
127{
128    updateTimeline(0);
129    player->setCurrentTime(250);
130    EXPECT_EQ(250, player->currentTime());
131    EXPECT_EQ(-250, player->timeDrift());
132}
133
134TEST_F(PlayerTest, SetCurrentTimeBeforeTimelineStarted)
135{
136    player->setCurrentTime(250);
137    EXPECT_EQ(250, player->currentTime());
138    EXPECT_EQ(-250, player->timeDrift());
139
140    updateTimeline(0);
141    EXPECT_EQ(250, player->currentTime());
142}
143
144TEST_F(PlayerTest, SetPlaybackRate)
145{
146    updateTimeline(0);
147    player->setPlaybackRate(2);
148    EXPECT_EQ(2, player->playbackRate());
149    EXPECT_EQ(0, player->currentTime());
150    EXPECT_EQ(0, player->timeDrift());
151
152    updateTimeline(100);
153    EXPECT_EQ(200, player->currentTime());
154    EXPECT_EQ(0, player->timeDrift());
155}
156
157TEST_F(PlayerTest, SetPlaybackRateBeforeTimelineStarted)
158{
159    player->setPlaybackRate(2);
160    EXPECT_EQ(0, player->currentTime());
161    EXPECT_EQ(0, player->timeDrift());
162
163    updateTimeline(100);
164    EXPECT_EQ(200, player->currentTime());
165    EXPECT_EQ(0, player->timeDrift());
166}
167
168TEST_F(PlayerTest, SetPlaybackRateWhilePaused)
169{
170    updateTimeline(100);
171    player->setPaused(true);
172    player->setPlaybackRate(2);
173    EXPECT_EQ(100, player->currentTime());
174    EXPECT_EQ(100, player->timeDrift());
175
176    updateTimeline(200);
177    player->setPaused(false);
178    EXPECT_EQ(100, player->currentTime());
179    EXPECT_EQ(300, player->timeDrift());
180
181    updateTimeline(250);
182    EXPECT_EQ(200, player->currentTime());
183    EXPECT_EQ(300, player->timeDrift());
184}
185
186TEST_F(PlayerTest, SetPlaybackRateNaN)
187{
188    updateTimeline(0);
189    player->setPlaybackRate(nullValue());
190    EXPECT_TRUE(isNull(player->playbackRate()));
191    EXPECT_TRUE(isNull(player->currentTime()));
192    EXPECT_TRUE(isNull(player->timeDrift()));
193
194    updateTimeline(100);
195    EXPECT_TRUE(isNull(player->currentTime()));
196    EXPECT_TRUE(isNull(player->timeDrift()));
197}
198
199TEST_F(PlayerTest, SetPlaybackRateInfinity)
200{
201    updateTimeline(0);
202    player->setPlaybackRate(std::numeric_limits<double>::infinity());
203    EXPECT_EQ(std::numeric_limits<double>::infinity(), player->playbackRate());
204    EXPECT_TRUE(isNull(player->currentTime()));
205    EXPECT_TRUE(isNull(player->timeDrift()));
206
207    updateTimeline(100);
208    EXPECT_TRUE(isNull(player->currentTime()));
209    EXPECT_TRUE(isNull(player->timeDrift()));
210}
211
212TEST_F(PlayerTest, SetPlaybackRateMax)
213{
214    updateTimeline(0);
215    player->setPlaybackRate(std::numeric_limits<double>::max());
216    EXPECT_EQ(std::numeric_limits<double>::max(), player->playbackRate());
217    EXPECT_EQ(0, player->currentTime());
218    EXPECT_EQ(0, player->timeDrift());
219
220    updateTimeline(100);
221    EXPECT_EQ(std::numeric_limits<double>::infinity(), player->currentTime());
222}
223
224TEST_F(PlayerTest, SetCurrentTimeNan)
225{
226    updateTimeline(0);
227    player->setCurrentTime(nullValue());
228    EXPECT_TRUE(isNull(player->currentTime()));
229    EXPECT_TRUE(isNull(player->timeDrift()));
230
231    updateTimeline(100);
232    EXPECT_TRUE(isNull(player->currentTime()));
233    EXPECT_TRUE(isNull(player->timeDrift()));
234}
235
236TEST_F(PlayerTest, SetCurrentTimeInfinity)
237{
238    updateTimeline(0);
239    player->setCurrentTime(std::numeric_limits<double>::infinity());
240    EXPECT_EQ(std::numeric_limits<double>::infinity(), player->currentTime());
241    EXPECT_EQ(-std::numeric_limits<double>::infinity(), player->timeDrift());
242
243    updateTimeline(100);
244    EXPECT_EQ(std::numeric_limits<double>::infinity(), player->currentTime());
245    EXPECT_EQ(-std::numeric_limits<double>::infinity(), player->timeDrift());
246}
247
248TEST_F(PlayerTest, SetCurrentTimeMax)
249{
250    updateTimeline(0);
251    player->setCurrentTime(std::numeric_limits<double>::max());
252    EXPECT_EQ(std::numeric_limits<double>::max(), player->currentTime());
253    EXPECT_EQ(-std::numeric_limits<double>::max(), player->timeDrift());
254
255    updateTimeline(100);
256    EXPECT_EQ(std::numeric_limits<double>::max(), player->currentTime());
257    EXPECT_EQ(-std::numeric_limits<double>::max(), player->timeDrift());
258}
259
260}
261