blob: 3ac40d45040f2df951b936e59dd6a00ed66029f3 [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(std::make_unique<InterpolableNumber>(a));
InterpolationValue end(std::make_unique<InterpolableNumber>(b));
TransitionInterpolation* i = MakeGarbageCollected<TransitionInterpolation>(
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 To<InterpolableNumber>(interpolated_value->GetInterpolableValue())
.Value();
}
void ScaleAndAdd(InterpolableValue& base,
double scale,
const InterpolableValue& add) {
base.ScaleAndAdd(scale, add);
}
std::unique_ptr<InterpolableValue> InterpolateLists(
std::unique_ptr<InterpolableValue> list_a,
std::unique_ptr<InterpolableValue> list_b,
double progress) {
std::unique_ptr<InterpolableValue> result = list_a->CloneAndZero();
list_a->Interpolate(*list_b, progress, *result);
return result;
}
};
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) {
auto list_a = std::make_unique<InterpolableList>(3);
list_a->Set(0, std::make_unique<InterpolableNumber>(0));
list_a->Set(1, std::make_unique<InterpolableNumber>(42));
list_a->Set(2, std::make_unique<InterpolableNumber>(20.5));
auto list_b = std::make_unique<InterpolableList>(3);
list_b->Set(0, std::make_unique<InterpolableNumber>(100));
list_b->Set(1, std::make_unique<InterpolableNumber>(-200));
list_b->Set(2, std::make_unique<InterpolableNumber>(300));
std::unique_ptr<InterpolableValue> interpolated_value =
InterpolateLists(std::move(list_a), std::move(list_b), 0.3);
const auto& out_list = To<InterpolableList>(*interpolated_value);
EXPECT_FLOAT_EQ(30, To<InterpolableNumber>(out_list.Get(0))->Value());
EXPECT_FLOAT_EQ(-30.6f, To<InterpolableNumber>(out_list.Get(1))->Value());
EXPECT_FLOAT_EQ(104.35f, To<InterpolableNumber>(out_list.Get(2))->Value());
}
TEST_F(AnimationInterpolableValueTest, NestedList) {
auto list_a = std::make_unique<InterpolableList>(3);
list_a->Set(0, std::make_unique<InterpolableNumber>(0));
auto sub_list_a = std::make_unique<InterpolableList>(1);
sub_list_a->Set(0, std::make_unique<InterpolableNumber>(100));
list_a->Set(1, std::move(sub_list_a));
list_a->Set(2, std::make_unique<InterpolableNumber>(0));
auto list_b = std::make_unique<InterpolableList>(3);
list_b->Set(0, std::make_unique<InterpolableNumber>(100));
auto sub_list_b = std::make_unique<InterpolableList>(1);
sub_list_b->Set(0, std::make_unique<InterpolableNumber>(50));
list_b->Set(1, std::move(sub_list_b));
list_b->Set(2, std::make_unique<InterpolableNumber>(1));
std::unique_ptr<InterpolableValue> interpolated_value =
InterpolateLists(std::move(list_a), std::move(list_b), 0.5);
const auto& out_list = To<InterpolableList>(*interpolated_value);
EXPECT_FLOAT_EQ(50, To<InterpolableNumber>(out_list.Get(0))->Value());
EXPECT_FLOAT_EQ(
75, To<InterpolableNumber>(To<InterpolableList>(out_list.Get(1))->Get(0))
->Value());
EXPECT_FLOAT_EQ(0.5, To<InterpolableNumber>(out_list.Get(2))->Value());
}
TEST_F(AnimationInterpolableValueTest, ScaleAndAddNumbers) {
std::unique_ptr<InterpolableNumber> base =
std::make_unique<InterpolableNumber>(10);
ScaleAndAdd(*base, 2, *std::make_unique<InterpolableNumber>(1));
EXPECT_FLOAT_EQ(21, base->Value());
base = std::make_unique<InterpolableNumber>(10);
ScaleAndAdd(*base, 0, *std::make_unique<InterpolableNumber>(5));
EXPECT_FLOAT_EQ(5, base->Value());
base = std::make_unique<InterpolableNumber>(10);
ScaleAndAdd(*base, -1, *std::make_unique<InterpolableNumber>(8));
EXPECT_FLOAT_EQ(-2, base->Value());
}
TEST_F(AnimationInterpolableValueTest, ScaleAndAddLists) {
auto base_list = std::make_unique<InterpolableList>(3);
base_list->Set(0, std::make_unique<InterpolableNumber>(5));
base_list->Set(1, std::make_unique<InterpolableNumber>(10));
base_list->Set(2, std::make_unique<InterpolableNumber>(15));
auto add_list = std::make_unique<InterpolableList>(3);
add_list->Set(0, std::make_unique<InterpolableNumber>(1));
add_list->Set(1, std::make_unique<InterpolableNumber>(2));
add_list->Set(2, std::make_unique<InterpolableNumber>(3));
ScaleAndAdd(*base_list, 2, *add_list);
EXPECT_FLOAT_EQ(11, To<InterpolableNumber>(base_list->Get(0))->Value());
EXPECT_FLOAT_EQ(22, To<InterpolableNumber>(base_list->Get(1))->Value());
EXPECT_FLOAT_EQ(33, To<InterpolableNumber>(base_list->Get(2))->Value());
}
} // namespace blink