Upstream version 5.34.98.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / animation / AnimationTranslationUtilTest.cpp
1 /*
2  * Copyright (C) 2012 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
6  * are met:
7  * 1.  Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  * 2.  Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24
25 #include "config.h"
26
27 #include "core/animation/AnimationTranslationUtil.h"
28
29 #include "core/animation/css/CSSAnimationData.h"
30 #include "platform/animation/KeyframeValueList.h"
31 #include "platform/geometry/IntSize.h"
32 #include "platform/graphics/filters/FilterOperations.h"
33 #include "platform/transforms/Matrix3DTransformOperation.h"
34 #include "platform/transforms/RotateTransformOperation.h"
35 #include "platform/transforms/ScaleTransformOperation.h"
36 #include "platform/transforms/TransformOperations.h"
37 #include "platform/transforms/TranslateTransformOperation.h"
38 #include "public/platform/WebAnimation.h"
39 #include "public/platform/WebFilterOperations.h"
40 #include "wtf/RefPtr.h"
41 #include <gmock/gmock.h>
42 #include <gtest/gtest.h>
43
44 using namespace WebCore;
45 using namespace blink;
46
47 namespace {
48
49 class WebTransformOperationsMock : public blink::WebTransformOperations {
50 public:
51     MOCK_CONST_METHOD1(canBlendWith, bool(const WebTransformOperations&));
52     MOCK_METHOD3(appendTranslate, void(double, double, double));
53     MOCK_METHOD4(appendRotate, void(double, double, double, double));
54     MOCK_METHOD3(appendScale, void(double, double, double));
55     MOCK_METHOD2(appendSkew, void(double, double));
56     MOCK_METHOD1(appendPerspective, void(double));
57     MOCK_METHOD1(appendMatrix, void(const SkMatrix44&));
58     MOCK_METHOD0(appendIdentity, void());
59     MOCK_CONST_METHOD0(isIdentity, bool());
60 };
61
62 class WebFilterOperationsMock : public blink::WebFilterOperations {
63 public:
64     MOCK_METHOD1(appendGrayscaleFilter, void(float));
65     MOCK_METHOD1(appendSepiaFilter, void(float));
66     MOCK_METHOD1(appendSaturateFilter, void(float));
67     MOCK_METHOD1(appendHueRotateFilter, void(float));
68     MOCK_METHOD1(appendInvertFilter, void(float));
69     MOCK_METHOD1(appendBrightnessFilter, void(float));
70     MOCK_METHOD1(appendContrastFilter, void(float));
71     MOCK_METHOD1(appendOpacityFilter, void(float));
72     MOCK_METHOD1(appendBlurFilter, void(float));
73     MOCK_METHOD3(appendDropShadowFilter, void(WebPoint, float, WebColor));
74     MOCK_METHOD1(appendColorMatrixFilter, void(SkScalar[20]));
75     MOCK_METHOD2(appendZoomFilter, void(float, int));
76     MOCK_METHOD1(appendSaturatingBrightnessFilter, void(float));
77     MOCK_METHOD1(appendReferenceFilter, void(SkImageFilter*));
78     MOCK_METHOD0(clear, void());
79 };
80
81 bool animationCanBeTranslated(const KeyframeValueList& values, CSSAnimationData* animation)
82 {
83     IntSize boxSize;
84     return createWebAnimation(values, animation, 0, 0, boxSize);
85 }
86
87 TEST(AnimationTranslationUtilTest, createOpacityAnimation)
88 {
89     const double duration = 1;
90     WebCore::KeyframeValueList values(AnimatedPropertyOpacity);
91     values.insert(adoptPtr(new FloatAnimationValue(0, 0)));
92     values.insert(adoptPtr(new FloatAnimationValue(duration, 1)));
93
94     RefPtr<CSSAnimationData> animation = CSSAnimationData::create();
95     animation->setDuration(duration);
96
97     EXPECT_TRUE(animationCanBeTranslated(values, animation.get()));
98 }
99
100 TEST(AnimationTranslationUtilTest, createFilterAnimation)
101 {
102     const double duration = 1;
103     WebCore::KeyframeValueList values(AnimatedPropertyWebkitFilter);
104
105     FilterOperations operations1;
106     operations1.operations().append(BasicColorMatrixFilterOperation::create(0.5, FilterOperation::SATURATE));
107     values.insert(adoptPtr(new FilterAnimationValue(0, &operations1)));
108
109     FilterOperations operations2;
110     operations2.operations().append(BasicColorMatrixFilterOperation::create(1.0, FilterOperation::SATURATE));
111     values.insert(adoptPtr(new FilterAnimationValue(duration, &operations2)));
112
113     RefPtr<CSSAnimationData> animation = CSSAnimationData::create();
114     animation->setDuration(duration);
115
116     EXPECT_TRUE(animationCanBeTranslated(values, animation.get()));
117 }
118
119 TEST(AnimationTranslationUtilTest, createTransformAnimation)
120 {
121     const double duration = 1;
122     WebCore::KeyframeValueList values(AnimatedPropertyWebkitTransform);
123
124     TransformOperations operations1;
125     operations1.operations().append(TranslateTransformOperation::create(Length(2, WebCore::Fixed), Length(0, WebCore::Fixed), TransformOperation::TranslateX));
126     values.insert(adoptPtr(new TransformAnimationValue(0, &operations1)));
127
128     TransformOperations operations2;
129     operations2.operations().append(TranslateTransformOperation::create(Length(4, WebCore::Fixed), Length(0, WebCore::Fixed), TransformOperation::TranslateX));
130     values.insert(adoptPtr(new TransformAnimationValue(duration, &operations2)));
131
132     RefPtr<CSSAnimationData> animation = CSSAnimationData::create();
133     animation->setDuration(duration);
134
135     EXPECT_TRUE(animationCanBeTranslated(values, animation.get()));
136 }
137
138 TEST(AnimationTranslationUtilTest, createTransformAnimationWithBigRotation)
139 {
140     const double duration = 1;
141     WebCore::KeyframeValueList values(AnimatedPropertyWebkitTransform);
142
143     TransformOperations operations1;
144     operations1.operations().append(RotateTransformOperation::create(0, TransformOperation::Rotate));
145     values.insert(adoptPtr(new TransformAnimationValue(0, &operations1)));
146
147     TransformOperations operations2;
148     operations2.operations().append(RotateTransformOperation::create(270, TransformOperation::Rotate));
149     values.insert(adoptPtr(new TransformAnimationValue(duration, &operations2)));
150
151     RefPtr<CSSAnimationData> animation = CSSAnimationData::create();
152     animation->setDuration(duration);
153
154     EXPECT_TRUE(animationCanBeTranslated(values, animation.get()));
155 }
156
157 TEST(AnimationTranslationUtilTest, createTransformAnimationWithBigRotationAndEmptyTransformOperationList)
158 {
159     const double duration = 1;
160     WebCore::KeyframeValueList values(AnimatedPropertyWebkitTransform);
161
162     TransformOperations operations1;
163     values.insert(adoptPtr(new TransformAnimationValue(0, &operations1)));
164
165     TransformOperations operations2;
166     operations2.operations().append(RotateTransformOperation::create(270, TransformOperation::Rotate));
167     values.insert(adoptPtr(new TransformAnimationValue(duration, &operations2)));
168
169     RefPtr<CSSAnimationData> animation = CSSAnimationData::create();
170     animation->setDuration(duration);
171
172     EXPECT_TRUE(animationCanBeTranslated(values, animation.get()));
173 }
174
175 TEST(AnimationTranslationUtilTest, createTransformAnimationWithRotationInvolvingNegativeAngles)
176 {
177     const double duration = 1;
178     WebCore::KeyframeValueList values(AnimatedPropertyWebkitTransform);
179
180     TransformOperations operations1;
181     operations1.operations().append(RotateTransformOperation::create(-330, TransformOperation::Rotate));
182     values.insert(adoptPtr(new TransformAnimationValue(0, &operations1)));
183
184     TransformOperations operations2;
185     operations2.operations().append(RotateTransformOperation::create(-320, TransformOperation::Rotate));
186     values.insert(adoptPtr(new TransformAnimationValue(duration, &operations2)));
187
188     RefPtr<CSSAnimationData> animation = CSSAnimationData::create();
189     animation->setDuration(duration);
190
191     EXPECT_TRUE(animationCanBeTranslated(values, animation.get()));
192 }
193
194 TEST(AnimationTranslationUtilTest, createTransformAnimationWithSmallRotationInvolvingLargeAngles)
195 {
196     const double duration = 1;
197     WebCore::KeyframeValueList values(AnimatedPropertyWebkitTransform);
198
199     TransformOperations operations1;
200     operations1.operations().append(RotateTransformOperation::create(270, TransformOperation::Rotate));
201     values.insert(adoptPtr(new TransformAnimationValue(0, &operations1)));
202
203     TransformOperations operations2;
204     operations2.operations().append(RotateTransformOperation::create(360, TransformOperation::Rotate));
205     values.insert(adoptPtr(new TransformAnimationValue(duration, &operations2)));
206
207     RefPtr<CSSAnimationData> animation = CSSAnimationData::create();
208     animation->setDuration(duration);
209
210     EXPECT_TRUE(animationCanBeTranslated(values, animation.get()));
211 }
212
213 TEST(AnimationTranslationUtilTest, createTransformAnimationWithNonDecomposableMatrix)
214 {
215     const double duration = 1;
216     WebCore::KeyframeValueList values(AnimatedPropertyWebkitTransform);
217
218     TransformationMatrix matrix1;
219     TransformOperations operations1;
220     operations1.operations().append(Matrix3DTransformOperation::create(matrix1));
221     values.insert(adoptPtr(new TransformAnimationValue(0, &operations1)));
222
223     TransformationMatrix matrix2;
224     matrix2.setM11(0);
225     TransformOperations operations2;
226     operations2.operations().append(Matrix3DTransformOperation::create(matrix2));
227     values.insert(adoptPtr(new TransformAnimationValue(duration, &operations2)));
228
229     RefPtr<CSSAnimationData> animation = CSSAnimationData::create();
230     animation->setDuration(duration);
231
232     EXPECT_FALSE(animationCanBeTranslated(values, animation.get()));
233 }
234
235 TEST(AnimationTranslationUtilTest, createTransformAnimationWithNonInvertibleTransform)
236 {
237     const double duration = 1;
238     WebCore::KeyframeValueList values(AnimatedPropertyWebkitTransform);
239
240     TransformOperations operations1;
241     operations1.operations().append(ScaleTransformOperation::create(1, 1, 1, TransformOperation::Scale3D));
242     values.insert(adoptPtr(new TransformAnimationValue(0, &operations1)));
243
244     TransformOperations operations2;
245     operations2.operations().append(ScaleTransformOperation::create(1, 0, 1, TransformOperation::Scale3D));
246     values.insert(adoptPtr(new TransformAnimationValue(duration, &operations2)));
247
248     RefPtr<CSSAnimationData> animation = CSSAnimationData::create();
249     animation->setDuration(duration);
250
251     EXPECT_TRUE(animationCanBeTranslated(values, animation.get()));
252 }
253
254 TEST(AnimationTranslationUtilTest, createReversedAnimation)
255 {
256     const double duration = 1;
257     WebCore::KeyframeValueList values(AnimatedPropertyWebkitTransform);
258
259     TransformOperations operations1;
260     operations1.operations().append(TranslateTransformOperation::create(Length(2, WebCore::Fixed), Length(0, WebCore::Fixed), TransformOperation::TranslateX));
261     values.insert(adoptPtr(new TransformAnimationValue(0, &operations1)));
262
263     TransformOperations operations2;
264     operations2.operations().append(TranslateTransformOperation::create(Length(4, WebCore::Fixed), Length(0, WebCore::Fixed), TransformOperation::TranslateX));
265     values.insert(adoptPtr(new TransformAnimationValue(duration, &operations2)));
266
267     RefPtr<CSSAnimationData> animation = CSSAnimationData::create();
268     animation->setDuration(duration);
269     animation->setDirection(CSSAnimationData::AnimationDirectionReverse);
270
271     EXPECT_TRUE(animationCanBeTranslated(values, animation.get()));
272 }
273
274 TEST(AnimationTranslationUtilTest, createAlternatingAnimation)
275 {
276     const double duration = 1;
277     WebCore::KeyframeValueList values(AnimatedPropertyWebkitTransform);
278
279     TransformOperations operations1;
280     operations1.operations().append(TranslateTransformOperation::create(Length(2, WebCore::Fixed), Length(0, WebCore::Fixed), TransformOperation::TranslateX));
281     values.insert(adoptPtr(new TransformAnimationValue(0, &operations1)));
282
283     TransformOperations operations2;
284     operations2.operations().append(TranslateTransformOperation::create(Length(4, WebCore::Fixed), Length(0, WebCore::Fixed), TransformOperation::TranslateX));
285     values.insert(adoptPtr(new TransformAnimationValue(duration, &operations2)));
286
287     RefPtr<CSSAnimationData> animation = CSSAnimationData::create();
288     animation->setDuration(duration);
289     animation->setDirection(CSSAnimationData::AnimationDirectionAlternate);
290     animation->setIterationCount(2);
291
292     EXPECT_TRUE(animationCanBeTranslated(values, animation.get()));
293 }
294
295 TEST(AnimationTranslationUtilTest, createReversedAlternatingAnimation)
296 {
297     const double duration = 1;
298     WebCore::KeyframeValueList values(AnimatedPropertyWebkitTransform);
299
300     TransformOperations operations1;
301     operations1.operations().append(TranslateTransformOperation::create(Length(2, WebCore::Fixed), Length(0, WebCore::Fixed), TransformOperation::TranslateX));
302     values.insert(adoptPtr(new TransformAnimationValue(0, &operations1)));
303
304     TransformOperations operations2;
305     operations2.operations().append(TranslateTransformOperation::create(Length(4, WebCore::Fixed), Length(0, WebCore::Fixed), TransformOperation::TranslateX));
306     values.insert(adoptPtr(new TransformAnimationValue(duration, &operations2)));
307
308     RefPtr<CSSAnimationData> animation = CSSAnimationData::create();
309     animation->setDuration(duration);
310     animation->setDirection(CSSAnimationData::AnimationDirectionAlternateReverse);
311     animation->setIterationCount(2);
312
313     EXPECT_TRUE(animationCanBeTranslated(values, animation.get()));
314 }
315
316 TEST(AnimationTranslationUtilTest, transformsWork)
317 {
318     TransformOperations ops;
319     FloatSize box(100, 200);
320     WebTransformOperationsMock outOps;
321
322     EXPECT_CALL(outOps, appendTranslate(2, 0, 0));
323     EXPECT_CALL(outOps, appendTranslate(2, 60, 0));
324     EXPECT_CALL(outOps, appendRotate(0.1, 0.2, 0.3, 200000.4));
325     EXPECT_CALL(outOps, appendScale(50.2, 100, -4));
326
327     ops.operations().append(TranslateTransformOperation::create(Length(2, WebCore::Fixed), Length(0, WebCore::Fixed), TransformOperation::TranslateX));
328     ops.operations().append(TranslateTransformOperation::create(Length(2, WebCore::Percent), Length(30, WebCore::Percent), TransformOperation::Translate));
329     ops.operations().append(RotateTransformOperation::create(0.1, 0.2, 0.3, 200000.4, TransformOperation::Rotate3D));
330     ops.operations().append(ScaleTransformOperation::create(50.2, 100, -4, TransformOperation::Scale3D));
331     toWebTransformOperations(ops, box, &outOps);
332 }
333
334 TEST(AnimationTranslationUtilTest, filtersWork)
335 {
336     FilterOperations ops;
337     WebFilterOperationsMock outOps;
338
339     EXPECT_CALL(outOps, appendSaturateFilter(0.5));
340     EXPECT_CALL(outOps, appendGrayscaleFilter(0.2f));
341     EXPECT_CALL(outOps, appendSepiaFilter(0.8f));
342     EXPECT_CALL(outOps, appendOpacityFilter(0.1f));
343
344     ops.operations().append(BasicColorMatrixFilterOperation::create(0.5, FilterOperation::SATURATE));
345     ops.operations().append(BasicColorMatrixFilterOperation::create(0.2, FilterOperation::GRAYSCALE));
346     ops.operations().append(BasicColorMatrixFilterOperation::create(0.8, FilterOperation::SEPIA));
347     ops.operations().append(BasicColorMatrixFilterOperation::create(0.1, FilterOperation::OPACITY));
348     toWebFilterOperations(ops, &outOps);
349 }
350
351 }
352