1// Copyright 2013 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 "cc/animation/scroll_offset_animation_curve.h"
6
7#include "cc/animation/timing_function.h"
8#include "cc/test/geometry_test_utils.h"
9#include "testing/gtest/include/gtest/gtest.h"
10
11namespace cc {
12namespace {
13
14TEST(ScrollOffsetAnimationCurveTest, Duration) {
15  gfx::Vector2dF target_value(100.f, 200.f);
16  scoped_ptr<ScrollOffsetAnimationCurve> curve(
17      ScrollOffsetAnimationCurve::Create(
18          target_value,
19          EaseInOutTimingFunction::Create().Pass()));
20
21  curve->SetInitialValue(target_value);
22  EXPECT_DOUBLE_EQ(0.0, curve->Duration());
23
24  // x decreases, y stays the same.
25  curve->SetInitialValue(gfx::Vector2dF(136.f, 200.f));
26  EXPECT_DOUBLE_EQ(0.1, curve->Duration());
27
28  // x increases, y stays the same.
29  curve->SetInitialValue(gfx::Vector2dF(19.f, 200.f));
30  EXPECT_DOUBLE_EQ(0.15, curve->Duration());
31
32  // x stays the same, y decreases.
33  curve->SetInitialValue(gfx::Vector2dF(100.f, 344.f));
34  EXPECT_DOUBLE_EQ(0.2, curve->Duration());
35
36  // x stays the same, y increases.
37  curve->SetInitialValue(gfx::Vector2dF(100.f, 191.f));
38  EXPECT_DOUBLE_EQ(0.05, curve->Duration());
39
40  // x decreases, y decreases.
41  curve->SetInitialValue(gfx::Vector2dF(32500.f, 500.f));
42  EXPECT_DOUBLE_EQ(3.0, curve->Duration());
43
44  // x decreases, y increases.
45  curve->SetInitialValue(gfx::Vector2dF(150.f, 119.f));
46  EXPECT_DOUBLE_EQ(0.15, curve->Duration());
47
48  // x increases, y decreases.
49  curve->SetInitialValue(gfx::Vector2dF(0.f, 14600.f));
50  EXPECT_DOUBLE_EQ(2.0, curve->Duration());
51
52  // x increases, y increases.
53  curve->SetInitialValue(gfx::Vector2dF(95.f, 191.f));
54  EXPECT_DOUBLE_EQ(0.05, curve->Duration());
55}
56
57TEST(ScrollOffsetAnimationCurveTest, GetValue) {
58  gfx::Vector2dF initial_value(2.f, 40.f);
59  gfx::Vector2dF target_value(10.f, 20.f);
60  scoped_ptr<ScrollOffsetAnimationCurve> curve(
61      ScrollOffsetAnimationCurve::Create(
62          target_value,
63          EaseInOutTimingFunction::Create().Pass()));
64  curve->SetInitialValue(initial_value);
65
66  double duration = curve->Duration();
67  EXPECT_GT(curve->Duration(), 0);
68  EXPECT_LT(curve->Duration(), 0.1);
69
70  EXPECT_EQ(AnimationCurve::ScrollOffset, curve->Type());
71  EXPECT_EQ(duration, curve->Duration());
72
73  EXPECT_VECTOR2DF_EQ(initial_value, curve->GetValue(-1.0));
74  EXPECT_VECTOR2DF_EQ(initial_value, curve->GetValue(0.0));
75  EXPECT_VECTOR2DF_EQ(gfx::Vector2dF(6.f, 30.f), curve->GetValue(duration/2.0));
76  EXPECT_VECTOR2DF_EQ(target_value, curve->GetValue(duration));
77  EXPECT_VECTOR2DF_EQ(target_value, curve->GetValue(duration+1.0));
78
79  // Verify that GetValue takes the timing function into account.
80  gfx::Vector2dF value = curve->GetValue(duration/4.0);
81  EXPECT_NEAR(3.0333f, value.x(), 0.00015f);
82  EXPECT_NEAR(37.4168f, value.y(), 0.00015f);
83}
84
85// Verify that a clone behaves exactly like the original.
86TEST(ScrollOffsetAnimationCurveTest, Clone) {
87  gfx::Vector2dF initial_value(2.f, 40.f);
88  gfx::Vector2dF target_value(10.f, 20.f);
89  scoped_ptr<ScrollOffsetAnimationCurve> curve(
90      ScrollOffsetAnimationCurve::Create(
91          target_value,
92          EaseInOutTimingFunction::Create().Pass()));
93  curve->SetInitialValue(initial_value);
94  double duration = curve->Duration();
95
96  scoped_ptr<AnimationCurve> clone(curve->Clone().Pass());
97
98  EXPECT_EQ(AnimationCurve::ScrollOffset, clone->Type());
99  EXPECT_EQ(duration, clone->Duration());
100
101  EXPECT_VECTOR2DF_EQ(initial_value,
102                      clone->ToScrollOffsetAnimationCurve()->GetValue(-1.0));
103  EXPECT_VECTOR2DF_EQ(initial_value,
104                      clone->ToScrollOffsetAnimationCurve()->GetValue(0.0));
105  EXPECT_VECTOR2DF_EQ(
106      gfx::Vector2dF(6.f, 30.f),
107      clone->ToScrollOffsetAnimationCurve()->GetValue(duration / 2.0));
108  EXPECT_VECTOR2DF_EQ(
109      target_value,
110      clone->ToScrollOffsetAnimationCurve()->GetValue(duration));
111  EXPECT_VECTOR2DF_EQ(
112      target_value,
113      clone->ToScrollOffsetAnimationCurve()->GetValue(duration + 1.0));
114
115  // Verify that the timing function was cloned correctly.
116  gfx::Vector2dF value =
117      clone->ToScrollOffsetAnimationCurve()->GetValue(duration / 4.0);
118  EXPECT_NEAR(3.0333f, value.x(), 0.00015f);
119  EXPECT_NEAR(37.4168f, value.y(), 0.00015f);
120}
121
122TEST(ScrollOffsetAnimationCurveTest, UpdateTarget) {
123  gfx::Vector2dF initial_value(0.f, 0.f);
124  gfx::Vector2dF target_value(0.f, 3600.f);
125  scoped_ptr<ScrollOffsetAnimationCurve> curve(
126      ScrollOffsetAnimationCurve::Create(
127          target_value, EaseInOutTimingFunction::Create().Pass()));
128  curve->SetInitialValue(initial_value);
129  EXPECT_EQ(1.0, curve->Duration());
130  EXPECT_EQ(1800.0, curve->GetValue(0.5).y());
131  EXPECT_EQ(3600.0, curve->GetValue(1.0).y());
132
133  curve->UpdateTarget(0.5, gfx::Vector2dF(0.0, 9900.0));
134
135  EXPECT_EQ(2.0, curve->Duration());
136  EXPECT_EQ(1800.0, curve->GetValue(0.5).y());
137  EXPECT_NEAR(5566.49, curve->GetValue(1.0).y(), 0.01);
138  EXPECT_EQ(9900.0, curve->GetValue(2.0).y());
139
140  curve->UpdateTarget(1.0, gfx::Vector2dF(0.0, 7200.0));
141
142  EXPECT_NEAR(1.674, curve->Duration(), 0.01);
143  EXPECT_NEAR(5566.49, curve->GetValue(1.0).y(), 0.01);
144  EXPECT_EQ(7200.0, curve->GetValue(1.674).y());
145}
146
147}  // namespace
148}  // namespace cc
149