Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / animation / AnimatableLengthTest.cpp
1 /*
2  * Copyright (c) 2013, Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include "config.h"
32
33 #include "core/animation/AnimatableLength.h"
34
35 #include "core/animation/AnimatableValueTestHelper.h"
36 #include "core/css/CSSCalculationValue.h"
37 #include "core/css/CSSPrimitiveValue.h"
38 #include "core/css/CSSToLengthConversionData.h"
39 #include "core/rendering/style/RenderStyle.h"
40 #include "core/rendering/style/StyleInheritedData.h"
41 #include "platform/CalculationValue.h"
42 #include "wtf/MathExtras.h"
43
44 #include <gtest/gtest.h>
45
46 #define EXPECT_ROUNDTRIP(a, f) EXPECT_REFV_EQ(a, f(a.get()))
47
48 namespace WebCore {
49
50 class AnimationAnimatableLengthTest : public ::testing::Test {
51 protected:
52     AnimationAnimatableLengthTest()
53         : style(RenderStyle::createDefaultStyle())
54         , conversionDataZoom1(style.get(), style.get(), 0, 0, 1.0f)
55         , conversionDataZoom3(style.get(), style.get(), 0, 0, 3.0f)
56     {
57     }
58
59     PassRefPtr<AnimatableLength> create(double value, CSSPrimitiveValue::UnitTypes type)
60     {
61         return AnimatableLength::create(CSSPrimitiveValue::create(value, type).get());
62     }
63
64     PassRefPtr<AnimatableLength> create(double valueLeft, CSSPrimitiveValue::UnitTypes typeLeft, double valueRight, CSSPrimitiveValue::UnitTypes typeRight)
65     {
66         return AnimatableLength::create(createCalc(valueLeft, typeLeft, valueRight, typeRight).get());
67     }
68
69     PassRefPtrWillBeRawPtr<CSSCalcValue> createCalc(double valueLeft, CSSPrimitiveValue::UnitTypes typeLeft, double valueRight, CSSPrimitiveValue::UnitTypes typeRight)
70     {
71         return CSSCalcValue::create(CSSCalcValue::createExpressionNode(
72             CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(valueLeft, typeLeft), valueLeft == trunc(valueLeft)),
73             CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(valueRight, typeRight), valueRight == trunc(valueRight)),
74             CalcAdd
75         ));
76     }
77
78     PassRefPtr<CSSValue> toCSSValue(CSSValue* cssValue)
79     {
80         return AnimatableLength::create(cssValue)->toCSSValue();
81     }
82
83     AnimatableLength::NumberUnitType commonUnitType(PassRefPtr<AnimatableLength> a, PassRefPtr<AnimatableLength> b)
84     {
85         return a->commonUnitType(b.get());
86     }
87
88     bool isUnitlessZero(PassRefPtr<AnimatableLength> a)
89     {
90         return a->isUnitlessZero();
91     }
92
93     RefPtr<RenderStyle> style;
94     CSSToLengthConversionData conversionDataZoom1;
95     CSSToLengthConversionData conversionDataZoom3;
96 };
97
98 TEST_F(AnimationAnimatableLengthTest, CanCreateFrom)
99 {
100     EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_PX).get()));
101     EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_CM).get()));
102     EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_MM).get()));
103     EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_IN).get()));
104     EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_PT).get()));
105     EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_PC).get()));
106     EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_EMS).get()));
107     EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_EXS).get()));
108     EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_REMS).get()));
109     EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_PERCENTAGE).get()));
110     EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_VW).get()));
111     EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_VH).get()));
112     EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_VMIN).get()));
113     EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_VMAX).get()));
114
115     EXPECT_TRUE(AnimatableLength::canCreateFrom(createCalc(3, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_CM).get()));
116     EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(createCalc(3, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_CM)).get()));
117
118     EXPECT_FALSE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create("NaN", CSSPrimitiveValue::CSS_STRING).get()));
119 }
120
121 TEST_F(AnimationAnimatableLengthTest, Create)
122 {
123     EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_PX).get()));
124     EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_CM).get()));
125     EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_MM).get()));
126     EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_IN).get()));
127     EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_PT).get()));
128     EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_PC).get()));
129     EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_EMS).get()));
130     EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_EXS).get()));
131     EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_REMS).get()));
132     EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_PERCENTAGE).get()));
133     EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_VW).get()));
134     EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_VH).get()));
135     EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_VMIN).get()));
136     EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_VMAX).get()));
137
138     EXPECT_TRUE(static_cast<bool>(
139         AnimatableLength::create(createCalc(3, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_CM).get()).get()
140     ));
141     EXPECT_TRUE(static_cast<bool>(
142         AnimatableLength::create(CSSPrimitiveValue::create(createCalc(3, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_CM)).get()).get()
143     ));
144 }
145
146
147 TEST_F(AnimationAnimatableLengthTest, ToCSSValue)
148 {
149
150     EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_PX), toCSSValue);
151     EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_CM), toCSSValue);
152     EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_MM), toCSSValue);
153     EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_IN), toCSSValue);
154     EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_PT), toCSSValue);
155     EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_PC), toCSSValue);
156     EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_EMS), toCSSValue);
157     EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_EXS), toCSSValue);
158     EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_REMS), toCSSValue);
159     EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_PERCENTAGE), toCSSValue);
160     EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_VW), toCSSValue);
161     EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_VH), toCSSValue);
162     EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_VMIN), toCSSValue);
163     EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_VMAX), toCSSValue);
164
165     EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(createCalc(3, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_IN)), toCSSValue);
166     EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(createCalc(3, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_IN)), toCSSValue);
167 }
168
169
170 TEST_F(AnimationAnimatableLengthTest, ToLength)
171 {
172     EXPECT_EQ(Length(-5, WebCore::Fixed), create(-5, CSSPrimitiveValue::CSS_PX)->toLength(conversionDataZoom1));
173     EXPECT_EQ(Length(-15, WebCore::Fixed), create(-5, CSSPrimitiveValue::CSS_PX)->toLength(conversionDataZoom3));
174     EXPECT_EQ(Length(0, WebCore::Fixed), create(-5, CSSPrimitiveValue::CSS_PX)->toLength(conversionDataZoom1, NonNegativeValues));
175     EXPECT_EQ(Length(0, WebCore::Fixed), create(-5, CSSPrimitiveValue::CSS_PX)->toLength(conversionDataZoom3, NonNegativeValues));
176
177     EXPECT_EQ(Length(-5, Percent), create(-5, CSSPrimitiveValue::CSS_PERCENTAGE)->toLength(conversionDataZoom1));
178     EXPECT_EQ(Length(-5, Percent), create(-5, CSSPrimitiveValue::CSS_PERCENTAGE)->toLength(conversionDataZoom3));
179     EXPECT_EQ(Length(0, Percent), create(-5, CSSPrimitiveValue::CSS_PERCENTAGE)->toLength(conversionDataZoom1, NonNegativeValues));
180     EXPECT_EQ(Length(0, Percent), create(-5, CSSPrimitiveValue::CSS_PERCENTAGE)->toLength(conversionDataZoom3, NonNegativeValues));
181
182     EXPECT_EQ(
183         Length(CalculationValue::create(
184             adoptPtr(new CalcExpressionBinaryOperation(
185                 adoptPtr(new CalcExpressionLength(Length(-5, WebCore::Fixed))),
186                 adoptPtr(new CalcExpressionLength(Length(-5, Percent))),
187                 CalcAdd)),
188             ValueRangeAll)),
189         create(-5, CSSPrimitiveValue::CSS_PX, -5, CSSPrimitiveValue::CSS_PERCENTAGE)->toLength(conversionDataZoom1));
190     EXPECT_EQ(
191         Length(CalculationValue::create(
192             adoptPtr(new CalcExpressionBinaryOperation(
193                 adoptPtr(new CalcExpressionLength(Length(-15, WebCore::Fixed))),
194                 adoptPtr(new CalcExpressionLength(Length(-5, Percent))),
195                 CalcAdd)),
196             ValueRangeAll)),
197         create(-5, CSSPrimitiveValue::CSS_PX, -5, CSSPrimitiveValue::CSS_PERCENTAGE)->toLength(conversionDataZoom3));
198     EXPECT_EQ(
199         Length(CalculationValue::create(
200             adoptPtr(new CalcExpressionBinaryOperation(
201                 adoptPtr(new CalcExpressionLength(Length(-5, WebCore::Fixed))),
202                 adoptPtr(new CalcExpressionLength(Length(-5, Percent))),
203                 CalcAdd)),
204             ValueRangeNonNegative)),
205         create(-5, CSSPrimitiveValue::CSS_PX, -5, CSSPrimitiveValue::CSS_PERCENTAGE)->toLength(conversionDataZoom1, NonNegativeValues));
206     EXPECT_EQ(
207         Length(CalculationValue::create(
208             adoptPtr(new CalcExpressionBinaryOperation(
209                 adoptPtr(new CalcExpressionLength(Length(-15, WebCore::Fixed))),
210                 adoptPtr(new CalcExpressionLength(Length(-5, Percent))),
211                 CalcAdd)),
212             ValueRangeNonNegative)),
213         create(-5, CSSPrimitiveValue::CSS_PX, -5, CSSPrimitiveValue::CSS_PERCENTAGE)->toLength(conversionDataZoom3, NonNegativeValues));
214 }
215
216 TEST_F(AnimationAnimatableLengthTest, Interpolate)
217 {
218     RefPtr<AnimatableLength> from10px = create(10, CSSPrimitiveValue::CSS_PX);
219     RefPtr<AnimatableLength> to20pxAsInches = create(20.0 / 96, CSSPrimitiveValue::CSS_IN);
220
221     EXPECT_REFV_EQ(create(5,  CSSPrimitiveValue::CSS_PX),
222         AnimatableValue::interpolate(from10px.get(), to20pxAsInches.get(), -0.5));
223
224     EXPECT_REFV_EQ(create(10, CSSPrimitiveValue::CSS_PX),
225         AnimatableValue::interpolate(from10px.get(), to20pxAsInches.get(),  0));
226     EXPECT_REFV_EQ(create(14, CSSPrimitiveValue::CSS_PX),
227         AnimatableValue::interpolate(from10px.get(), to20pxAsInches.get(),  0.4));
228     EXPECT_REFV_EQ(create(15, CSSPrimitiveValue::CSS_PX),
229         AnimatableValue::interpolate(from10px.get(), to20pxAsInches.get(),  0.5));
230     EXPECT_REFV_EQ(create(16, CSSPrimitiveValue::CSS_PX),
231         AnimatableValue::interpolate(from10px.get(), to20pxAsInches.get(),  0.6));
232     EXPECT_REFV_EQ(create(20.0 / 96, CSSPrimitiveValue::CSS_IN),
233         AnimatableValue::interpolate(from10px.get(), to20pxAsInches.get(),  1));
234     EXPECT_REFV_EQ(create(25, CSSPrimitiveValue::CSS_PX),
235         AnimatableValue::interpolate(from10px.get(), to20pxAsInches.get(),  1.5));
236
237     RefPtr<AnimatableLength> from10em = create(10, CSSPrimitiveValue::CSS_EMS);
238     RefPtr<AnimatableLength> to20rem = create(20, CSSPrimitiveValue::CSS_REMS);
239     EXPECT_REFV_EQ(create(15, CSSPrimitiveValue::CSS_EMS, -10, CSSPrimitiveValue::CSS_REMS),
240         AnimatableValue::interpolate(from10em.get(), to20rem.get(), -0.5));
241     EXPECT_REFV_EQ(create(10, CSSPrimitiveValue::CSS_EMS),
242         AnimatableValue::interpolate(from10em.get(), to20rem.get(),  0));
243     EXPECT_REFV_EQ(create(6, CSSPrimitiveValue::CSS_EMS, 8, CSSPrimitiveValue::CSS_REMS),
244         AnimatableValue::interpolate(from10em.get(), to20rem.get(),  0.4));
245     EXPECT_REFV_EQ(create(5, CSSPrimitiveValue::CSS_EMS, 10, CSSPrimitiveValue::CSS_REMS),
246         AnimatableValue::interpolate(from10em.get(), to20rem.get(),  0.5));
247     EXPECT_REFV_EQ(create(4, CSSPrimitiveValue::CSS_EMS, 12, CSSPrimitiveValue::CSS_REMS),
248         AnimatableValue::interpolate(from10em.get(), to20rem.get(),  0.6));
249     EXPECT_REFV_EQ(create(20, CSSPrimitiveValue::CSS_REMS),
250         AnimatableValue::interpolate(from10em.get(), to20rem.get(),  1));
251     EXPECT_REFV_EQ(create(-5, CSSPrimitiveValue::CSS_EMS, 30, CSSPrimitiveValue::CSS_REMS),
252         AnimatableValue::interpolate(from10em.get(), to20rem.get(),  1.5));
253
254     // Zero values are typeless and hence we can don't get a calc
255     RefPtr<AnimatableLength> from0px = create(0, CSSPrimitiveValue::CSS_PX);
256     EXPECT_REFV_EQ(create(-10, CSSPrimitiveValue::CSS_REMS),
257         AnimatableValue::interpolate(from0px.get(), to20rem.get(), -0.5));
258     // At t=0, interpolate always returns the "from" value.
259     EXPECT_REFV_EQ(create(0, CSSPrimitiveValue::CSS_PX),
260         AnimatableValue::interpolate(from0px.get(), to20rem.get(), 0));
261     EXPECT_REFV_EQ(create(10, CSSPrimitiveValue::CSS_REMS),
262         AnimatableValue::interpolate(from0px.get(), to20rem.get(), 0.5));
263     EXPECT_REFV_EQ(create(20, CSSPrimitiveValue::CSS_REMS),
264         AnimatableValue::interpolate(from0px.get(), to20rem.get(), 1.0));
265     EXPECT_REFV_EQ(create(30, CSSPrimitiveValue::CSS_REMS),
266         AnimatableValue::interpolate(from0px.get(), to20rem.get(), 1.5));
267
268     // Except 0% which is special
269     RefPtr<AnimatableLength> from0percent = create(0, CSSPrimitiveValue::CSS_PERCENTAGE);
270     EXPECT_REFV_EQ(create(0, CSSPrimitiveValue::CSS_PERCENTAGE, -10, CSSPrimitiveValue::CSS_REMS),
271         AnimatableValue::interpolate(from0percent.get(), to20rem.get(), -0.5));
272     // At t=0, interpolate always returns the "from" value.
273     EXPECT_REFV_EQ(create(0, CSSPrimitiveValue::CSS_PERCENTAGE),
274         AnimatableValue::interpolate(from0percent.get(), to20rem.get(), 0));
275     EXPECT_REFV_EQ(create(0, CSSPrimitiveValue::CSS_PERCENTAGE, 10, CSSPrimitiveValue::CSS_REMS),
276         AnimatableValue::interpolate(from0percent.get(), to20rem.get(), 0.5));
277     // At t=1, interpolate always returns the "to" value.
278     EXPECT_REFV_EQ(create(20, CSSPrimitiveValue::CSS_REMS),
279         AnimatableValue::interpolate(from0percent.get(), to20rem.get(), 1.0));
280     EXPECT_REFV_EQ(create(0, CSSPrimitiveValue::CSS_PERCENTAGE, 30, CSSPrimitiveValue::CSS_REMS),
281         AnimatableValue::interpolate(from0percent.get(), to20rem.get(), 1.5));
282 }
283
284 TEST_F(AnimationAnimatableLengthTest, Add)
285 {
286     EXPECT_REFV_EQ(create(10, CSSPrimitiveValue::CSS_PX),
287         AnimatableValue::add(create(10, CSSPrimitiveValue::CSS_PX).get(), create(0, CSSPrimitiveValue::CSS_MM).get()));
288     EXPECT_REFV_EQ(create(100, CSSPrimitiveValue::CSS_PX),
289         AnimatableValue::add(create(4, CSSPrimitiveValue::CSS_PX).get(), create(1, CSSPrimitiveValue::CSS_IN).get()));
290     EXPECT_REFV_EQ(
291         create(10, CSSPrimitiveValue::CSS_EMS, 20, CSSPrimitiveValue::CSS_REMS),
292         AnimatableValue::add(create(10, CSSPrimitiveValue::CSS_EMS).get(), create(20, CSSPrimitiveValue::CSS_REMS).get()));
293     EXPECT_REFV_EQ(
294         create(10, CSSPrimitiveValue::CSS_EMS),
295         AnimatableValue::add(create(10, CSSPrimitiveValue::CSS_EMS).get(), create(0, CSSPrimitiveValue::CSS_REMS).get()));
296     EXPECT_REFV_EQ(
297         create(20, CSSPrimitiveValue::CSS_REMS),
298         AnimatableValue::add(create(0, CSSPrimitiveValue::CSS_EMS).get(), create(20, CSSPrimitiveValue::CSS_REMS).get()));
299
300     // Check you actually get the reference back for zero optimization
301     RefPtr<AnimatableLength> rems20 = create(20, CSSPrimitiveValue::CSS_REMS);
302     EXPECT_EQ(rems20.get(), AnimatableValue::add(create(0, CSSPrimitiveValue::CSS_EMS).get(), rems20.get()).get());
303     EXPECT_EQ(rems20.get(), AnimatableValue::add(rems20.get(), create(0, CSSPrimitiveValue::CSS_EMS).get()).get());
304
305     // Except 0% which is special
306     RefPtr<AnimatableLength> zeropercent = create(0, CSSPrimitiveValue::CSS_PERCENTAGE);
307     EXPECT_REFV_EQ(create(0, CSSPrimitiveValue::CSS_PERCENTAGE, -10, CSSPrimitiveValue::CSS_REMS),
308         AnimatableValue::add(zeropercent.get(), create(-10, CSSPrimitiveValue::CSS_REMS).get()));
309     EXPECT_REFV_EQ(create(-10, CSSPrimitiveValue::CSS_REMS, 0, CSSPrimitiveValue::CSS_PERCENTAGE),
310         AnimatableValue::add(create(-10, CSSPrimitiveValue::CSS_REMS).get(), zeropercent.get()));
311 }
312
313 TEST_F(AnimationAnimatableLengthTest, IsUnitless)
314 {
315     EXPECT_TRUE(isUnitlessZero(create(0, CSSPrimitiveValue::CSS_PX)));
316     EXPECT_FALSE(isUnitlessZero(create(0, CSSPrimitiveValue::CSS_PERCENTAGE)));
317     EXPECT_TRUE(isUnitlessZero(create(0, CSSPrimitiveValue::CSS_EMS)));
318     EXPECT_TRUE(isUnitlessZero(create(0, CSSPrimitiveValue::CSS_EXS)));
319     EXPECT_TRUE(isUnitlessZero(create(0, CSSPrimitiveValue::CSS_REMS)));
320     EXPECT_TRUE(isUnitlessZero(create(0, CSSPrimitiveValue::CSS_VW)));
321     EXPECT_TRUE(isUnitlessZero(create(0, CSSPrimitiveValue::CSS_VH)));
322     EXPECT_TRUE(isUnitlessZero(create(0, CSSPrimitiveValue::CSS_VMIN)));
323     EXPECT_TRUE(isUnitlessZero(create(0, CSSPrimitiveValue::CSS_VMAX)));
324
325     EXPECT_FALSE(isUnitlessZero(create(1, CSSPrimitiveValue::CSS_PX)));
326     EXPECT_FALSE(isUnitlessZero(create(2, CSSPrimitiveValue::CSS_PERCENTAGE)));
327     EXPECT_FALSE(isUnitlessZero(create(3, CSSPrimitiveValue::CSS_EMS)));
328     EXPECT_FALSE(isUnitlessZero(create(4, CSSPrimitiveValue::CSS_EXS)));
329     EXPECT_FALSE(isUnitlessZero(create(5, CSSPrimitiveValue::CSS_REMS)));
330     EXPECT_FALSE(isUnitlessZero(create(6, CSSPrimitiveValue::CSS_VW)));
331     EXPECT_FALSE(isUnitlessZero(create(7, CSSPrimitiveValue::CSS_VH)));
332     EXPECT_FALSE(isUnitlessZero(create(8, CSSPrimitiveValue::CSS_VMIN)));
333     EXPECT_FALSE(isUnitlessZero(create(9, CSSPrimitiveValue::CSS_VMAX)));
334 }
335
336 TEST_F(AnimationAnimatableLengthTest, CommonUnitType)
337 {
338     RefPtr<AnimatableLength> length10px = create(10, CSSPrimitiveValue::CSS_PX);
339     EXPECT_EQ(AnimatableLength::UnitTypePixels,  commonUnitType(length10px, create(1, CSSPrimitiveValue::CSS_PX).get()));
340     EXPECT_EQ(AnimatableLength::UnitTypeCalc, commonUnitType(length10px, create(2, CSSPrimitiveValue::CSS_PERCENTAGE).get()));
341     EXPECT_EQ(AnimatableLength::UnitTypeCalc, commonUnitType(length10px, create(3, CSSPrimitiveValue::CSS_EMS).get()));
342     EXPECT_EQ(AnimatableLength::UnitTypeCalc, commonUnitType(length10px, create(4, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_CM).get()));
343     EXPECT_EQ(AnimatableLength::UnitTypeCalc, commonUnitType(length10px, create(0, CSSPrimitiveValue::CSS_PERCENTAGE).get()));
344
345     RefPtr<AnimatableLength> length0px = create(0, CSSPrimitiveValue::CSS_PX);
346     EXPECT_EQ(AnimatableLength::UnitTypePixels,     commonUnitType(length0px, create(1, CSSPrimitiveValue::CSS_PX).get()));
347     EXPECT_EQ(AnimatableLength::UnitTypePercentage, commonUnitType(length0px, create(2, CSSPrimitiveValue::CSS_PERCENTAGE).get()));
348     EXPECT_EQ(AnimatableLength::UnitTypeFontSize,   commonUnitType(length0px, create(3, CSSPrimitiveValue::CSS_EMS).get()));
349     EXPECT_EQ(AnimatableLength::UnitTypeCalc,    commonUnitType(length0px, create(4, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_CM).get()));
350     EXPECT_EQ(AnimatableLength::UnitTypePercentage, commonUnitType(length0px, create(0, CSSPrimitiveValue::CSS_PERCENTAGE).get()));
351
352     RefPtr<AnimatableLength> length0percent = create(0, CSSPrimitiveValue::CSS_PERCENTAGE);
353     EXPECT_EQ(AnimatableLength::UnitTypeCalc,    commonUnitType(length0percent, create(1, CSSPrimitiveValue::CSS_PX).get()));
354     EXPECT_EQ(AnimatableLength::UnitTypePercentage, commonUnitType(length0percent, create(2, CSSPrimitiveValue::CSS_PERCENTAGE).get()));
355     EXPECT_EQ(AnimatableLength::UnitTypeCalc,    commonUnitType(length0percent, create(3, CSSPrimitiveValue::CSS_EMS).get()));
356     EXPECT_EQ(AnimatableLength::UnitTypeCalc,    commonUnitType(length0percent, create(4, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_CM).get()));
357     EXPECT_EQ(AnimatableLength::UnitTypePercentage, commonUnitType(length0percent, create(0, CSSPrimitiveValue::CSS_PERCENTAGE).get()));
358
359     RefPtr<AnimatableLength> lengthCalc = create(3, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_CM);
360     EXPECT_EQ(AnimatableLength::UnitTypeCalc, commonUnitType(lengthCalc, create(1, CSSPrimitiveValue::CSS_PX).get()));
361     EXPECT_EQ(AnimatableLength::UnitTypeCalc, commonUnitType(lengthCalc, create(2, CSSPrimitiveValue::CSS_PERCENTAGE).get()));
362     EXPECT_EQ(AnimatableLength::UnitTypeCalc, commonUnitType(lengthCalc, create(3, CSSPrimitiveValue::CSS_EMS).get()));
363     EXPECT_EQ(AnimatableLength::UnitTypeCalc, commonUnitType(lengthCalc, create(4, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_CM).get()));
364     EXPECT_EQ(AnimatableLength::UnitTypeCalc, commonUnitType(lengthCalc, create(0, CSSPrimitiveValue::CSS_PERCENTAGE).get()));
365 }
366
367 } // namespace WebCore