// Copyright (c) 2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/logging.h" #include "media/base/clock_impl.h" #include "testing/gmock/include/gmock/gmock.h" using ::testing::DefaultValue; using ::testing::InSequence; using ::testing::Return; using ::testing::StrictMock; namespace { // Provide a stream output operator so we can use EXPECT_EQ(...) with TimeDelta. // // TODO(scherkus): move this into the testing package. std::ostream& operator<<(std::ostream& stream, const base::TimeDelta& time) { return (stream << time.ToInternalValue()); } } // namespace namespace media { class MockTimeProvider { public: MockTimeProvider() { DCHECK(!instance_) << "Only one instance of MockTimeProvider can exist"; DCHECK(!DefaultValue::IsSet()); instance_ = this; DefaultValue::Set(base::Time::FromInternalValue(0)); } ~MockTimeProvider() { instance_ = NULL; DefaultValue::Clear(); } MOCK_METHOD0(Now, base::Time()); static base::Time StaticNow() { return instance_->Now(); } private: static MockTimeProvider* instance_; DISALLOW_COPY_AND_ASSIGN(MockTimeProvider); }; MockTimeProvider* MockTimeProvider::instance_ = NULL; TEST(ClockTest, Created) { StrictMock mock_time; const base::TimeDelta kExpected = base::TimeDelta::FromSeconds(0); ClockImpl clock(&MockTimeProvider::StaticNow); EXPECT_EQ(kExpected, clock.Elapsed()); } TEST(ClockTest, Play_NormalSpeed) { InSequence s; StrictMock mock_time; EXPECT_CALL(mock_time, Now()) .WillOnce(Return(base::Time::FromDoubleT(4))); EXPECT_CALL(mock_time, Now()) .WillOnce(Return(base::Time::FromDoubleT(6))); const base::TimeDelta kZero; const base::TimeDelta kExpected = base::TimeDelta::FromSeconds(2); ClockImpl clock(&MockTimeProvider::StaticNow); EXPECT_EQ(kZero, clock.Play()); EXPECT_EQ(kExpected, clock.Elapsed()); } TEST(ClockTest, Play_DoubleSpeed) { InSequence s; StrictMock mock_time; EXPECT_CALL(mock_time, Now()) .WillOnce(Return(base::Time::FromDoubleT(4))); EXPECT_CALL(mock_time, Now()) .WillOnce(Return(base::Time::FromDoubleT(9))); const base::TimeDelta kZero; const base::TimeDelta kExpected = base::TimeDelta::FromSeconds(10); ClockImpl clock(&MockTimeProvider::StaticNow); clock.SetPlaybackRate(2.0f); EXPECT_EQ(kZero, clock.Play()); EXPECT_EQ(kExpected, clock.Elapsed()); } TEST(ClockTest, Play_HalfSpeed) { InSequence s; StrictMock mock_time; EXPECT_CALL(mock_time, Now()) .WillOnce(Return(base::Time::FromDoubleT(4))); EXPECT_CALL(mock_time, Now()) .WillOnce(Return(base::Time::FromDoubleT(8))); const base::TimeDelta kZero; const base::TimeDelta kExpected = base::TimeDelta::FromSeconds(2); ClockImpl clock(&MockTimeProvider::StaticNow); clock.SetPlaybackRate(0.5f); EXPECT_EQ(kZero, clock.Play()); EXPECT_EQ(kExpected, clock.Elapsed()); } TEST(ClockTest, Play_ZeroSpeed) { // We'll play for 2 seconds at normal speed, 4 seconds at zero speed, and 8 // seconds at normal speed: // (1.0 x 2) + (0.0 x 4) + (1.0 x 8) = 10 InSequence s; StrictMock mock_time; EXPECT_CALL(mock_time, Now()) .WillOnce(Return(base::Time::FromDoubleT(4))); EXPECT_CALL(mock_time, Now()) .WillOnce(Return(base::Time::FromDoubleT(6))); EXPECT_CALL(mock_time, Now()) .WillOnce(Return(base::Time::FromDoubleT(10))); EXPECT_CALL(mock_time, Now()) .WillOnce(Return(base::Time::FromDoubleT(18))); const base::TimeDelta kZero; const base::TimeDelta kExpected = base::TimeDelta::FromSeconds(10); ClockImpl clock(&MockTimeProvider::StaticNow); EXPECT_EQ(kZero, clock.Play()); clock.SetPlaybackRate(0.0f); clock.SetPlaybackRate(1.0f); EXPECT_EQ(kExpected, clock.Elapsed()); } TEST(ClockTest, Play_MultiSpeed) { // We'll play for 2 seconds at half speed, 4 seconds at normal speed, and 8 // seconds at double speed: // (0.5 x 2) + (1.0 x 4) + (2.0 x 8) = 21 InSequence s; StrictMock mock_time; EXPECT_CALL(mock_time, Now()) .WillOnce(Return(base::Time::FromDoubleT(4))); EXPECT_CALL(mock_time, Now()) .WillOnce(Return(base::Time::FromDoubleT(6))); EXPECT_CALL(mock_time, Now()) .WillOnce(Return(base::Time::FromDoubleT(10))); EXPECT_CALL(mock_time, Now()) .WillOnce(Return(base::Time::FromDoubleT(18))); const base::TimeDelta kZero; const base::TimeDelta kExpected = base::TimeDelta::FromSeconds(21); ClockImpl clock(&MockTimeProvider::StaticNow); clock.SetPlaybackRate(0.5f); EXPECT_EQ(kZero, clock.Play()); clock.SetPlaybackRate(1.0f); clock.SetPlaybackRate(2.0f); EXPECT_EQ(kExpected, clock.Elapsed()); } TEST(ClockTest, Pause) { InSequence s; StrictMock mock_time; EXPECT_CALL(mock_time, Now()) .WillOnce(Return(base::Time::FromDoubleT(4))); EXPECT_CALL(mock_time, Now()) .WillOnce(Return(base::Time::FromDoubleT(8))); EXPECT_CALL(mock_time, Now()) .WillOnce(Return(base::Time::FromDoubleT(12))); EXPECT_CALL(mock_time, Now()) .WillOnce(Return(base::Time::FromDoubleT(16))); const base::TimeDelta kZero; const base::TimeDelta kFirstPause = base::TimeDelta::FromSeconds(4); const base::TimeDelta kSecondPause = base::TimeDelta::FromSeconds(8); ClockImpl clock(&MockTimeProvider::StaticNow); EXPECT_EQ(kZero, clock.Play()); EXPECT_EQ(kFirstPause, clock.Pause()); EXPECT_EQ(kFirstPause, clock.Elapsed()); EXPECT_EQ(kFirstPause, clock.Play()); EXPECT_EQ(kSecondPause, clock.Pause()); EXPECT_EQ(kSecondPause, clock.Elapsed()); } TEST(ClockTest, SetTime_Paused) { // We'll remain paused while we set the time. The time should be simply // updated without accessing the time provider. InSequence s; StrictMock mock_time; const base::TimeDelta kFirstTime = base::TimeDelta::FromSeconds(4); const base::TimeDelta kSecondTime = base::TimeDelta::FromSeconds(16); ClockImpl clock(&MockTimeProvider::StaticNow); clock.SetTime(kFirstTime); EXPECT_EQ(kFirstTime, clock.Elapsed()); clock.SetTime(kSecondTime); EXPECT_EQ(kSecondTime, clock.Elapsed()); } TEST(ClockTest, SetTime_Playing) { // We'll play for 4 seconds, then set the time to 12, then play for 4 more // seconds. We'll expect a media time of 16. InSequence s; StrictMock mock_time; EXPECT_CALL(mock_time, Now()) .WillOnce(Return(base::Time::FromDoubleT(4))); EXPECT_CALL(mock_time, Now()) .WillOnce(Return(base::Time::FromDoubleT(8))); EXPECT_CALL(mock_time, Now()) .WillOnce(Return(base::Time::FromDoubleT(12))); const base::TimeDelta kZero; const base::TimeDelta kExepected = base::TimeDelta::FromSeconds(16); ClockImpl clock(&MockTimeProvider::StaticNow); EXPECT_EQ(kZero, clock.Play()); clock.SetTime(base::TimeDelta::FromSeconds(12)); EXPECT_EQ(kExepected, clock.Elapsed()); } } // namespace media