blob: 89ab7f38725b6d202b46d14c6f47857b355ca07d [file] [log] [blame]
// Copyright 2014 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 <memory>
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/animation/animation_test_helper.h"
#include "third_party/blink/renderer/core/animation/css_length_interpolation_type.h"
#include "third_party/blink/renderer/core/animation/css_number_interpolation_type.h"
#include "third_party/blink/renderer/core/animation/interpolable_value.h"
#include "third_party/blink/renderer/core/animation/interpolation_value.h"
#include "third_party/blink/renderer/core/animation/string_keyframe.h"
#include "third_party/blink/renderer/core/animation/transition_interpolation.h"
namespace blink {
class AnimationInterpolableValueTest : public testing::Test {
protected:
double InterpolateNumbers(int a, int b, double progress) {
// We require a property that maps to CSSNumberInterpolationType. 'z-index'
// suffices for this, and also means we can ignore the AnimatableValues for
// the compositor (as z-index isn't compositor-compatible).
PropertyHandle property_handle(GetCSSPropertyZIndex());
CSSNumberInterpolationType interpolation_type(property_handle);
InterpolationValue start(InterpolableNumber::Create(a));
InterpolationValue end(InterpolableNumber::Create(b));
TransitionInterpolation* i = TransitionInterpolation::Create(
property_handle, interpolation_type, std::move(start), std::move(end),
nullptr, nullptr);
i->Interpolate(0, progress);
std::unique_ptr<TypedInterpolationValue> interpolated_value =
i->GetInterpolatedValue();
EXPECT_TRUE(interpolated_value);
return ToInterpolableNumber(interpolated_value->GetInterpolableValue())
.Value();
}
void ScaleAndAdd(InterpolableValue& base,
double scale,
const InterpolableValue& add) {
base.ScaleAndAdd(scale, add);
}
std::unique_ptr<TypedInterpolationValue> InterpolateLists(
std::unique_ptr<InterpolableList> list_a,
std::unique_ptr<InterpolableList> list_b,
double progress) {
// We require a property that maps to CSSLengthInterpolationType. 'left'
// suffices for this, and also means we can ignore the AnimatableValues for
// the compositor (as left isn't compositor-compatible).
PropertyHandle property_handle(GetCSSPropertyLeft());
CSSLengthInterpolationType interpolation_type(property_handle);
InterpolationValue start(std::move(list_a));
InterpolationValue end(std::move(list_b));
TransitionInterpolation* i = TransitionInterpolation::Create(
property_handle, interpolation_type, std::move(start), std::move(end),
nullptr, nullptr);
i->Interpolate(0, progress);
return i->GetInterpolatedValue();
}
};
TEST_F(AnimationInterpolableValueTest, InterpolateNumbers) {
EXPECT_FLOAT_EQ(126, InterpolateNumbers(42, 0, -2));
EXPECT_FLOAT_EQ(42, InterpolateNumbers(42, 0, 0));
EXPECT_FLOAT_EQ(29.4f, InterpolateNumbers(42, 0, 0.3));
EXPECT_FLOAT_EQ(21, InterpolateNumbers(42, 0, 0.5));
EXPECT_FLOAT_EQ(0, InterpolateNumbers(42, 0, 1));
EXPECT_FLOAT_EQ(-21, InterpolateNumbers(42, 0, 1.5));
}
TEST_F(AnimationInterpolableValueTest, SimpleList) {
std::unique_ptr<InterpolableList> list_a = InterpolableList::Create(3);
list_a->Set(0, InterpolableNumber::Create(0));
list_a->Set(1, InterpolableNumber::Create(42));
list_a->Set(2, InterpolableNumber::Create(20.5));
std::unique_ptr<InterpolableList> list_b = InterpolableList::Create(3);
list_b->Set(0, InterpolableNumber::Create(100));
list_b->Set(1, InterpolableNumber::Create(-200));
list_b->Set(2, InterpolableNumber::Create(300));
std::unique_ptr<TypedInterpolationValue> interpolated_value =
InterpolateLists(std::move(list_a), std::move(list_b), 0.3);
const InterpolableList& out_list =
ToInterpolableList(interpolated_value->GetInterpolableValue());
EXPECT_FLOAT_EQ(30, ToInterpolableNumber(out_list.Get(0))->Value());
EXPECT_FLOAT_EQ(-30.6f, ToInterpolableNumber(out_list.Get(1))->Value());
EXPECT_FLOAT_EQ(104.35f, ToInterpolableNumber(out_list.Get(2))->Value());
}
TEST_F(AnimationInterpolableValueTest, NestedList) {
std::unique_ptr<InterpolableList> list_a = InterpolableList::Create(3);
list_a->Set(0, InterpolableNumber::Create(0));
std::unique_ptr<InterpolableList> sub_list_a = InterpolableList::Create(1);
sub_list_a->Set(0, InterpolableNumber::Create(100));
list_a->Set(1, std::move(sub_list_a));
list_a->Set(2, InterpolableNumber::Create(0));
std::unique_ptr<InterpolableList> list_b = InterpolableList::Create(3);
list_b->Set(0, InterpolableNumber::Create(100));
std::unique_ptr<InterpolableList> sub_list_b = InterpolableList::Create(1);
sub_list_b->Set(0, InterpolableNumber::Create(50));
list_b->Set(1, std::move(sub_list_b));
list_b->Set(2, InterpolableNumber::Create(1));
std::unique_ptr<TypedInterpolationValue> interpolated_value =
InterpolateLists(std::move(list_a), std::move(list_b), 0.5);
const InterpolableList& out_list =
ToInterpolableList(interpolated_value->GetInterpolableValue());
EXPECT_FLOAT_EQ(50, ToInterpolableNumber(out_list.Get(0))->Value());
EXPECT_FLOAT_EQ(
75, ToInterpolableNumber(ToInterpolableList(out_list.Get(1))->Get(0))
->Value());
EXPECT_FLOAT_EQ(0.5, ToInterpolableNumber(out_list.Get(2))->Value());
}
TEST_F(AnimationInterpolableValueTest, ScaleAndAddNumbers) {
std::unique_ptr<InterpolableNumber> base = InterpolableNumber::Create(10);
ScaleAndAdd(*base, 2, *InterpolableNumber::Create(1));
EXPECT_FLOAT_EQ(21, base->Value());
base = InterpolableNumber::Create(10);
ScaleAndAdd(*base, 0, *InterpolableNumber::Create(5));
EXPECT_FLOAT_EQ(5, base->Value());
base = InterpolableNumber::Create(10);
ScaleAndAdd(*base, -1, *InterpolableNumber::Create(8));
EXPECT_FLOAT_EQ(-2, base->Value());
}
TEST_F(AnimationInterpolableValueTest, ScaleAndAddLists) {
std::unique_ptr<InterpolableList> base_list = InterpolableList::Create(3);
base_list->Set(0, InterpolableNumber::Create(5));
base_list->Set(1, InterpolableNumber::Create(10));
base_list->Set(2, InterpolableNumber::Create(15));
std::unique_ptr<InterpolableList> add_list = InterpolableList::Create(3);
add_list->Set(0, InterpolableNumber::Create(1));
add_list->Set(1, InterpolableNumber::Create(2));
add_list->Set(2, InterpolableNumber::Create(3));
ScaleAndAdd(*base_list, 2, *add_list);
EXPECT_FLOAT_EQ(11, ToInterpolableNumber(base_list->Get(0))->Value());
EXPECT_FLOAT_EQ(22, ToInterpolableNumber(base_list->Get(1))->Value());
EXPECT_FLOAT_EQ(33, ToInterpolableNumber(base_list->Get(2))->Value());
}
} // namespace blink