Web Animations: Add tests for player state transitions and fix discovered issues

BUG=396372,410229

Review URL: https://codereview.chromium.org/555063002

git-svn-id: svn://svn.chromium.org/blink/trunk@181716 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent e9932e62
<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script>
function assert_unresolved(value) {
assert_equals(value, null);
}
function idlePlayer() {
var player = document.documentElement.animate([], 100000);
player.cancel();
return player;
}
function runningPlayer() {
var player = document.documentElement.animate([], 100000);
player.startTime = document.timeline.currentTime;
return player;
}
function pendingStartTimePlayer() {
var player = document.documentElement.animate([], 100000);
return player;
}
function pendingStartTimeAndCurrentTimePlayer() {
var player = document.documentElement.animate([], 100000);
player.pause();
player.play();
return player;
}
function pausedPlayer() {
var player = document.documentElement.animate([], 100000);
player.pause();
player.currentTime = 0;
return player;
}
function finishedPlayer() {
var player = document.documentElement.animate([], 100000);
player.finish();
return player;
}
test(function() {
var player = idlePlayer();
assert_unresolved(player.startTime);
assert_unresolved(player.currentTime);
assert_equals(player.playState, 'idle');
}, "idle");
test(function() {
var player = pendingStartTimePlayer();
assert_unresolved(player.startTime);
assert_equals(player.currentTime, 0);
assert_equals(player.playState, 'pending');
}, "pending startTime");
test(function() {
var player = pendingStartTimeAndCurrentTimePlayer();
assert_unresolved(player.startTime);
assert_unresolved(player.currentTime);
assert_equals(player.playState, 'pending');
}, "pending startTime and currentTime");
test(function() {
var player = runningPlayer();
assert_equals(player.startTime, document.timeline.currentTime - player.currentTime);
assert_equals(player.currentTime, 0);
assert_equals(player.playState, 'running');
}, "running");
test(function() {
var player = pausedPlayer();
assert_unresolved(player.startTime);
assert_equals(player.currentTime, 0);
assert_equals(player.playState, 'paused');
}, "paused");
test(function() {
var player = finishedPlayer();
assert_equals(player.startTime, document.timeline.currentTime - player.currentTime);
assert_equals(player.currentTime, 100000);
assert_equals(player.playState, 'finished');
}, "finished");
test(function() {
var player = idlePlayer();
player.play();
assert_unresolved(player.startTime);
assert_equals(player.currentTime, 0);
assert_equals(player.playState, 'pending');
}, "idle -> play()");
test(function() {
var player = idlePlayer();
player.pause();
assert_unresolved(player.startTime);
assert_unresolved(player.currentTime);
assert_equals(player.playState, 'idle');
}, "idle -> pause()");
test(function() {
var player = idlePlayer();
player.cancel();
assert_unresolved(player.startTime);
assert_unresolved(player.currentTime);
assert_equals(player.playState, 'idle');
}, "idle -> cancel()");
test(function() {
var player = idlePlayer();
player.finish();
assert_unresolved(player.startTime);
assert_unresolved(player.currentTime);
assert_equals(player.playState, 'idle');
}, "idle -> finish()");
test(function() {
var player = idlePlayer();
player.reverse();
assert_unresolved(player.startTime);
assert_equals(player.currentTime, 100000);
assert_equals(player.playState, 'pending');
}, "idle -> reverse()");
test(function() {
var player = idlePlayer();
player.currentTime = 1000;
assert_unresolved(player.startTime);
assert_unresolved(player.currentTime);
assert_equals(player.playState, 'idle');
}, "idle -> set currentTime");
test(function() {
var player = idlePlayer();
player.startTime = 1000;
assert_unresolved(player.startTime);
assert_unresolved(player.currentTime);
assert_equals(player.playState, 'idle');
}, "idle -> set startTime");
test(function() {
var player = pendingStartTimePlayer();
player.play();
assert_unresolved(player.startTime);
assert_equals(player.currentTime, 0);
assert_equals(player.playState, 'pending');
}, "pending startTime -> play()");
test(function() {
var player = pendingStartTimePlayer();
player.pause();
assert_unresolved(player.startTime);
assert_unresolved(player.currentTime);
assert_equals(player.playState, 'pending');
}, "pending startTime -> pause()");
test(function() {
var player = pendingStartTimePlayer();
player.cancel();
assert_unresolved(player.startTime);
assert_unresolved(player.currentTime);
assert_equals(player.playState, 'idle');
}, "pending startTime -> cancel()");
test(function() {
var player = pendingStartTimePlayer();
player.finish();
assert_equals(player.startTime, document.timeline.currentTime - player.currentTime);
assert_equals(player.currentTime, 100000);
assert_equals(player.playState, 'finished');
}, "pending startTime -> finish()");
test(function() {
var player = pendingStartTimePlayer();
player.reverse();
assert_unresolved(player.startTime);
assert_equals(player.currentTime, 100000);
assert_equals(player.playState, 'pending');
}, "pending startTime -> reverse()");
test(function() {
var player = pendingStartTimePlayer();
player.currentTime = 1000;
assert_unresolved(player.startTime);
assert_equals(player.currentTime, 1000);
assert_equals(player.playState, 'pending');
}, "pending startTime -> set currentTime");
test(function() {
var player = pendingStartTimePlayer();
player.startTime = document.timeline.currentTime - 1000;
assert_equals(player.startTime, document.timeline.currentTime - 1000);
assert_equals(player.currentTime, 1000);
assert_equals(player.playState, 'running');
}, "pending startTime -> set startTime");
test(function() {
var player = pendingStartTimeAndCurrentTimePlayer();
player.play();
assert_unresolved(player.startTime);
assert_unresolved(player.currentTime);
assert_equals(player.playState, 'pending');
}, "pending startTime & currentTime -> play()");
test(function() {
var player = pendingStartTimeAndCurrentTimePlayer();
player.pause();
assert_unresolved(player.startTime);
assert_unresolved(player.currentTime);
assert_equals(player.playState, 'pending');
}, "pending startTime & currentTime -> pause()");
test(function() {
var player = pendingStartTimeAndCurrentTimePlayer();
player.cancel();
assert_unresolved(player.startTime);
assert_unresolved(player.currentTime);
assert_equals(player.playState, 'idle');
}, "pending startTime & currentTime -> cancel()");
test(function() {
var player = pendingStartTimeAndCurrentTimePlayer();
player.finish();
assert_equals(player.startTime, document.timeline.currentTime - player.currentTime);
assert_equals(player.currentTime, 100000);
assert_equals(player.playState, 'finished');
}, "pending startTime & currentTime -> finish()");
test(function() {
var player = pendingStartTimeAndCurrentTimePlayer();
player.reverse();
assert_unresolved(player.startTime);
assert_unresolved(player.currentTime);
assert_equals(player.playState, 'pending');
}, "pending startTime & currentTime -> reverse()");
test(function() {
var player = pendingStartTimeAndCurrentTimePlayer();
player.currentTime = 1000;
assert_unresolved(player.startTime);
assert_equals(player.currentTime, 1000);
assert_equals(player.playState, 'pending');
}, "pending startTime & currentTime -> set currentTime");
test(function() {
var player = pendingStartTimeAndCurrentTimePlayer();
player.startTime = document.timeline.currentTime;
assert_equals(player.startTime, document.timeline.currentTime);
assert_equals(player.currentTime, 0);
assert_equals(player.playState, 'running');
}, "pending startTime & currentTime -> set startTime");
test(function() {
var player = runningPlayer();
var startTime = player.startTime;
var currentTime = player.currentTime;
player.play();
assert_equals(player.startTime, startTime);
assert_equals(player.currentTime, currentTime);
assert_equals(player.playState, 'running');
}, "running -> play()");
test(function() {
var player = runningPlayer();
player.pause();
assert_unresolved(player.startTime);
assert_unresolved(player.currentTime);
assert_equals(player.playState, 'pending');
}, "running -> pause()");
test(function() {
var player = runningPlayer();
player.cancel();
assert_unresolved(player.startTime);
assert_unresolved(player.currentTime);
assert_equals(player.playState, 'idle');
}, "running -> cancel()");
test(function() {
var player = runningPlayer();
player.finish();
assert_equals(player.startTime, document.timeline.currentTime - player.currentTime);
assert_equals(player.currentTime, 100000);
assert_equals(player.playState, 'finished');
}, "running -> finish()");
test(function() {
var player = runningPlayer();
player.reverse();
assert_unresolved(player.startTime);
assert_unresolved(player.currentTime);
assert_equals(player.playState, 'pending');
}, "running -> reverse()");
test(function() {
var player = runningPlayer();
player.currentTime = 1000;
assert_equals(player.startTime, document.timeline.currentTime - player.currentTime);
assert_equals(player.currentTime, 1000);
assert_equals(player.playState, 'running');
}, "running -> set currentTime");
test(function() {
var player = runningPlayer();
player.startTime = document.timeline.currentTime - 1000;
assert_equals(player.startTime, document.timeline.currentTime - 1000);
assert_equals(player.currentTime, 1000);
assert_equals(player.playState, 'running');
}, "running -> set startTime");
test(function() {
var player = pausedPlayer();
player.play();
assert_unresolved(player.startTime);
assert_equals(player.currentTime, 0);
assert_equals(player.playState, 'pending');
}, "paused -> play()");
test(function() {
var player = pausedPlayer();
player.pause();
assert_unresolved(player.startTime);
assert_equals(player.currentTime, 0);
assert_equals(player.playState, 'paused');
}, "paused -> pause()");
test(function() {
var player = pausedPlayer();
player.cancel();
assert_unresolved(player.startTime);
assert_unresolved(player.currentTime);
assert_equals(player.playState, 'idle');
}, "paused -> cancel()");
test(function() {
var player = pausedPlayer();
player.finish();
assert_unresolved(player.startTime);
assert_equals(player.currentTime, 100000);
assert_equals(player.playState, 'paused');
}, "paused -> finish()");
test(function() {
var player = pausedPlayer();
player.reverse();
assert_unresolved(player.startTime);
assert_equals(player.currentTime, 100000);
assert_equals(player.playState, 'pending');
}, "paused -> reverse()");
test(function() {
var player = pausedPlayer();
player.currentTime = 1000;
assert_unresolved(player.startTime);
assert_equals(player.currentTime, 1000);
assert_equals(player.playState, 'paused');
}, "paused -> set currentTime");
test(function() {
var player = pausedPlayer();
player.startTime = 1000;
assert_unresolved(player.startTime);
assert_equals(player.currentTime, 0);
assert_equals(player.playState, 'paused');
}, "paused -> set startTime");
test(function() {
var player = finishedPlayer();
player.play();
assert_unresolved(player.startTime);
assert_equals(player.currentTime, 0);
assert_equals(player.playState, 'pending');
}, "finished -> play()");
test(function() {
var player = finishedPlayer();
player.pause();
assert_unresolved(player.startTime);
assert_equals(player.currentTime, 100000);
assert_equals(player.playState, 'paused');
}, "finished -> pause()");
test(function() {
var player = finishedPlayer();
player.cancel();
assert_unresolved(player.startTime);
assert_unresolved(player.currentTime);
assert_equals(player.playState, 'idle');
}, "finished -> cancel()");
test(function() {
var player = finishedPlayer();
player.finish();
assert_equals(player.startTime, document.timeline.currentTime - player.currentTime);
assert_equals(player.currentTime, 100000);
assert_equals(player.playState, 'finished');
}, "finished -> finish()");
test(function() {
var player = finishedPlayer();
player.reverse();
assert_unresolved(player.startTime);
assert_equals(player.currentTime, 100000);
assert_equals(player.playState, 'pending');
}, "finished -> reverse()");
test(function() {
var player = finishedPlayer();
player.currentTime = 1000;
assert_equals(player.startTime, document.timeline.currentTime - player.currentTime);
assert_equals(player.currentTime, 1000);
assert_equals(player.playState, 'running');
}, "finished -> set currentTime");
</script>
......@@ -307,19 +307,13 @@ void AnimationPlayer::setCurrentTime(double newCurrentTime)
return;
setCompositorPending();
// Setting current time while pending forces a start time.
if (m_currentTimePending) {
m_startTime = 0;
m_currentTimePending = false;
}
m_currentTimePending = false;
setCurrentTimeInternal(newCurrentTime / 1000, TimingUpdateOnDemand);
}
void AnimationPlayer::setStartTime(double startTime)
{
if (m_paused) // FIXME: Should this throw an exception?
if (m_paused || m_idle)
return;
if (!std::isfinite(startTime))
return;
......@@ -472,23 +466,13 @@ void AnimationPlayer::reverse()
}
uncancel();
if (m_content) {
if (m_playbackRate > 0 && currentTimeInternal() > sourceEnd()) {
setCurrentTimeInternal(sourceEnd(), TimingUpdateOnDemand);
ASSERT(finished());
} else if (m_playbackRate < 0 && currentTimeInternal() < 0) {
setCurrentTimeInternal(0, TimingUpdateOnDemand);
ASSERT(finished());
}
}
setPlaybackRate(-m_playbackRate);
unpauseInternal();
play();
}
void AnimationPlayer::finish(ExceptionState& exceptionState)
{
if (!m_playbackRate) {
if (!m_playbackRate || m_idle) {
return;
}
if (m_playbackRate > 0 && sourceEnd() == std::numeric_limits<double>::infinity()) {
......@@ -500,13 +484,14 @@ void AnimationPlayer::finish(ExceptionState& exceptionState)
}
uncancel();
m_startTime = 0;
if (m_playbackRate < 0) {
setCurrentTimeInternal(0, TimingUpdateOnDemand);
} else {
setCurrentTimeInternal(sourceEnd(), TimingUpdateOnDemand);
double newCurrentTime = m_playbackRate < 0 ? 0 : sourceEnd();
setCurrentTimeInternal(newCurrentTime, TimingUpdateOnDemand);
if (!paused()) {
m_startTime = calculateStartTime(newCurrentTime);
}
m_currentTimePending = false;
ASSERT(finished());
}
......@@ -546,7 +531,7 @@ void AnimationPlayer::setPlaybackRate(double playbackRate)
return;
setCompositorPending();
if (!finished() && !paused())
if (!finished() && !paused() && hasStartTime())
m_currentTimePending = true;
double storedCurrentTime = currentTimeInternal();
......@@ -663,6 +648,7 @@ void AnimationPlayer::cancel()
m_held = true;
m_idle = true;
m_startTime = nullValue();
m_currentTimePending = false;
setCompositorPending();
}
......
......@@ -284,7 +284,7 @@ TEST_F(AnimationAnimationPlayerTest, StartTimePauseFinish)
EXPECT_EQ(AnimationPlayer::Pending, player->playStateInternal());
EXPECT_TRUE(std::isnan(player->startTime()));
player->finish(exceptionState);
EXPECT_EQ(AnimationPlayer::Pending, player->playStateInternal());
EXPECT_EQ(AnimationPlayer::Paused, player->playStateInternal());
EXPECT_TRUE(std::isnan(player->startTime()));
}
......@@ -300,9 +300,8 @@ TEST_F(AnimationAnimationPlayerTest, PauseBeatsFinish)
TEST_F(AnimationAnimationPlayerTest, StartTimeFinishPause)
{
double startTime = player->startTime();
player->finish(exceptionState);
EXPECT_EQ(startTime, player->startTime());
EXPECT_EQ(-30 * 1000, player->startTime());
player->pause();
EXPECT_TRUE(std::isnan(player->startTime()));
}
......@@ -461,18 +460,18 @@ TEST_F(AnimationAnimationPlayerTest, ReverseSeeksToEnd)
EXPECT_EQ(30, player->currentTimeInternal());
}
TEST_F(AnimationAnimationPlayerTest, ReverseLimitsAnimationPlayer)
TEST_F(AnimationAnimationPlayerTest, ReverseBeyondLimit)
{
player->setCurrentTimeInternal(40);
player->setPlaybackRate(-1);
player->reverse();
EXPECT_TRUE(player->finished());
EXPECT_EQ(40, player->currentTimeInternal());
EXPECT_EQ(AnimationPlayer::Pending, player->playStateInternal());
EXPECT_EQ(0, player->currentTimeInternal());
player->setCurrentTimeInternal(-10);
player->reverse();
EXPECT_TRUE(player->finished());
EXPECT_EQ(-10, player->currentTimeInternal());
EXPECT_EQ(AnimationPlayer::Pending, player->playStateInternal());
EXPECT_EQ(30, player->currentTimeInternal());
}
......@@ -849,8 +848,6 @@ TEST_F(AnimationAnimationPlayerTest, PlayBackwardsAfterCancel)
EXPECT_EQ(40 * 1000, player->startTime());
}
// FIXME: crbug.com/410229, when fixed, will reuqire the expected results of
// this test to change (currentTime -> 30 * 1000).
TEST_F(AnimationAnimationPlayerTest, ReverseAfterCancel)
{
player->cancel();
......@@ -859,12 +856,12 @@ TEST_F(AnimationAnimationPlayerTest, ReverseAfterCancel)
EXPECT_TRUE(std::isnan(player->startTime()));
player->reverse();
EXPECT_EQ(AnimationPlayer::Pending, player->playStateInternal());
EXPECT_TRUE(std::isnan(player->currentTime()));
EXPECT_EQ(30 * 1000, player->currentTime());
EXPECT_TRUE(std::isnan(player->startTime()));
simulateFrame(10);
EXPECT_EQ(AnimationPlayer::Finished, player->playStateInternal());
EXPECT_EQ(0 * 1000, player->currentTime());
EXPECT_EQ(10 * 1000, player->startTime());
EXPECT_EQ(AnimationPlayer::Running, player->playStateInternal());
EXPECT_EQ(30 * 1000, player->currentTime());
EXPECT_EQ(40 * 1000, player->startTime());
}
TEST_F(AnimationAnimationPlayerTest, FinishAfterCancel)
......@@ -874,9 +871,9 @@ TEST_F(AnimationAnimationPlayerTest, FinishAfterCancel)
EXPECT_TRUE(std::isnan(player->currentTime()));
EXPECT_TRUE(std::isnan(player->startTime()));
player->finish(exceptionState);
EXPECT_EQ(AnimationPlayer::Finished, player->playStateInternal());
EXPECT_EQ(30 * 1000, player->currentTime());
EXPECT_EQ(0, player->startTime());
EXPECT_TRUE(std::isnan(player->currentTime()));
EXPECT_TRUE(std::isnan(player->startTime()));
EXPECT_EQ(AnimationPlayer::Idle, player->playStateInternal());
}
TEST_F(AnimationAnimationPlayerTest, PauseAfterCancel)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment