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