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 "testing/gtest/include/gtest/gtest.h"
6#include "ui/base/animation/animation_delegate.h"
7#include "ui/base/animation/linear_animation.h"
8#include "ui/base/animation/test_animation_delegate.h"
9
10#if defined(OS_WIN)
11#include "base/win/windows_version.h"
12#endif
13
14namespace ui {
15
16class AnimationTest: public testing::Test {
17 private:
18  base::MessageLoopForUI message_loop_;
19};
20
21namespace {
22
23///////////////////////////////////////////////////////////////////////////////
24// RunAnimation
25
26class RunAnimation : public LinearAnimation {
27 public:
28  RunAnimation(int frame_rate, AnimationDelegate* delegate)
29      : LinearAnimation(frame_rate, delegate) {
30  }
31
32  virtual void AnimateToState(double state) OVERRIDE {
33    EXPECT_LE(0.0, state);
34    EXPECT_GE(1.0, state);
35  }
36};
37
38///////////////////////////////////////////////////////////////////////////////
39// CancelAnimation
40
41class CancelAnimation : public LinearAnimation {
42 public:
43  CancelAnimation(int duration, int frame_rate, AnimationDelegate* delegate)
44      : LinearAnimation(duration, frame_rate, delegate) {
45  }
46
47  virtual void AnimateToState(double state) OVERRIDE {
48    if (state >= 0.5)
49      Stop();
50  }
51};
52
53///////////////////////////////////////////////////////////////////////////////
54// EndAnimation
55
56class EndAnimation : public LinearAnimation {
57 public:
58  EndAnimation(int duration, int frame_rate, AnimationDelegate* delegate)
59      : LinearAnimation(duration, frame_rate, delegate) {
60  }
61
62  virtual void AnimateToState(double state) OVERRIDE {
63    if (state >= 0.5)
64      End();
65  }
66};
67
68///////////////////////////////////////////////////////////////////////////////
69// DeletingAnimationDelegate
70
71// AnimationDelegate implementation that deletes the animation in ended.
72class DeletingAnimationDelegate : public AnimationDelegate {
73 public:
74  virtual void AnimationEnded(const Animation* animation) OVERRIDE {
75    delete animation;
76    base::MessageLoop::current()->Quit();
77  }
78};
79
80}  // namespace
81
82///////////////////////////////////////////////////////////////////////////////
83// LinearCase
84
85TEST_F(AnimationTest, RunCase) {
86  TestAnimationDelegate ad;
87  RunAnimation a1(150, &ad);
88  a1.SetDuration(2000);
89  a1.Start();
90  base::MessageLoop::current()->Run();
91
92  EXPECT_TRUE(ad.finished());
93  EXPECT_FALSE(ad.canceled());
94}
95
96TEST_F(AnimationTest, CancelCase) {
97  TestAnimationDelegate ad;
98  CancelAnimation a2(2000, 150, &ad);
99  a2.Start();
100  base::MessageLoop::current()->Run();
101
102  EXPECT_TRUE(ad.finished());
103  EXPECT_TRUE(ad.canceled());
104}
105
106// Lets an animation run, invoking End part way through and make sure we get the
107// right delegate methods invoked.
108TEST_F(AnimationTest, EndCase) {
109  TestAnimationDelegate ad;
110  EndAnimation a2(2000, 150, &ad);
111  a2.Start();
112  base::MessageLoop::current()->Run();
113
114  EXPECT_TRUE(ad.finished());
115  EXPECT_FALSE(ad.canceled());
116}
117
118// Runs an animation with a delegate that deletes the animation in end.
119TEST_F(AnimationTest, DeleteFromEnd) {
120  DeletingAnimationDelegate delegate;
121  RunAnimation* animation = new RunAnimation(150, &delegate);
122  animation->Start();
123  base::MessageLoop::current()->Run();
124  // delegate should have deleted animation.
125}
126
127TEST_F(AnimationTest, ShouldRenderRichAnimation) {
128#if defined(OS_WIN)
129  if (base::win::GetVersion() >= base::win::VERSION_VISTA) {
130    BOOL result;
131    ASSERT_NE(
132        0, ::SystemParametersInfo(SPI_GETCLIENTAREAANIMATION, 0, &result, 0));
133    // ShouldRenderRichAnimation() should check the SPI_GETCLIENTAREAANIMATION
134    // value on Vista.
135    EXPECT_EQ(!!result, Animation::ShouldRenderRichAnimation());
136  } else {
137    // On XP, the function should check the SM_REMOTESESSION value.
138    EXPECT_EQ(!::GetSystemMetrics(SM_REMOTESESSION),
139              Animation::ShouldRenderRichAnimation());
140  }
141#else
142  EXPECT_TRUE(Animation::ShouldRenderRichAnimation());
143#endif
144}
145
146// Test that current value is always 0 after Start() is called.
147TEST_F(AnimationTest, StartState) {
148  LinearAnimation animation(100, 60, NULL);
149  EXPECT_EQ(0.0, animation.GetCurrentValue());
150  animation.Start();
151  EXPECT_EQ(0.0, animation.GetCurrentValue());
152  animation.End();
153  EXPECT_EQ(1.0, animation.GetCurrentValue());
154  animation.Start();
155  EXPECT_EQ(0.0, animation.GetCurrentValue());
156}
157
158}  // namespace ui
159