summaryrefslogtreecommitdiff
path: root/chromium/cc/animation/keyframed_animation_curve_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/cc/animation/keyframed_animation_curve_unittest.cc')
-rw-r--r--chromium/cc/animation/keyframed_animation_curve_unittest.cc336
1 files changed, 336 insertions, 0 deletions
diff --git a/chromium/cc/animation/keyframed_animation_curve_unittest.cc b/chromium/cc/animation/keyframed_animation_curve_unittest.cc
new file mode 100644
index 00000000000..32efc147636
--- /dev/null
+++ b/chromium/cc/animation/keyframed_animation_curve_unittest.cc
@@ -0,0 +1,336 @@
+// Copyright 2012 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 "cc/animation/keyframed_animation_curve.h"
+
+#include "cc/animation/transform_operations.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cc {
+namespace {
+
+void ExpectTranslateX(double translate_x, const gfx::Transform& transform) {
+ EXPECT_FLOAT_EQ(translate_x, transform.matrix().getDouble(0, 3));
+}
+
+void ExpectBrightness(double brightness, const FilterOperations& filter) {
+ EXPECT_EQ(1u, filter.size());
+ EXPECT_EQ(FilterOperation::BRIGHTNESS, filter.at(0).type());
+ EXPECT_FLOAT_EQ(brightness, filter.at(0).amount());
+}
+
+// Tests that a float animation with one keyframe works as expected.
+TEST(KeyframedAnimationCurveTest, OneFloatKeyframe) {
+ scoped_ptr<KeyframedFloatAnimationCurve> curve(
+ KeyframedFloatAnimationCurve::Create());
+ curve->AddKeyframe(
+ FloatKeyframe::Create(0.0, 2.f, scoped_ptr<TimingFunction>()));
+ EXPECT_FLOAT_EQ(2.f, curve->GetValue(-1.f));
+ EXPECT_FLOAT_EQ(2.f, curve->GetValue(0.f));
+ EXPECT_FLOAT_EQ(2.f, curve->GetValue(0.5f));
+ EXPECT_FLOAT_EQ(2.f, curve->GetValue(1.f));
+ EXPECT_FLOAT_EQ(2.f, curve->GetValue(2.f));
+}
+
+// Tests that a float animation with two keyframes works as expected.
+TEST(KeyframedAnimationCurveTest, TwoFloatKeyframe) {
+ scoped_ptr<KeyframedFloatAnimationCurve> curve(
+ KeyframedFloatAnimationCurve::Create());
+ curve->AddKeyframe(
+ FloatKeyframe::Create(0.0, 2.f, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(
+ FloatKeyframe::Create(1.0, 4.f, scoped_ptr<TimingFunction>()));
+ EXPECT_FLOAT_EQ(2.f, curve->GetValue(-1.f));
+ EXPECT_FLOAT_EQ(2.f, curve->GetValue(0.f));
+ EXPECT_FLOAT_EQ(3.f, curve->GetValue(0.5f));
+ EXPECT_FLOAT_EQ(4.f, curve->GetValue(1.f));
+ EXPECT_FLOAT_EQ(4.f, curve->GetValue(2.f));
+}
+
+// Tests that a float animation with three keyframes works as expected.
+TEST(KeyframedAnimationCurveTest, ThreeFloatKeyframe) {
+ scoped_ptr<KeyframedFloatAnimationCurve> curve(
+ KeyframedFloatAnimationCurve::Create());
+ curve->AddKeyframe(
+ FloatKeyframe::Create(0.0, 2.f, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(
+ FloatKeyframe::Create(1.0, 4.f, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(
+ FloatKeyframe::Create(2.0, 8.f, scoped_ptr<TimingFunction>()));
+ EXPECT_FLOAT_EQ(2.f, curve->GetValue(-1.f));
+ EXPECT_FLOAT_EQ(2.f, curve->GetValue(0.f));
+ EXPECT_FLOAT_EQ(3.f, curve->GetValue(0.5f));
+ EXPECT_FLOAT_EQ(4.f, curve->GetValue(1.f));
+ EXPECT_FLOAT_EQ(6.f, curve->GetValue(1.5f));
+ EXPECT_FLOAT_EQ(8.f, curve->GetValue(2.f));
+ EXPECT_FLOAT_EQ(8.f, curve->GetValue(3.f));
+}
+
+// Tests that a float animation with multiple keys at a given time works sanely.
+TEST(KeyframedAnimationCurveTest, RepeatedFloatKeyTimes) {
+ scoped_ptr<KeyframedFloatAnimationCurve> curve(
+ KeyframedFloatAnimationCurve::Create());
+ curve->AddKeyframe(
+ FloatKeyframe::Create(0.0, 4.f, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(
+ FloatKeyframe::Create(1.0, 4.f, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(
+ FloatKeyframe::Create(1.0, 6.f, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(
+ FloatKeyframe::Create(2.0, 6.f, scoped_ptr<TimingFunction>()));
+
+ EXPECT_FLOAT_EQ(4.f, curve->GetValue(-1.f));
+ EXPECT_FLOAT_EQ(4.f, curve->GetValue(0.f));
+ EXPECT_FLOAT_EQ(4.f, curve->GetValue(0.5f));
+
+ // There is a discontinuity at 1. Any value between 4 and 6 is valid.
+ float value = curve->GetValue(1.f);
+ EXPECT_TRUE(value >= 4 && value <= 6);
+
+ EXPECT_FLOAT_EQ(6.f, curve->GetValue(1.5f));
+ EXPECT_FLOAT_EQ(6.f, curve->GetValue(2.f));
+ EXPECT_FLOAT_EQ(6.f, curve->GetValue(3.f));
+}
+
+// Tests that a transform animation with one keyframe works as expected.
+TEST(KeyframedAnimationCurveTest, OneTransformKeyframe) {
+ scoped_ptr<KeyframedTransformAnimationCurve> curve(
+ KeyframedTransformAnimationCurve::Create());
+ TransformOperations operations;
+ operations.AppendTranslate(2.f, 0.f, 0.f);
+ curve->AddKeyframe(
+ TransformKeyframe::Create(0.f, operations, scoped_ptr<TimingFunction>()));
+
+ ExpectTranslateX(2.f, curve->GetValue(-1.f));
+ ExpectTranslateX(2.f, curve->GetValue(0.f));
+ ExpectTranslateX(2.f, curve->GetValue(0.5f));
+ ExpectTranslateX(2.f, curve->GetValue(1.f));
+ ExpectTranslateX(2.f, curve->GetValue(2.f));
+}
+
+// Tests that a transform animation with two keyframes works as expected.
+TEST(KeyframedAnimationCurveTest, TwoTransformKeyframe) {
+ scoped_ptr<KeyframedTransformAnimationCurve> curve(
+ KeyframedTransformAnimationCurve::Create());
+ TransformOperations operations1;
+ operations1.AppendTranslate(2.f, 0.f, 0.f);
+ TransformOperations operations2;
+ operations2.AppendTranslate(4.f, 0.f, 0.f);
+
+ curve->AddKeyframe(TransformKeyframe::Create(
+ 0.f, operations1, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(TransformKeyframe::Create(
+ 1.f, operations2, scoped_ptr<TimingFunction>()));
+ ExpectTranslateX(2.f, curve->GetValue(-1.f));
+ ExpectTranslateX(2.f, curve->GetValue(0.f));
+ ExpectTranslateX(3.f, curve->GetValue(0.5f));
+ ExpectTranslateX(4.f, curve->GetValue(1.f));
+ ExpectTranslateX(4.f, curve->GetValue(2.f));
+}
+
+// Tests that a transform animation with three keyframes works as expected.
+TEST(KeyframedAnimationCurveTest, ThreeTransformKeyframe) {
+ scoped_ptr<KeyframedTransformAnimationCurve> curve(
+ KeyframedTransformAnimationCurve::Create());
+ TransformOperations operations1;
+ operations1.AppendTranslate(2.f, 0.f, 0.f);
+ TransformOperations operations2;
+ operations2.AppendTranslate(4.f, 0.f, 0.f);
+ TransformOperations operations3;
+ operations3.AppendTranslate(8.f, 0.f, 0.f);
+ curve->AddKeyframe(TransformKeyframe::Create(
+ 0.f, operations1, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(TransformKeyframe::Create(
+ 1.f, operations2, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(TransformKeyframe::Create(
+ 2.f, operations3, scoped_ptr<TimingFunction>()));
+ ExpectTranslateX(2.f, curve->GetValue(-1.f));
+ ExpectTranslateX(2.f, curve->GetValue(0.f));
+ ExpectTranslateX(3.f, curve->GetValue(0.5f));
+ ExpectTranslateX(4.f, curve->GetValue(1.f));
+ ExpectTranslateX(6.f, curve->GetValue(1.5f));
+ ExpectTranslateX(8.f, curve->GetValue(2.f));
+ ExpectTranslateX(8.f, curve->GetValue(3.f));
+}
+
+// Tests that a transform animation with multiple keys at a given time works
+// sanely.
+TEST(KeyframedAnimationCurveTest, RepeatedTransformKeyTimes) {
+ scoped_ptr<KeyframedTransformAnimationCurve> curve(
+ KeyframedTransformAnimationCurve::Create());
+ // A step function.
+ TransformOperations operations1;
+ operations1.AppendTranslate(4.f, 0.f, 0.f);
+ TransformOperations operations2;
+ operations2.AppendTranslate(4.f, 0.f, 0.f);
+ TransformOperations operations3;
+ operations3.AppendTranslate(6.f, 0.f, 0.f);
+ TransformOperations operations4;
+ operations4.AppendTranslate(6.f, 0.f, 0.f);
+ curve->AddKeyframe(TransformKeyframe::Create(
+ 0.f, operations1, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(TransformKeyframe::Create(
+ 1.f, operations2, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(TransformKeyframe::Create(
+ 1.f, operations3, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(TransformKeyframe::Create(
+ 2.f, operations4, scoped_ptr<TimingFunction>()));
+
+ ExpectTranslateX(4.f, curve->GetValue(-1.f));
+ ExpectTranslateX(4.f, curve->GetValue(0.f));
+ ExpectTranslateX(4.f, curve->GetValue(0.5f));
+
+ // There is a discontinuity at 1. Any value between 4 and 6 is valid.
+ gfx::Transform value = curve->GetValue(1.f);
+ EXPECT_GE(value.matrix().getDouble(0.f, 3.f), 4);
+ EXPECT_LE(value.matrix().getDouble(0.f, 3.f), 6);
+
+ ExpectTranslateX(6.f, curve->GetValue(1.5f));
+ ExpectTranslateX(6.f, curve->GetValue(2.f));
+ ExpectTranslateX(6.f, curve->GetValue(3.f));
+}
+
+// Tests that a filter animation with one keyframe works as expected.
+TEST(KeyframedAnimationCurveTest, OneFilterKeyframe) {
+ scoped_ptr<KeyframedFilterAnimationCurve> curve(
+ KeyframedFilterAnimationCurve::Create());
+ FilterOperations operations;
+ operations.Append(FilterOperation::CreateBrightnessFilter(2.f));
+ curve->AddKeyframe(
+ FilterKeyframe::Create(0.f, operations, scoped_ptr<TimingFunction>()));
+
+ ExpectBrightness(2.f, curve->GetValue(-1.f));
+ ExpectBrightness(2.f, curve->GetValue(0.f));
+ ExpectBrightness(2.f, curve->GetValue(0.5f));
+ ExpectBrightness(2.f, curve->GetValue(1.f));
+ ExpectBrightness(2.f, curve->GetValue(2.f));
+}
+
+// Tests that a filter animation with two keyframes works as expected.
+TEST(KeyframedAnimationCurveTest, TwoFilterKeyframe) {
+ scoped_ptr<KeyframedFilterAnimationCurve> curve(
+ KeyframedFilterAnimationCurve::Create());
+ FilterOperations operations1;
+ operations1.Append(FilterOperation::CreateBrightnessFilter(2.f));
+ FilterOperations operations2;
+ operations2.Append(FilterOperation::CreateBrightnessFilter(4.f));
+
+ curve->AddKeyframe(FilterKeyframe::Create(
+ 0.f, operations1, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(FilterKeyframe::Create(
+ 1.f, operations2, scoped_ptr<TimingFunction>()));
+ ExpectBrightness(2.f, curve->GetValue(-1.f));
+ ExpectBrightness(2.f, curve->GetValue(0.f));
+ ExpectBrightness(3.f, curve->GetValue(0.5f));
+ ExpectBrightness(4.f, curve->GetValue(1.f));
+ ExpectBrightness(4.f, curve->GetValue(2.f));
+}
+
+// Tests that a filter animation with three keyframes works as expected.
+TEST(KeyframedAnimationCurveTest, ThreeFilterKeyframe) {
+ scoped_ptr<KeyframedFilterAnimationCurve> curve(
+ KeyframedFilterAnimationCurve::Create());
+ FilterOperations operations1;
+ operations1.Append(FilterOperation::CreateBrightnessFilter(2.f));
+ FilterOperations operations2;
+ operations2.Append(FilterOperation::CreateBrightnessFilter(4.f));
+ FilterOperations operations3;
+ operations3.Append(FilterOperation::CreateBrightnessFilter(8.f));
+ curve->AddKeyframe(FilterKeyframe::Create(
+ 0.f, operations1, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(FilterKeyframe::Create(
+ 1.f, operations2, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(FilterKeyframe::Create(
+ 2.f, operations3, scoped_ptr<TimingFunction>()));
+ ExpectBrightness(2.f, curve->GetValue(-1.f));
+ ExpectBrightness(2.f, curve->GetValue(0.f));
+ ExpectBrightness(3.f, curve->GetValue(0.5f));
+ ExpectBrightness(4.f, curve->GetValue(1.f));
+ ExpectBrightness(6.f, curve->GetValue(1.5f));
+ ExpectBrightness(8.f, curve->GetValue(2.f));
+ ExpectBrightness(8.f, curve->GetValue(3.f));
+}
+
+// Tests that a filter animation with multiple keys at a given time works
+// sanely.
+TEST(KeyframedAnimationCurveTest, RepeatedFilterKeyTimes) {
+ scoped_ptr<KeyframedFilterAnimationCurve> curve(
+ KeyframedFilterAnimationCurve::Create());
+ // A step function.
+ FilterOperations operations1;
+ operations1.Append(FilterOperation::CreateBrightnessFilter(4.f));
+ FilterOperations operations2;
+ operations2.Append(FilterOperation::CreateBrightnessFilter(4.f));
+ FilterOperations operations3;
+ operations3.Append(FilterOperation::CreateBrightnessFilter(6.f));
+ FilterOperations operations4;
+ operations4.Append(FilterOperation::CreateBrightnessFilter(6.f));
+ curve->AddKeyframe(FilterKeyframe::Create(
+ 0.f, operations1, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(FilterKeyframe::Create(
+ 1.f, operations2, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(FilterKeyframe::Create(
+ 1.f, operations3, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(FilterKeyframe::Create(
+ 2.f, operations4, scoped_ptr<TimingFunction>()));
+
+ ExpectBrightness(4.f, curve->GetValue(-1.f));
+ ExpectBrightness(4.f, curve->GetValue(0.f));
+ ExpectBrightness(4.f, curve->GetValue(0.5f));
+
+ // There is a discontinuity at 1. Any value between 4 and 6 is valid.
+ FilterOperations value = curve->GetValue(1.f);
+ EXPECT_EQ(1u, value.size());
+ EXPECT_EQ(FilterOperation::BRIGHTNESS, value.at(0).type());
+ EXPECT_GE(value.at(0).amount(), 4);
+ EXPECT_LE(value.at(0).amount(), 6);
+
+ ExpectBrightness(6.f, curve->GetValue(1.5f));
+ ExpectBrightness(6.f, curve->GetValue(2.f));
+ ExpectBrightness(6.f, curve->GetValue(3.f));
+}
+
+// Tests that the keyframes may be added out of order.
+TEST(KeyframedAnimationCurveTest, UnsortedKeyframes) {
+ scoped_ptr<KeyframedFloatAnimationCurve> curve(
+ KeyframedFloatAnimationCurve::Create());
+ curve->AddKeyframe(
+ FloatKeyframe::Create(2.0, 8.f, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(
+ FloatKeyframe::Create(0.0, 2.f, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(
+ FloatKeyframe::Create(1.0, 4.f, scoped_ptr<TimingFunction>()));
+ EXPECT_FLOAT_EQ(2.f, curve->GetValue(-1.f));
+ EXPECT_FLOAT_EQ(2.f, curve->GetValue(0.f));
+ EXPECT_FLOAT_EQ(3.f, curve->GetValue(0.5f));
+ EXPECT_FLOAT_EQ(4.f, curve->GetValue(1.f));
+ EXPECT_FLOAT_EQ(6.f, curve->GetValue(1.5f));
+ EXPECT_FLOAT_EQ(8.f, curve->GetValue(2.f));
+ EXPECT_FLOAT_EQ(8.f, curve->GetValue(3.f));
+}
+
+// Tests that a cubic bezier timing function works as expected.
+TEST(KeyframedAnimationCurveTest, CubicBezierTimingFunction) {
+ scoped_ptr<KeyframedFloatAnimationCurve> curve(
+ KeyframedFloatAnimationCurve::Create());
+ curve->AddKeyframe(FloatKeyframe::Create(
+ 0.0,
+ 0.f,
+ CubicBezierTimingFunction::Create(0.25f, 0.f, 0.75f, 1.f)
+ .PassAs<TimingFunction>()));
+ curve->AddKeyframe(
+ FloatKeyframe::Create(1.0, 1.f, scoped_ptr<TimingFunction>()));
+
+ EXPECT_FLOAT_EQ(0.f, curve->GetValue(0.f));
+ EXPECT_LT(0.f, curve->GetValue(0.25f));
+ EXPECT_GT(0.25f, curve->GetValue(0.25f));
+ EXPECT_NEAR(curve->GetValue(0.5f), 0.5f, 0.00015f);
+ EXPECT_LT(0.75f, curve->GetValue(0.75f));
+ EXPECT_GT(1.f, curve->GetValue(0.75f));
+ EXPECT_FLOAT_EQ(1.f, curve->GetValue(1.f));
+}
+
+} // namespace
+} // namespace cc