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/EffectInput.h" 7 8 #include "bindings/v8/Dictionary.h" 9 #include "core/animation/AnimationTestHelper.h" 10 #include "core/animation/KeyframeEffectModel.h" 11 #include "core/dom/Document.h" 12 #include "core/dom/Element.h" 13 #include <gtest/gtest.h> 14 #include <v8.h> 15 16 using namespace WebCore; 17 18 namespace { 19 20 class AnimationEffectInputTest : public ::testing::Test { 21 protected: 22 AnimationEffectInputTest() 23 : document(Document::create()) 24 , element(document->createElement("foo", ASSERT_NO_EXCEPTION)) 25 , m_isolate(v8::Isolate::GetCurrent()) 26 , m_scope(m_isolate) 27 { 28 } 29 30 RefPtrWillBePersistent<Document> document; 31 RefPtrWillBePersistent<Element> element; 32 TrackExceptionState exceptionState; 33 v8::Isolate* m_isolate; 34 35 private: 36 V8TestingScope m_scope; 37 }; 38 39 TEST_F(AnimationEffectInputTest, SortedOffsets) 40 { 41 Vector<Dictionary> jsKeyframes; 42 v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate); 43 v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate); 44 45 setV8ObjectPropertyAsString(keyframe1, "width", "100px"); 46 setV8ObjectPropertyAsString(keyframe1, "offset", "0"); 47 setV8ObjectPropertyAsString(keyframe2, "width", "0px"); 48 setV8ObjectPropertyAsString(keyframe2, "offset", "1"); 49 50 jsKeyframes.append(Dictionary(keyframe1, m_isolate)); 51 jsKeyframes.append(Dictionary(keyframe2, m_isolate)); 52 53 RefPtrWillBeRawPtr<AnimationEffect> animationEffect = EffectInput::convert(element.get(), jsKeyframes, exceptionState); 54 EXPECT_FALSE(exceptionState.hadException()); 55 const KeyframeEffectModelBase& keyframeEffect = *toKeyframeEffectModelBase(animationEffect.get()); 56 EXPECT_EQ(1.0, keyframeEffect.getFrames()[1]->offset()); 57 } 58 59 TEST_F(AnimationEffectInputTest, UnsortedOffsets) 60 { 61 Vector<Dictionary> jsKeyframes; 62 v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate); 63 v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate); 64 65 setV8ObjectPropertyAsString(keyframe1, "width", "0px"); 66 setV8ObjectPropertyAsString(keyframe1, "offset", "1"); 67 setV8ObjectPropertyAsString(keyframe2, "width", "100px"); 68 setV8ObjectPropertyAsString(keyframe2, "offset", "0"); 69 70 jsKeyframes.append(Dictionary(keyframe1, m_isolate)); 71 jsKeyframes.append(Dictionary(keyframe2, m_isolate)); 72 73 RefPtrWillBeRawPtr<AnimationEffect> animationEffect = EffectInput::convert(element.get(), jsKeyframes, exceptionState); 74 EXPECT_FALSE(exceptionState.hadException()); 75 const KeyframeEffectModelBase& keyframeEffect = *toKeyframeEffectModelBase(animationEffect.get()); 76 EXPECT_EQ(1.0, keyframeEffect.getFrames()[1]->offset()); 77 } 78 79 TEST_F(AnimationEffectInputTest, LooslySorted) 80 { 81 Vector<Dictionary> jsKeyframes; 82 v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate); 83 v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate); 84 v8::Handle<v8::Object> keyframe3 = v8::Object::New(m_isolate); 85 86 setV8ObjectPropertyAsString(keyframe1, "width", "100px"); 87 setV8ObjectPropertyAsString(keyframe1, "offset", "0"); 88 setV8ObjectPropertyAsString(keyframe2, "width", "200px"); 89 setV8ObjectPropertyAsString(keyframe3, "width", "0px"); 90 setV8ObjectPropertyAsString(keyframe3, "offset", "1"); 91 92 jsKeyframes.append(Dictionary(keyframe1, m_isolate)); 93 jsKeyframes.append(Dictionary(keyframe2, m_isolate)); 94 jsKeyframes.append(Dictionary(keyframe3, m_isolate)); 95 96 RefPtrWillBeRawPtr<AnimationEffect> animationEffect = EffectInput::convert(element.get(), jsKeyframes, exceptionState); 97 EXPECT_FALSE(exceptionState.hadException()); 98 const KeyframeEffectModelBase& keyframeEffect = *toKeyframeEffectModelBase(animationEffect.get()); 99 EXPECT_EQ(1, keyframeEffect.getFrames()[2]->offset()); 100 } 101 102 TEST_F(AnimationEffectInputTest, Invalid) 103 { 104 // Not loosely sorted by offset, and there exists a keyframe with null offset. 105 Vector<Dictionary> jsKeyframes; 106 v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate); 107 v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate); 108 v8::Handle<v8::Object> keyframe3 = v8::Object::New(m_isolate); 109 110 setV8ObjectPropertyAsString(keyframe1, "width", "0px"); 111 setV8ObjectPropertyAsString(keyframe1, "offset", "1"); 112 setV8ObjectPropertyAsString(keyframe2, "width", "200px"); 113 setV8ObjectPropertyAsString(keyframe3, "width", "100px"); 114 setV8ObjectPropertyAsString(keyframe3, "offset", "0"); 115 116 jsKeyframes.append(Dictionary(keyframe1, m_isolate)); 117 jsKeyframes.append(Dictionary(keyframe2, m_isolate)); 118 jsKeyframes.append(Dictionary(keyframe3, m_isolate)); 119 120 RefPtrWillBeRawPtr<AnimationEffect> animationEffect ALLOW_UNUSED = EffectInput::convert(element.get(), jsKeyframes, exceptionState); 121 EXPECT_TRUE(exceptionState.hadException()); 122 EXPECT_EQ(InvalidModificationError, exceptionState.code()); 123 } 124 125 } 126