1f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu// Copyright 2014 The Chromium Authors. All rights reserved.
2f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu// Use of this source code is governed by a BSD-style license that can be
3f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu// found in the LICENSE file.
4f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
5f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#include "config.h"
6f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#include "core/animation/EffectInput.h"
7f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
8197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/Dictionary.h"
9f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#include "core/animation/AnimationTestHelper.h"
10f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#include "core/animation/KeyframeEffectModel.h"
11f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#include "core/dom/Document.h"
12f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#include "core/dom/Element.h"
13f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#include <gtest/gtest.h>
14f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include <v8.h>
15f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
16c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)using namespace blink;
17f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
18f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liunamespace {
19f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
20f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liuclass AnimationEffectInputTest : public ::testing::Test {
21f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liuprotected:
22f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    AnimationEffectInputTest()
23f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        : document(Document::create())
24f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        , element(document->createElement("foo", ASSERT_NO_EXCEPTION))
25f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        , m_isolate(v8::Isolate::GetCurrent())
26f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        , m_scope(m_isolate)
27f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    {
28f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    }
29f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
30f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    RefPtrWillBePersistent<Document> document;
31d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    RefPtrWillBePersistent<Element> element;
32f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    TrackExceptionState exceptionState;
33f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    v8::Isolate* m_isolate;
34f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
35f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liuprivate:
36f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    V8TestingScope m_scope;
37f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu};
38f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
39f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo LiuTEST_F(AnimationEffectInputTest, SortedOffsets)
40f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu{
41f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    Vector<Dictionary> jsKeyframes;
42f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate);
43f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate);
44f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
45f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    setV8ObjectPropertyAsString(keyframe1, "width", "100px");
46f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    setV8ObjectPropertyAsString(keyframe1, "offset", "0");
47f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    setV8ObjectPropertyAsString(keyframe2, "width", "0px");
48f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    setV8ObjectPropertyAsString(keyframe2, "offset", "1");
49f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
50f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    jsKeyframes.append(Dictionary(keyframe1, m_isolate));
51f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    jsKeyframes.append(Dictionary(keyframe2, m_isolate));
52f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
5376c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    RefPtrWillBeRawPtr<AnimationEffect> animationEffect = EffectInput::convert(element.get(), jsKeyframes, exceptionState);
54f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    EXPECT_FALSE(exceptionState.hadException());
55f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    const KeyframeEffectModelBase& keyframeEffect = *toKeyframeEffectModelBase(animationEffect.get());
56f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    EXPECT_EQ(1.0, keyframeEffect.getFrames()[1]->offset());
57f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu}
58f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
59f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo LiuTEST_F(AnimationEffectInputTest, UnsortedOffsets)
60f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu{
61f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    Vector<Dictionary> jsKeyframes;
62f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate);
63f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate);
64f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
65f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    setV8ObjectPropertyAsString(keyframe1, "width", "0px");
66f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    setV8ObjectPropertyAsString(keyframe1, "offset", "1");
67f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    setV8ObjectPropertyAsString(keyframe2, "width", "100px");
68f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    setV8ObjectPropertyAsString(keyframe2, "offset", "0");
69f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
70f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    jsKeyframes.append(Dictionary(keyframe1, m_isolate));
71f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    jsKeyframes.append(Dictionary(keyframe2, m_isolate));
72f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
73c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EffectInput::convert(element.get(), jsKeyframes, exceptionState);
74c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_TRUE(exceptionState.hadException());
75c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_EQ(InvalidModificationError, exceptionState.code());
76f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu}
77f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
78f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo LiuTEST_F(AnimationEffectInputTest, LooslySorted)
79f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu{
80f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    Vector<Dictionary> jsKeyframes;
81f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate);
82f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate);
83f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    v8::Handle<v8::Object> keyframe3 = v8::Object::New(m_isolate);
84f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
85f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    setV8ObjectPropertyAsString(keyframe1, "width", "100px");
86f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    setV8ObjectPropertyAsString(keyframe1, "offset", "0");
87f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    setV8ObjectPropertyAsString(keyframe2, "width", "200px");
88f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    setV8ObjectPropertyAsString(keyframe3, "width", "0px");
89f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    setV8ObjectPropertyAsString(keyframe3, "offset", "1");
90f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
91f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    jsKeyframes.append(Dictionary(keyframe1, m_isolate));
92f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    jsKeyframes.append(Dictionary(keyframe2, m_isolate));
93f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    jsKeyframes.append(Dictionary(keyframe3, m_isolate));
94f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
9576c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    RefPtrWillBeRawPtr<AnimationEffect> animationEffect = EffectInput::convert(element.get(), jsKeyframes, exceptionState);
96f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    EXPECT_FALSE(exceptionState.hadException());
97f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    const KeyframeEffectModelBase& keyframeEffect = *toKeyframeEffectModelBase(animationEffect.get());
98f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    EXPECT_EQ(1, keyframeEffect.getFrames()[2]->offset());
99f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu}
100f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
101c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)TEST_F(AnimationEffectInputTest, OutOfOrderWithNullOffsets)
102c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
103c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    Vector<Dictionary> jsKeyframes;
104c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate);
105c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate);
106c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    v8::Handle<v8::Object> keyframe3 = v8::Object::New(m_isolate);
107c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    v8::Handle<v8::Object> keyframe4 = v8::Object::New(m_isolate);
108c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
109c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    setV8ObjectPropertyAsString(keyframe1, "height", "100px");
110c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    setV8ObjectPropertyAsString(keyframe1, "offset", "0.5");
111c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    setV8ObjectPropertyAsString(keyframe2, "height", "150px");
112c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    setV8ObjectPropertyAsString(keyframe3, "height", "200px");
113c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    setV8ObjectPropertyAsString(keyframe3, "offset", "0");
114c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    setV8ObjectPropertyAsString(keyframe4, "height", "300px");
115c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    setV8ObjectPropertyAsString(keyframe4, "offset", "1");
116c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
117c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    jsKeyframes.append(Dictionary(keyframe1, m_isolate));
118c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    jsKeyframes.append(Dictionary(keyframe2, m_isolate));
119c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    jsKeyframes.append(Dictionary(keyframe3, m_isolate));
120c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    jsKeyframes.append(Dictionary(keyframe4, m_isolate));
121c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
122c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EffectInput::convert(element.get(), jsKeyframes, exceptionState);
123c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_TRUE(exceptionState.hadException());
124c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
125c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
126f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo LiuTEST_F(AnimationEffectInputTest, Invalid)
127f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu{
128f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    // Not loosely sorted by offset, and there exists a keyframe with null offset.
129f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    Vector<Dictionary> jsKeyframes;
130f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate);
131f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate);
132f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    v8::Handle<v8::Object> keyframe3 = v8::Object::New(m_isolate);
133f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
134f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    setV8ObjectPropertyAsString(keyframe1, "width", "0px");
135f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    setV8ObjectPropertyAsString(keyframe1, "offset", "1");
136f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    setV8ObjectPropertyAsString(keyframe2, "width", "200px");
137f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    setV8ObjectPropertyAsString(keyframe3, "width", "100px");
138f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    setV8ObjectPropertyAsString(keyframe3, "offset", "0");
139f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
140f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    jsKeyframes.append(Dictionary(keyframe1, m_isolate));
141f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    jsKeyframes.append(Dictionary(keyframe2, m_isolate));
142f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    jsKeyframes.append(Dictionary(keyframe3, m_isolate));
143f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
144c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EffectInput::convert(element.get(), jsKeyframes, exceptionState);
145f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    EXPECT_TRUE(exceptionState.hadException());
146f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    EXPECT_EQ(InvalidModificationError, exceptionState.code());
147f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu}
148f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
149f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu}
150