Chromium Code Reviews| Index: ui/compositor/callback_layer_animation_observer_unittest.cc |
| diff --git a/ui/compositor/callback_layer_animation_observer_unittest.cc b/ui/compositor/callback_layer_animation_observer_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..0d82dbb68d78828a3a0467790b74586f703f8966 |
| --- /dev/null |
| +++ b/ui/compositor/callback_layer_animation_observer_unittest.cc |
| @@ -0,0 +1,380 @@ |
| +// Copyright 2015 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 "ui/compositor/callback_layer_animation_observer.h" |
| + |
| +#include "base/bind.h" |
| +#include "base/macros.h" |
| +#include "base/memory/scoped_vector.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| +#include "ui/compositor/layer_animation_sequence.h" |
| +#include "ui/compositor/test/layer_animation_observer_test_api.h" |
| + |
| +namespace ui { |
| +namespace test { |
| + |
| +// Simple class that tracks whether callbacks were invoked and when. |
| +class TestCallbacks { |
| + public: |
| + TestCallbacks(); |
| + |
| + void ResetCallbackObservations(); |
| + |
| + void set_should_delete_observer_on_animations_ended( |
| + bool should_delete_observer_on_animations_ended) { |
| + should_delete_observer_on_animations_ended_ = |
| + should_delete_observer_on_animations_ended; |
| + } |
| + |
| + bool animations_started() const { return animations_started_; } |
| + |
| + bool animations_ended() const { return animations_ended_; } |
| + |
| + void AnimationsStarted(const CallbackLayerAnimationObserver&); |
| + |
| + bool AnimationsEnded(const CallbackLayerAnimationObserver&); |
| + |
| + testing::AssertionResult StartedEpochIsBeforeEndedEpoch(); |
| + |
| + private: |
| + // Monotonic counter that tracks the next time snapshot. |
| + int next_epoch_ = 0; |
| + |
| + // Is true when AnimationsStarted() has been called. |
| + bool animations_started_ = false; |
| + |
| + // Relative time snapshot of when AnimationsStarted() was last called. |
| + int animations_started_epoch_ = -1; |
| + |
| + // Is true when AnimationsEnded() has been called. |
| + bool animations_ended_ = false; |
| + |
| + // Relative time snapshot of when AnimationsEnded() was last called. |
| + int animations_ended_epoch_ = -1; |
| + |
| + // The return value for AnimationsEnded(). |
| + bool should_delete_observer_on_animations_ended_ = false; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(TestCallbacks); |
| +}; |
| + |
| +TestCallbacks::TestCallbacks() {} |
| + |
| +void TestCallbacks::ResetCallbackObservations() { |
| + next_epoch_ = 0; |
| + animations_started_ = false; |
| + animations_started_epoch_ = -1; |
| + animations_ended_ = false; |
| + animations_ended_epoch_ = -1; |
| + should_delete_observer_on_animations_ended_ = false; |
| +} |
| + |
| +void TestCallbacks::AnimationsStarted(const CallbackLayerAnimationObserver&) { |
| + animations_started_ = true; |
| + animations_started_epoch_ = next_epoch_++; |
| +} |
| + |
| +bool TestCallbacks::AnimationsEnded(const CallbackLayerAnimationObserver&) { |
| + animations_ended_ = true; |
| + animations_ended_epoch_ = next_epoch_++; |
| + return should_delete_observer_on_animations_ended_; |
| +} |
| + |
| +testing::AssertionResult TestCallbacks::StartedEpochIsBeforeEndedEpoch() { |
| + if (animations_started_epoch_ < animations_ended_epoch_) { |
| + return testing::AssertionSuccess(); |
| + } else { |
| + return testing::AssertionFailure() |
| + << "The started epoch=" << animations_started_epoch_ |
| + << " is NOT before the ended epoch=" << animations_ended_epoch_; |
| + } |
| +} |
| + |
| +// A test specific CallbackLayerAnimationObserver that will set a bool when |
| +// destroyed. |
| +class TestCallbackLayerAnimationObserver |
| + : public CallbackLayerAnimationObserver { |
| + public: |
| + TestCallbackLayerAnimationObserver( |
| + AnimationStartedCallback animation_started_callback, |
| + AnimationEndedCallback animation_ended_callback, |
| + bool* destroyed); |
| + ~TestCallbackLayerAnimationObserver() override; |
| + |
| + private: |
| + bool* destroyed_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(TestCallbackLayerAnimationObserver); |
| +}; |
| + |
| +TestCallbackLayerAnimationObserver::TestCallbackLayerAnimationObserver( |
| + AnimationStartedCallback animation_started_callback, |
| + AnimationEndedCallback animation_ended_callback, |
| + bool* destroyed) |
| + : CallbackLayerAnimationObserver(animation_started_callback, |
| + animation_ended_callback), |
| + destroyed_(destroyed) { |
| + (*destroyed_) = false; |
| +} |
| + |
| +TestCallbackLayerAnimationObserver::~TestCallbackLayerAnimationObserver() { |
| + (*destroyed_) = true; |
| +} |
| + |
| +class CallbackLayerAnimationObserverTest : public testing::Test { |
| + public: |
| + CallbackLayerAnimationObserverTest(); |
| + ~CallbackLayerAnimationObserverTest() override; |
| + |
| + protected: |
| + // Creates a LayerAnimationSequence. The lifetime of the sequence will be |
| + // managed by this. |
| + LayerAnimationSequence* CreateLayerAnimationSequence(); |
| + |
| + scoped_ptr<TestCallbacks> callbacks_; |
| + |
| + scoped_ptr<CallbackLayerAnimationObserver> observer_; |
| + |
| + scoped_ptr<LayerAnimationObserverTestApi> observer_test_api_; |
| + |
| + // List of managaged sequences created by CreateLayerAnimationSequence() that |
| + // need to be destroyed. |
| + ScopedVector<LayerAnimationSequence> sequences_; |
| + |
| + private: |
| + DISALLOW_COPY_AND_ASSIGN(CallbackLayerAnimationObserverTest); |
| +}; |
| + |
| +CallbackLayerAnimationObserverTest::CallbackLayerAnimationObserverTest() |
| + : callbacks_(new TestCallbacks()), |
| + observer_(new CallbackLayerAnimationObserver( |
| + base::Bind(&TestCallbacks::AnimationsStarted, |
| + base::Unretained(callbacks_.get())), |
| + base::Bind(&TestCallbacks::AnimationsEnded, |
| + base::Unretained(callbacks_.get())))), |
| + observer_test_api_(new LayerAnimationObserverTestApi(observer_.get())) {} |
| + |
| +CallbackLayerAnimationObserverTest::~CallbackLayerAnimationObserverTest() { |
| + observer_test_api_.reset(); |
| + // The |observer_| will detach from all attached sequences upon destruction so |
| + // we need to explicitly delete the |observer_| before the |sequences_| and |
| + // |callbacks_|. |
|
ajuma
2015/10/07 20:14:55
I'm not sure I follow this part. The observer's de
bruthig
2015/10/07 21:37:29
Observers are detached from in LayerAnimationObser
ajuma
2015/10/07 21:50:38
Ah, yes, that's what I was missing. Thanks!
|
| + observer_.reset(); |
| +} |
| + |
| +LayerAnimationSequence* |
| +CallbackLayerAnimationObserverTest::CreateLayerAnimationSequence() { |
| + LayerAnimationSequence* sequence = new LayerAnimationSequence(); |
| + sequences_.push_back(sequence); |
| + return sequence; |
| +} |
| + |
| +TEST(CallbackLayerAnimationObserverDestructionTest, |
| + AnimationEndedReturnsFalse) { |
| + TestCallbacks callbacks; |
| + callbacks.set_should_delete_observer_on_animations_ended(false); |
| + |
| + bool is_destroyed = false; |
| + |
| + TestCallbackLayerAnimationObserver* observer = |
| + new TestCallbackLayerAnimationObserver( |
| + base::Bind(&TestCallbacks::AnimationsStarted, |
| + base::Unretained(&callbacks)), |
| + base::Bind(&TestCallbacks::AnimationsEnded, |
| + base::Unretained(&callbacks)), |
| + &is_destroyed); |
| + observer->SetActive(); |
| + |
| + EXPECT_FALSE(is_destroyed); |
| + delete observer; |
| +} |
| + |
| +TEST(CallbackLayerAnimationObserverDestructionTest, AnimationEndedReturnsTrue) { |
| + TestCallbacks callbacks; |
| + callbacks.set_should_delete_observer_on_animations_ended(true); |
| + |
| + bool is_destroyed = false; |
| + |
| + TestCallbackLayerAnimationObserver* observer = |
| + new TestCallbackLayerAnimationObserver( |
| + base::Bind(&TestCallbacks::AnimationsStarted, |
| + base::Unretained(&callbacks)), |
| + base::Bind(&TestCallbacks::AnimationsEnded, |
| + base::Unretained(&callbacks)), |
| + &is_destroyed); |
| + observer->SetActive(); |
| + |
| + EXPECT_TRUE(is_destroyed); |
| +} |
| + |
| +TEST_F(CallbackLayerAnimationObserverTest, VerifyInitialState) { |
| + EXPECT_EQ(false, observer_->active()); |
| + EXPECT_EQ(0, observer_->aborted_count()); |
| + EXPECT_EQ(0, observer_->successful_count()); |
| + |
| + EXPECT_FALSE(callbacks_->animations_started()); |
| + EXPECT_FALSE(callbacks_->animations_ended()); |
| +} |
| + |
| +TEST_F(CallbackLayerAnimationObserverTest, |
| + SetActiveWhenNoSequencesWereAttached) { |
| + observer_->SetActive(); |
| + |
| + EXPECT_FALSE(observer_->active()); |
| + EXPECT_TRUE(callbacks_->animations_started()); |
| + EXPECT_TRUE(callbacks_->animations_ended()); |
| + EXPECT_TRUE(callbacks_->StartedEpochIsBeforeEndedEpoch()); |
| +} |
| + |
| +TEST_F(CallbackLayerAnimationObserverTest, |
| + SetActiveWhenAllSequencesAreAttachedButNoneWereStarted) { |
| + LayerAnimationSequence* sequence_1 = CreateLayerAnimationSequence(); |
| + LayerAnimationSequence* sequence_2 = CreateLayerAnimationSequence(); |
| + |
| + observer_test_api_->AttachedToSequence(sequence_1); |
| + observer_test_api_->AttachedToSequence(sequence_2); |
| + |
| + observer_->SetActive(); |
| + |
| + EXPECT_TRUE(observer_->active()); |
| + EXPECT_FALSE(callbacks_->animations_started()); |
| + EXPECT_FALSE(callbacks_->animations_ended()); |
| +} |
| + |
| +TEST_F(CallbackLayerAnimationObserverTest, |
| + SetActiveWhenAllSequencesAreAttachedAndOnlySomeWereStarted) { |
| + LayerAnimationSequence* sequence_1 = CreateLayerAnimationSequence(); |
| + LayerAnimationSequence* sequence_2 = CreateLayerAnimationSequence(); |
| + |
| + observer_test_api_->AttachedToSequence(sequence_1); |
| + observer_test_api_->AttachedToSequence(sequence_2); |
| + observer_->OnLayerAnimationStarted(sequence_1); |
| + |
| + observer_->SetActive(); |
| + |
| + EXPECT_TRUE(observer_->active()); |
| + EXPECT_FALSE(callbacks_->animations_started()); |
| + EXPECT_FALSE(callbacks_->animations_ended()); |
| +} |
| + |
| +TEST_F(CallbackLayerAnimationObserverTest, |
| + SetActiveWhenAllSequencesAreAttachedAndOnlySomeWereCompleted) { |
| + LayerAnimationSequence* sequence_1 = CreateLayerAnimationSequence(); |
| + LayerAnimationSequence* sequence_2 = CreateLayerAnimationSequence(); |
| + |
| + observer_test_api_->AttachedToSequence(sequence_1); |
| + observer_test_api_->AttachedToSequence(sequence_2); |
| + observer_->OnLayerAnimationStarted(sequence_1); |
| + observer_->OnLayerAnimationEnded(sequence_1); |
| + |
| + observer_->SetActive(); |
| + |
| + EXPECT_TRUE(observer_->active()); |
| + EXPECT_FALSE(callbacks_->animations_started()); |
| + EXPECT_FALSE(callbacks_->animations_ended()); |
| +} |
| + |
| +TEST_F(CallbackLayerAnimationObserverTest, |
| + SetActiveAfterAllSequencesWereStartedButNoneWereCompleted) { |
| + LayerAnimationSequence* sequence_1 = CreateLayerAnimationSequence(); |
| + LayerAnimationSequence* sequence_2 = CreateLayerAnimationSequence(); |
| + |
| + observer_test_api_->AttachedToSequence(sequence_1); |
| + observer_test_api_->AttachedToSequence(sequence_2); |
| + observer_->OnLayerAnimationStarted(sequence_1); |
| + observer_->OnLayerAnimationStarted(sequence_2); |
| + |
| + observer_->SetActive(); |
| + |
| + EXPECT_TRUE(observer_->active()); |
| + EXPECT_TRUE(callbacks_->animations_started()); |
| + EXPECT_FALSE(callbacks_->animations_ended()); |
| +} |
| + |
| +TEST_F(CallbackLayerAnimationObserverTest, |
| + SetActiveWhenAllSequencesAreStartedAndOnlySomeWereCompleted) { |
| + LayerAnimationSequence* sequence_1 = CreateLayerAnimationSequence(); |
| + LayerAnimationSequence* sequence_2 = CreateLayerAnimationSequence(); |
| + |
| + observer_test_api_->AttachedToSequence(sequence_1); |
| + observer_test_api_->AttachedToSequence(sequence_2); |
| + observer_->OnLayerAnimationStarted(sequence_1); |
| + observer_->OnLayerAnimationStarted(sequence_2); |
| + observer_->OnLayerAnimationEnded(sequence_1); |
| + |
| + observer_->SetActive(); |
| + |
| + EXPECT_TRUE(observer_->active()); |
| + EXPECT_TRUE(callbacks_->animations_started()); |
| + EXPECT_FALSE(callbacks_->animations_ended()); |
| +} |
| + |
| +TEST_F(CallbackLayerAnimationObserverTest, |
| + SetActiveWhenAllSequencesWereCompleted) { |
| + LayerAnimationSequence* sequence_1 = CreateLayerAnimationSequence(); |
| + LayerAnimationSequence* sequence_2 = CreateLayerAnimationSequence(); |
| + |
| + observer_test_api_->AttachedToSequence(sequence_1); |
| + observer_test_api_->AttachedToSequence(sequence_2); |
| + observer_->OnLayerAnimationStarted(sequence_1); |
| + observer_->OnLayerAnimationStarted(sequence_2); |
| + observer_->OnLayerAnimationEnded(sequence_1); |
| + observer_->OnLayerAnimationEnded(sequence_2); |
| + |
| + observer_->SetActive(); |
| + |
| + EXPECT_FALSE(observer_->active()); |
| + EXPECT_TRUE(callbacks_->animations_started()); |
| + EXPECT_TRUE(callbacks_->animations_ended()); |
| +} |
| + |
| +TEST_F(CallbackLayerAnimationObserverTest, |
| + SetActiveAgainAfterAllSequencesWereCompleted) { |
| + LayerAnimationSequence* sequence_1 = CreateLayerAnimationSequence(); |
| + LayerAnimationSequence* sequence_2 = CreateLayerAnimationSequence(); |
| + LayerAnimationSequence* sequence_3 = CreateLayerAnimationSequence(); |
| + LayerAnimationSequence* sequence_4 = CreateLayerAnimationSequence(); |
| + |
| + observer_test_api_->AttachedToSequence(sequence_1); |
| + observer_test_api_->AttachedToSequence(sequence_2); |
| + observer_->OnLayerAnimationStarted(sequence_1); |
| + observer_->OnLayerAnimationStarted(sequence_2); |
| + observer_->OnLayerAnimationEnded(sequence_1); |
| + observer_->OnLayerAnimationEnded(sequence_2); |
| + |
| + observer_->SetActive(); |
| + |
| + EXPECT_FALSE(observer_->active()); |
| + |
| + observer_test_api_->AttachedToSequence(sequence_3); |
| + observer_test_api_->AttachedToSequence(sequence_4); |
| + |
| + callbacks_->ResetCallbackObservations(); |
| + |
| + observer_->SetActive(); |
| + |
| + EXPECT_TRUE(observer_->active()); |
| + EXPECT_FALSE(callbacks_->animations_started()); |
| + EXPECT_FALSE(callbacks_->animations_ended()); |
| + EXPECT_EQ(2, observer_->successful_count()); |
| + |
| + observer_->OnLayerAnimationStarted(sequence_3); |
| + observer_->OnLayerAnimationStarted(sequence_4); |
| + |
| + EXPECT_TRUE(observer_->active()); |
| + EXPECT_TRUE(callbacks_->animations_started()); |
| + EXPECT_FALSE(callbacks_->animations_ended()); |
| + EXPECT_EQ(2, observer_->successful_count()); |
| + |
| + observer_->OnLayerAnimationEnded(sequence_3); |
| + observer_->OnLayerAnimationEnded(sequence_4); |
| + |
| + EXPECT_FALSE(observer_->active()); |
| + EXPECT_TRUE(callbacks_->animations_started()); |
| + EXPECT_TRUE(callbacks_->animations_ended()); |
| + EXPECT_EQ(4, observer_->successful_count()); |
| +} |
| + |
| +} // namespace test |
| +} // namespace ui |