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/core/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 16using namespace blink; 17 18namespace { 19 20class AnimationEffectInputTest : public ::testing::Test { 21protected: 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 35private: 36 V8TestingScope m_scope; 37}; 38 39TEST_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 59TEST_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 EffectInput::convert(element.get(), jsKeyframes, exceptionState); 74 EXPECT_TRUE(exceptionState.hadException()); 75 EXPECT_EQ(InvalidModificationError, exceptionState.code()); 76} 77 78TEST_F(AnimationEffectInputTest, LooslySorted) 79{ 80 Vector<Dictionary> jsKeyframes; 81 v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate); 82 v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate); 83 v8::Handle<v8::Object> keyframe3 = v8::Object::New(m_isolate); 84 85 setV8ObjectPropertyAsString(keyframe1, "width", "100px"); 86 setV8ObjectPropertyAsString(keyframe1, "offset", "0"); 87 setV8ObjectPropertyAsString(keyframe2, "width", "200px"); 88 setV8ObjectPropertyAsString(keyframe3, "width", "0px"); 89 setV8ObjectPropertyAsString(keyframe3, "offset", "1"); 90 91 jsKeyframes.append(Dictionary(keyframe1, m_isolate)); 92 jsKeyframes.append(Dictionary(keyframe2, m_isolate)); 93 jsKeyframes.append(Dictionary(keyframe3, m_isolate)); 94 95 RefPtrWillBeRawPtr<AnimationEffect> animationEffect = EffectInput::convert(element.get(), jsKeyframes, exceptionState); 96 EXPECT_FALSE(exceptionState.hadException()); 97 const KeyframeEffectModelBase& keyframeEffect = *toKeyframeEffectModelBase(animationEffect.get()); 98 EXPECT_EQ(1, keyframeEffect.getFrames()[2]->offset()); 99} 100 101TEST_F(AnimationEffectInputTest, OutOfOrderWithNullOffsets) 102{ 103 Vector<Dictionary> jsKeyframes; 104 v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate); 105 v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate); 106 v8::Handle<v8::Object> keyframe3 = v8::Object::New(m_isolate); 107 v8::Handle<v8::Object> keyframe4 = v8::Object::New(m_isolate); 108 109 setV8ObjectPropertyAsString(keyframe1, "height", "100px"); 110 setV8ObjectPropertyAsString(keyframe1, "offset", "0.5"); 111 setV8ObjectPropertyAsString(keyframe2, "height", "150px"); 112 setV8ObjectPropertyAsString(keyframe3, "height", "200px"); 113 setV8ObjectPropertyAsString(keyframe3, "offset", "0"); 114 setV8ObjectPropertyAsString(keyframe4, "height", "300px"); 115 setV8ObjectPropertyAsString(keyframe4, "offset", "1"); 116 117 jsKeyframes.append(Dictionary(keyframe1, m_isolate)); 118 jsKeyframes.append(Dictionary(keyframe2, m_isolate)); 119 jsKeyframes.append(Dictionary(keyframe3, m_isolate)); 120 jsKeyframes.append(Dictionary(keyframe4, m_isolate)); 121 122 EffectInput::convert(element.get(), jsKeyframes, exceptionState); 123 EXPECT_TRUE(exceptionState.hadException()); 124} 125 126TEST_F(AnimationEffectInputTest, Invalid) 127{ 128 // Not loosely sorted by offset, and there exists a keyframe with null offset. 129 Vector<Dictionary> jsKeyframes; 130 v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate); 131 v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate); 132 v8::Handle<v8::Object> keyframe3 = v8::Object::New(m_isolate); 133 134 setV8ObjectPropertyAsString(keyframe1, "width", "0px"); 135 setV8ObjectPropertyAsString(keyframe1, "offset", "1"); 136 setV8ObjectPropertyAsString(keyframe2, "width", "200px"); 137 setV8ObjectPropertyAsString(keyframe3, "width", "100px"); 138 setV8ObjectPropertyAsString(keyframe3, "offset", "0"); 139 140 jsKeyframes.append(Dictionary(keyframe1, m_isolate)); 141 jsKeyframes.append(Dictionary(keyframe2, m_isolate)); 142 jsKeyframes.append(Dictionary(keyframe3, m_isolate)); 143 144 EffectInput::convert(element.get(), jsKeyframes, exceptionState); 145 EXPECT_TRUE(exceptionState.hadException()); 146 EXPECT_EQ(InvalidModificationError, exceptionState.code()); 147} 148 149} 150