| 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..b5d708fb39ac7b2a807f57719d7a91fd0e7c87dd
|
| --- /dev/null
|
| +++ b/ui/compositor/callback_layer_animation_observer_unittest.cc
|
| @@ -0,0 +1,522 @@
|
| +// 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();
|
| + virtual ~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_; }
|
| +
|
| + virtual void AnimationsStarted(const CallbackLayerAnimationObserver&);
|
| +
|
| + virtual 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() {}
|
| +
|
| +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 child of TestCallbacks that can explicitly delete a
|
| +// CallbackLayerAnimationObserver in the AnimationsStarted() or
|
| +// AnimationsEnded() callback.
|
| +class TestCallbacksThatExplicitlyDeletesObserver : public TestCallbacks {
|
| + public:
|
| + TestCallbacksThatExplicitlyDeletesObserver();
|
| +
|
| + void set_observer_to_delete_in_animation_started(
|
| + CallbackLayerAnimationObserver* observer) {
|
| + observer_to_delete_in_animation_started_ = observer;
|
| + }
|
| +
|
| + void set_observer_to_delete_in_animation_ended(
|
| + CallbackLayerAnimationObserver* observer) {
|
| + observer_to_delete_in_animation_ended_ = observer;
|
| + }
|
| +
|
| + // TestCallbacks:
|
| + void AnimationsStarted(
|
| + const CallbackLayerAnimationObserver& observer) override;
|
| + bool AnimationsEnded(const CallbackLayerAnimationObserver& observer) override;
|
| +
|
| + private:
|
| + // The observer to delete, if non-NULL, in AnimationsStarted().
|
| + CallbackLayerAnimationObserver* observer_to_delete_in_animation_started_ =
|
| + nullptr;
|
| +
|
| + // The observer to delete, if non-NULL, in AnimationsEnded().
|
| + CallbackLayerAnimationObserver* observer_to_delete_in_animation_ended_ =
|
| + nullptr;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(TestCallbacksThatExplicitlyDeletesObserver);
|
| +};
|
| +
|
| +TestCallbacksThatExplicitlyDeletesObserver::
|
| + TestCallbacksThatExplicitlyDeletesObserver() {}
|
| +
|
| +void TestCallbacksThatExplicitlyDeletesObserver::AnimationsStarted(
|
| + const CallbackLayerAnimationObserver& observer) {
|
| + if (observer_to_delete_in_animation_started_)
|
| + delete observer_to_delete_in_animation_started_;
|
| + TestCallbacks::AnimationsStarted(observer);
|
| +}
|
| +
|
| +bool TestCallbacksThatExplicitlyDeletesObserver::AnimationsEnded(
|
| + const CallbackLayerAnimationObserver& observer) {
|
| + if (observer_to_delete_in_animation_ended_)
|
| + delete observer_to_delete_in_animation_ended_;
|
| + return TestCallbacks::AnimationsEnded(observer);
|
| +}
|
| +
|
| +// 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_|.
|
| + observer_.reset();
|
| +}
|
| +
|
| +LayerAnimationSequence*
|
| +CallbackLayerAnimationObserverTest::CreateLayerAnimationSequence() {
|
| + LayerAnimationSequence* sequence = new LayerAnimationSequence();
|
| + sequences_.push_back(sequence);
|
| + return sequence;
|
| +}
|
| +
|
| +TEST_F(CallbackLayerAnimationObserverTest, VerifyInitialState) {
|
| + EXPECT_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(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);
|
| +}
|
| +
|
| +// Verifies that the CallbackLayerAnimationObserver is robust to explicit
|
| +// deletes caused as a side effect of calling the AnimationsStartedCallback()
|
| +// when there are no animation sequences attached. This test also guards against
|
| +// heap-use-after-free errors.
|
| +TEST_F(
|
| + CallbackLayerAnimationObserverTest,
|
| + ExplicitlyDeleteObserverInAnimationStartedCallbackWithNoSequencesAttached) {
|
| + TestCallbacksThatExplicitlyDeletesObserver 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);
|
| +
|
| + callbacks.set_observer_to_delete_in_animation_started(observer);
|
| +
|
| + observer->SetActive();
|
| +
|
| + EXPECT_TRUE(is_destroyed);
|
| +}
|
| +
|
| +// Verifies that the CallbackLayerAnimationObserver is robust to explicit
|
| +// deletes caused as a side effect of calling the AnimationsStartedCallback()
|
| +// when there are some animation sequences attached. This test also guards
|
| +// against heap-use-after-free errors.
|
| +TEST_F(
|
| + CallbackLayerAnimationObserverTest,
|
| + ExplicitlyDeleteObserverInAnimationStartedCallbackWithSomeSequencesAttached) {
|
| + LayerAnimationSequence* sequence_1 = CreateLayerAnimationSequence();
|
| + LayerAnimationSequence* sequence_2 = CreateLayerAnimationSequence();
|
| +
|
| + TestCallbacksThatExplicitlyDeletesObserver 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_test_api_->AttachedToSequence(sequence_1);
|
| + observer_test_api_->AttachedToSequence(sequence_2);
|
| + observer_->OnLayerAnimationStarted(sequence_1);
|
| + observer_->OnLayerAnimationStarted(sequence_2);
|
| +
|
| + callbacks.set_observer_to_delete_in_animation_started(observer);
|
| +
|
| + observer->SetActive();
|
| +
|
| + EXPECT_TRUE(is_destroyed);
|
| +}
|
| +
|
| +// Verifies that a 'true' return value for AnimationEndedCallback is ignored if
|
| +// the CallbackLayerAnimationObserver is explicitly deleted as a side effect of
|
| +// calling the AnimationEndedCallback. This test also guards against
|
| +// heap-use-after-free errors.
|
| +TEST_F(CallbackLayerAnimationObserverTest,
|
| + IgnoreTrueReturnValueForAnimationEndedCallbackIfExplicitlyDeleted) {
|
| + TestCallbacksThatExplicitlyDeletesObserver 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);
|
| +
|
| + callbacks.set_observer_to_delete_in_animation_ended(observer);
|
| +
|
| + observer->SetActive();
|
| +
|
| + EXPECT_TRUE(is_destroyed);
|
| +}
|
| +
|
| +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
|
|
|