1// Copyright 2014 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 "config.h"
6#include "core/animation/LengthStyleInterpolation.h"
7
8#include "core/css/CSSPrimitiveValue.h"
9#include "core/css/StylePropertySet.h"
10
11#include <gtest/gtest.h>
12
13namespace blink {
14
15class AnimationLengthStyleInterpolationTest : public ::testing::Test {
16protected:
17    static PassOwnPtrWillBeRawPtr<InterpolableValue> lengthToInterpolableValue(CSSValue* value)
18    {
19        return LengthStyleInterpolation::lengthToInterpolableValue(value);
20    }
21
22    static PassRefPtrWillBeRawPtr<CSSValue> interpolableValueToLength(InterpolableValue* value, ValueRange range)
23    {
24        return LengthStyleInterpolation::interpolableValueToLength(value, range);
25    }
26
27    static PassRefPtrWillBeRawPtr<CSSValue> roundTrip(PassRefPtrWillBeRawPtr<CSSValue> value)
28    {
29        return interpolableValueToLength(lengthToInterpolableValue(value.get()).get(), ValueRangeAll);
30    }
31
32    static void testPrimitiveValue(RefPtrWillBeRawPtr<CSSValue> value, double doubleValue, CSSPrimitiveValue::UnitType unitType)
33    {
34        EXPECT_TRUE(value->isPrimitiveValue());
35        EXPECT_EQ(doubleValue, toCSSPrimitiveValue(value.get())->getDoubleValue());
36        EXPECT_EQ(unitType, toCSSPrimitiveValue(value.get())->primitiveType());
37    }
38
39    static PassOwnPtrWillBeRawPtr<InterpolableList> createInterpolableLength(double a, double b, double c, double d, double e, double f, double g, double h, double i, double j)
40    {
41        OwnPtrWillBeRawPtr<InterpolableList> list = InterpolableList::create(10);
42        list->set(0, InterpolableNumber::create(a));
43        list->set(1, InterpolableNumber::create(b));
44        list->set(2, InterpolableNumber::create(c));
45        list->set(3, InterpolableNumber::create(d));
46        list->set(4, InterpolableNumber::create(e));
47        list->set(5, InterpolableNumber::create(f));
48        list->set(6, InterpolableNumber::create(g));
49        list->set(7, InterpolableNumber::create(h));
50        list->set(8, InterpolableNumber::create(i));
51        list->set(9, InterpolableNumber::create(j));
52
53        return list.release();
54    }
55
56    void initLengthArray(CSSLengthArray& lengthArray)
57    {
58        lengthArray.resize(CSSPrimitiveValue::LengthUnitTypeCount);
59        for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; ++i)
60            lengthArray.at(i) = 0;
61    }
62
63    CSSLengthArray& setLengthArray(CSSLengthArray& lengthArray, String text)
64    {
65        initLengthArray(lengthArray);
66        RefPtrWillBeRawPtr<MutableStylePropertySet> propertySet = MutableStylePropertySet::create();
67        propertySet->setProperty(CSSPropertyLeft, text);
68        toCSSPrimitiveValue(propertySet->getPropertyCSSValue(CSSPropertyLeft).get())->accumulateLengthArray(lengthArray);
69        return lengthArray;
70    }
71
72    bool lengthArraysEqual(CSSLengthArray& a, CSSLengthArray& b)
73    {
74        for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; ++i) {
75            if (a.at(i) != b.at(i))
76                return false;
77        }
78        return true;
79    }
80};
81
82TEST_F(AnimationLengthStyleInterpolationTest, ZeroLength)
83{
84    RefPtrWillBeRawPtr<CSSValue> value = roundTrip(CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_PX));
85    testPrimitiveValue(value, 0, CSSPrimitiveValue::CSS_PX);
86
87    value = roundTrip(CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_EMS));
88    testPrimitiveValue(value, 0, CSSPrimitiveValue::CSS_PX);
89}
90
91TEST_F(AnimationLengthStyleInterpolationTest, SingleUnit)
92{
93    RefPtrWillBeRawPtr<CSSValue> value = roundTrip(CSSPrimitiveValue::create(10, CSSPrimitiveValue::CSS_PX));
94    testPrimitiveValue(value, 10, CSSPrimitiveValue::CSS_PX);
95
96    value = roundTrip(CSSPrimitiveValue::create(30, CSSPrimitiveValue::CSS_PERCENTAGE));
97    testPrimitiveValue(value, 30, CSSPrimitiveValue::CSS_PERCENTAGE);
98
99    value = roundTrip(CSSPrimitiveValue::create(-10, CSSPrimitiveValue::CSS_EMS));
100    testPrimitiveValue(value, -10, CSSPrimitiveValue::CSS_EMS);
101}
102
103TEST_F(AnimationLengthStyleInterpolationTest, SingleClampedUnit)
104{
105    RefPtrWillBeRawPtr<CSSValue> value = CSSPrimitiveValue::create(-10, CSSPrimitiveValue::CSS_EMS);
106    value = interpolableValueToLength(lengthToInterpolableValue(value.get()).get(), ValueRangeNonNegative);
107    testPrimitiveValue(value, 0, CSSPrimitiveValue::CSS_EMS);
108}
109
110TEST_F(AnimationLengthStyleInterpolationTest, MultipleUnits)
111{
112    CSSLengthArray actual, expectation;
113    initLengthArray(expectation);
114    OwnPtrWillBeRawPtr<InterpolableList> list = createInterpolableLength(0, 10, 0, 10, 0, 10, 0, 10, 0, 10);
115    toCSSPrimitiveValue(interpolableValueToLength(list.get(), ValueRangeAll).get())->accumulateLengthArray(expectation);
116    EXPECT_TRUE(lengthArraysEqual(expectation, setLengthArray(actual, "calc(10%% + 10ex + 10ch + 10vh + 10vmax)")));
117}
118
119}
120