1// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "ui/gfx/animation/animation_container.h" 6 7#include "base/memory/scoped_ptr.h" 8#include "testing/gtest/include/gtest/gtest.h" 9#include "ui/gfx/animation/animation_container_observer.h" 10#include "ui/gfx/animation/linear_animation.h" 11#include "ui/gfx/animation/test_animation_delegate.h" 12 13namespace gfx { 14 15namespace { 16 17class FakeAnimationContainerObserver : public AnimationContainerObserver { 18 public: 19 FakeAnimationContainerObserver() 20 : progressed_count_(0), 21 empty_(false) { 22 } 23 24 int progressed_count() const { return progressed_count_; } 25 bool empty() const { return empty_; } 26 27 private: 28 virtual void AnimationContainerProgressed( 29 AnimationContainer* container) OVERRIDE { 30 progressed_count_++; 31 } 32 33 // Invoked when no more animations are being managed by this container. 34 virtual void AnimationContainerEmpty(AnimationContainer* container) OVERRIDE { 35 empty_ = true; 36 } 37 38 int progressed_count_; 39 bool empty_; 40 41 DISALLOW_COPY_AND_ASSIGN(FakeAnimationContainerObserver); 42}; 43 44class TestAnimation : public LinearAnimation { 45 public: 46 explicit TestAnimation(AnimationDelegate* delegate) 47 : LinearAnimation(20, 20, delegate) { 48 } 49 50 virtual void AnimateToState(double state) OVERRIDE { 51 } 52 53 private: 54 DISALLOW_COPY_AND_ASSIGN(TestAnimation); 55}; 56 57} // namespace 58 59class AnimationContainerTest: public testing::Test { 60 private: 61 base::MessageLoopForUI message_loop_; 62}; 63 64// Makes sure the animation ups the ref count of the container and releases it 65// appropriately. 66TEST_F(AnimationContainerTest, Ownership) { 67 TestAnimationDelegate delegate; 68 scoped_refptr<AnimationContainer> container(new AnimationContainer()); 69 scoped_ptr<Animation> animation(new TestAnimation(&delegate)); 70 animation->SetContainer(container.get()); 71 // Setting the container should up the ref count. 72 EXPECT_FALSE(container->HasOneRef()); 73 74 animation.reset(); 75 76 // Releasing the animation should decrement the ref count. 77 EXPECT_TRUE(container->HasOneRef()); 78} 79 80// Makes sure multiple animations are managed correctly. 81TEST_F(AnimationContainerTest, Multi) { 82 TestAnimationDelegate delegate1; 83 TestAnimationDelegate delegate2; 84 85 scoped_refptr<AnimationContainer> container(new AnimationContainer()); 86 TestAnimation animation1(&delegate1); 87 TestAnimation animation2(&delegate2); 88 animation1.SetContainer(container.get()); 89 animation2.SetContainer(container.get()); 90 91 // Start both animations. 92 animation1.Start(); 93 EXPECT_TRUE(container->is_running()); 94 animation2.Start(); 95 EXPECT_TRUE(container->is_running()); 96 97 // Run the message loop the delegate quits the message loop when notified. 98 base::MessageLoop::current()->Run(); 99 100 // Both timers should have finished. 101 EXPECT_TRUE(delegate1.finished()); 102 EXPECT_TRUE(delegate2.finished()); 103 104 // And the container should no longer be runnings. 105 EXPECT_FALSE(container->is_running()); 106} 107 108// Makes sure observer is notified appropriately. 109TEST_F(AnimationContainerTest, Observer) { 110 FakeAnimationContainerObserver observer; 111 TestAnimationDelegate delegate1; 112 113 scoped_refptr<AnimationContainer> container(new AnimationContainer()); 114 container->set_observer(&observer); 115 TestAnimation animation1(&delegate1); 116 animation1.SetContainer(container.get()); 117 118 // Start the animation. 119 animation1.Start(); 120 EXPECT_TRUE(container->is_running()); 121 122 // Run the message loop. The delegate quits the message loop when notified. 123 base::MessageLoop::current()->Run(); 124 125 EXPECT_EQ(1, observer.progressed_count()); 126 127 // The timer should have finished. 128 EXPECT_TRUE(delegate1.finished()); 129 130 EXPECT_TRUE(observer.empty()); 131 132 // And the container should no longer be running. 133 EXPECT_FALSE(container->is_running()); 134 135 container->set_observer(NULL); 136} 137 138} // namespace gfx 139