TEST(AnimationTimingInputTest, TimingInputEndDelay) { V8TestingScope scope; bool ignoredSuccess; EXPECT_EQ(10, applyTimingInputNumber(scope.isolate(), "endDelay", 10000, ignoredSuccess).endDelay); EXPECT_EQ(-2.5, applyTimingInputNumber(scope.isolate(), "endDelay", -2500, ignoredSuccess).endDelay); }
TEST_F(PerformanceObserverTest, Enqueue) { V8TestingScope scope; initialize(scope.getScriptState()); Persistent<PerformanceEntry> entry = PerformanceMark::create("m", 1234); EXPECT_EQ(0, numPerformanceEntries()); m_observer->enqueuePerformanceEntry(*entry); EXPECT_EQ(1, numPerformanceEntries()); }
TEST(AnimationTimingInputTest, TimingInputIterationDuration) { V8TestingScope scope; bool success; EXPECT_EQ(1.1, applyTimingInputNumber(scope.isolate(), "duration", 1100, success).iterationDuration); EXPECT_TRUE(success); Timing timing = applyTimingInputNumber(scope.isolate(), "duration", std::numeric_limits<double>::infinity(), success); EXPECT_TRUE(success); EXPECT_TRUE(std::isinf(timing.iterationDuration)); EXPECT_GT(timing.iterationDuration, 0); EXPECT_TRUE(std::isnan(applyTimingInputString(scope.isolate(), "duration", "auto", success).iterationDuration)); EXPECT_TRUE(success); applyTimingInputString(scope.isolate(), "duration", "1000", success); EXPECT_FALSE(success); applyTimingInputNumber(scope.isolate(), "duration", -1000, success); EXPECT_FALSE(success); applyTimingInputString(scope.isolate(), "duration", "-Infinity", success); EXPECT_FALSE(success); applyTimingInputString(scope.isolate(), "duration", "NaN", success); EXPECT_FALSE(success); applyTimingInputString(scope.isolate(), "duration", "rubbish", success); EXPECT_FALSE(success); }
TEST(AnimationTimingInputTest, TimingInputPlaybackRate) { V8TestingScope scope; bool ignoredSuccess; EXPECT_EQ(2.1, applyTimingInputNumber(scope.isolate(), "playbackRate", 2.1, ignoredSuccess).playbackRate); EXPECT_EQ(-1, applyTimingInputNumber(scope.isolate(), "playbackRate", -1, ignoredSuccess).playbackRate); EXPECT_EQ(1, applyTimingInputString(scope.isolate(), "playbackRate", "Infinity", ignoredSuccess).playbackRate); EXPECT_EQ(1, applyTimingInputString(scope.isolate(), "playbackRate", "-Infinity", ignoredSuccess).playbackRate); EXPECT_EQ(1, applyTimingInputString(scope.isolate(), "playbackRate", "NaN", ignoredSuccess).playbackRate); EXPECT_EQ(1, applyTimingInputString(scope.isolate(), "playbackRate", "rubbish", ignoredSuccess).playbackRate); }
TEST_F(PerformanceObserverTest, Observe) { V8TestingScope scope; initialize(scope.getScriptState()); NonThrowableExceptionState exceptionState; PerformanceObserverInit options; Vector<String> entryTypeVec; entryTypeVec.append("mark"); options.setEntryTypes(entryTypeVec); m_observer->observe(options, exceptionState); EXPECT_TRUE(isRegistered()); }
TEST_F(PerformanceBaseTest, Register) { V8TestingScope scope; initialize(scope.getScriptState()); EXPECT_EQ(0, m_base->numObservers()); EXPECT_EQ(0, m_base->numActiveObservers()); m_base->registerPerformanceObserver(*m_observer.get()); EXPECT_EQ(1, m_base->numObservers()); EXPECT_EQ(0, m_base->numActiveObservers()); m_base->unregisterPerformanceObserver(*m_observer.get()); EXPECT_EQ(0, m_base->numObservers()); EXPECT_EQ(0, m_base->numActiveObservers()); }
TEST_F(PerformanceBaseTest, AddLongTaskTiming) { V8TestingScope scope; initialize(scope.getScriptState()); // Add a long task entry, but no observer registered. m_base->addLongTaskTiming(1234, 5678, "www.foo.com/bar", nullptr); EXPECT_FALSE(m_base->hasPerformanceObserverFor(PerformanceEntry::LongTask)); EXPECT_EQ(0, numPerformanceEntriesInObserver()); // has no effect // Make an observer for longtask NonThrowableExceptionState exceptionState; PerformanceObserverInit options; Vector<String> entryTypeVec; entryTypeVec.append("longtask"); options.setEntryTypes(entryTypeVec); m_observer->observe(options, exceptionState); EXPECT_TRUE(m_base->hasPerformanceObserverFor(PerformanceEntry::LongTask)); // Add a long task entry m_base->addLongTaskTiming(1234, 5678, "www.foo.com/bar", nullptr); EXPECT_EQ(1, numPerformanceEntriesInObserver()); // added an entry }
TEST(AnimationTimingInputTest, TimingInputFillMode) { V8TestingScope scope; Timing::FillMode defaultFillMode = Timing::FillModeAuto; bool ignoredSuccess; EXPECT_EQ(Timing::FillModeAuto, applyTimingInputString(scope.isolate(), "fill", "auto", ignoredSuccess).fillMode); EXPECT_EQ(Timing::FillModeForwards, applyTimingInputString(scope.isolate(), "fill", "forwards", ignoredSuccess).fillMode); EXPECT_EQ(Timing::FillModeNone, applyTimingInputString(scope.isolate(), "fill", "none", ignoredSuccess).fillMode); EXPECT_EQ(Timing::FillModeBackwards, applyTimingInputString(scope.isolate(), "fill", "backwards", ignoredSuccess).fillMode); EXPECT_EQ(Timing::FillModeBoth, applyTimingInputString(scope.isolate(), "fill", "both", ignoredSuccess).fillMode); EXPECT_EQ(defaultFillMode, applyTimingInputString(scope.isolate(), "fill", "everything!", ignoredSuccess).fillMode); EXPECT_EQ(defaultFillMode, applyTimingInputString(scope.isolate(), "fill", "backwardsandforwards", ignoredSuccess).fillMode); EXPECT_EQ(defaultFillMode, applyTimingInputNumber(scope.isolate(), "fill", 2, ignoredSuccess).fillMode); }
TEST(AnimationTimingInputTest, TimingInputTimingFunction) { V8TestingScope scope; const RefPtr<TimingFunction> defaultTimingFunction = LinearTimingFunction::shared(); bool success; EXPECT_EQ(*CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE), *applyTimingInputString(scope.isolate(), "easing", "ease", success).timingFunction); EXPECT_TRUE(success); EXPECT_EQ(*CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_IN), *applyTimingInputString(scope.isolate(), "easing", "ease-in", success).timingFunction); EXPECT_TRUE(success); EXPECT_EQ(*CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_OUT), *applyTimingInputString(scope.isolate(), "easing", "ease-out", success).timingFunction); EXPECT_TRUE(success); EXPECT_EQ(*CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseType::EASE_IN_OUT), *applyTimingInputString(scope.isolate(), "easing", "ease-in-out", success).timingFunction); EXPECT_TRUE(success); EXPECT_EQ(*LinearTimingFunction::shared(), *applyTimingInputString(scope.isolate(), "easing", "linear", success).timingFunction); EXPECT_TRUE(success); EXPECT_EQ(*StepsTimingFunction::preset(StepsTimingFunction::StepPosition::START), *applyTimingInputString(scope.isolate(), "easing", "step-start", success).timingFunction); EXPECT_TRUE(success); EXPECT_EQ(*StepsTimingFunction::preset(StepsTimingFunction::StepPosition::MIDDLE), *applyTimingInputString(scope.isolate(), "easing", "step-middle", success).timingFunction); EXPECT_TRUE(success); EXPECT_EQ(*StepsTimingFunction::preset(StepsTimingFunction::StepPosition::END), *applyTimingInputString(scope.isolate(), "easing", "step-end", success).timingFunction); EXPECT_TRUE(success); EXPECT_EQ(*CubicBezierTimingFunction::create(1, 1, 0.3, 0.3), *applyTimingInputString(scope.isolate(), "easing", "cubic-bezier(1, 1, 0.3, 0.3)", success).timingFunction); EXPECT_TRUE(success); EXPECT_EQ(*StepsTimingFunction::create(3, StepsTimingFunction::StepPosition::START), *applyTimingInputString(scope.isolate(), "easing", "steps(3, start)", success).timingFunction); EXPECT_TRUE(success); EXPECT_EQ(*StepsTimingFunction::create(5, StepsTimingFunction::StepPosition::MIDDLE), *applyTimingInputString(scope.isolate(), "easing", "steps(5, middle)", success).timingFunction); EXPECT_TRUE(success); EXPECT_EQ(*StepsTimingFunction::create(5, StepsTimingFunction::StepPosition::END), *applyTimingInputString(scope.isolate(), "easing", "steps(5, end)", success).timingFunction); EXPECT_TRUE(success); applyTimingInputString(scope.isolate(), "easing", "", success); EXPECT_FALSE(success); applyTimingInputString(scope.isolate(), "easing", "steps(5.6, end)", success); EXPECT_FALSE(success); applyTimingInputString(scope.isolate(), "easing", "cubic-bezier(2, 2, 0.3, 0.3)", success); EXPECT_FALSE(success); applyTimingInputString(scope.isolate(), "easing", "rubbish", success); EXPECT_FALSE(success); applyTimingInputNumber(scope.isolate(), "easing", 2, success); EXPECT_FALSE(success); applyTimingInputString(scope.isolate(), "easing", "initial", success); EXPECT_FALSE(success); }
TEST(AnimationTimingInputTest, TimingInputDirection) { V8TestingScope scope; Timing::PlaybackDirection defaultPlaybackDirection = Timing::PlaybackDirectionNormal; bool ignoredSuccess; EXPECT_EQ(Timing::PlaybackDirectionNormal, applyTimingInputString(scope.isolate(), "direction", "normal", ignoredSuccess).direction); EXPECT_EQ(Timing::PlaybackDirectionReverse, applyTimingInputString(scope.isolate(), "direction", "reverse", ignoredSuccess).direction); EXPECT_EQ(Timing::PlaybackDirectionAlternate, applyTimingInputString(scope.isolate(), "direction", "alternate", ignoredSuccess).direction); EXPECT_EQ(Timing::PlaybackDirectionAlternateReverse, applyTimingInputString(scope.isolate(), "direction", "alternate-reverse", ignoredSuccess).direction); EXPECT_EQ(defaultPlaybackDirection, applyTimingInputString(scope.isolate(), "direction", "rubbish", ignoredSuccess).direction); EXPECT_EQ(defaultPlaybackDirection, applyTimingInputNumber(scope.isolate(), "direction", 2, ignoredSuccess).direction); }
TEST(AnimationTimingInputTest, TimingInputStartDelay) { V8TestingScope scope; bool ignoredSuccess; EXPECT_EQ(1.1, applyTimingInputNumber(scope.isolate(), "delay", 1100, ignoredSuccess).startDelay); EXPECT_EQ(-1, applyTimingInputNumber(scope.isolate(), "delay", -1000, ignoredSuccess).startDelay); EXPECT_EQ(1, applyTimingInputString(scope.isolate(), "delay", "1000", ignoredSuccess).startDelay); EXPECT_EQ(0, applyTimingInputString(scope.isolate(), "delay", "1s", ignoredSuccess).startDelay); EXPECT_EQ(0, applyTimingInputString(scope.isolate(), "delay", "Infinity", ignoredSuccess).startDelay); EXPECT_EQ(0, applyTimingInputString(scope.isolate(), "delay", "-Infinity", ignoredSuccess).startDelay); EXPECT_EQ(0, applyTimingInputString(scope.isolate(), "delay", "NaN", ignoredSuccess).startDelay); EXPECT_EQ(0, applyTimingInputString(scope.isolate(), "delay", "rubbish", ignoredSuccess).startDelay); }
TEST(AnimationTimingInputTest, TimingInputIterationStart) { V8TestingScope scope; bool success; EXPECT_EQ(1.1, applyTimingInputNumber(scope.isolate(), "iterationStart", 1.1, success).iterationStart); EXPECT_TRUE(success); applyTimingInputNumber(scope.isolate(), "iterationStart", -1, success); EXPECT_FALSE(success); applyTimingInputString(scope.isolate(), "iterationStart", "Infinity", success); EXPECT_FALSE(success); applyTimingInputString(scope.isolate(), "iterationStart", "-Infinity", success); EXPECT_FALSE(success); applyTimingInputString(scope.isolate(), "iterationStart", "NaN", success); EXPECT_FALSE(success); applyTimingInputString(scope.isolate(), "iterationStart", "rubbish", success); EXPECT_FALSE(success); }
TEST(AnimationTimingInputTest, TimingInputIterationCount) { V8TestingScope scope; bool success; EXPECT_EQ(2.1, applyTimingInputNumber(scope.isolate(), "iterations", 2.1, success).iterationCount); EXPECT_TRUE(success); Timing timing = applyTimingInputString(scope.isolate(), "iterations", "Infinity", success); EXPECT_TRUE(success); EXPECT_TRUE(std::isinf(timing.iterationCount)); EXPECT_GT(timing.iterationCount, 0); applyTimingInputNumber(scope.isolate(), "iterations", -1, success); EXPECT_FALSE(success); applyTimingInputString(scope.isolate(), "iterations", "-Infinity", success); EXPECT_FALSE(success); applyTimingInputString(scope.isolate(), "iterations", "NaN", success); EXPECT_FALSE(success); applyTimingInputString(scope.isolate(), "iterations", "rubbish", success); EXPECT_FALSE(success); }
TEST(SerializedScriptValueTest, FileConstructorFile) { V8TestingScope scope; RefPtr<BlobDataHandle> blobDataHandle = BlobDataHandle::create(); File* originalFile = File::create("hello.txt", 12345678.0, blobDataHandle); ASSERT_FALSE(originalFile->hasBackingFile()); ASSERT_EQ(File::IsNotUserVisible, originalFile->getUserVisibility()); ASSERT_EQ("hello.txt", originalFile->name()); v8::Local<v8::Value> v8OriginalFile = toV8(originalFile, scope.context()->Global(), scope.isolate()); RefPtr<SerializedScriptValue> serializedScriptValue = SerializedScriptValue::serialize(scope.isolate(), v8OriginalFile, nullptr, nullptr, ASSERT_NO_EXCEPTION); v8::Local<v8::Value> v8File = serializedScriptValue->deserialize(scope.isolate()); ASSERT_TRUE(V8File::hasInstance(v8File, scope.isolate())); File* file = V8File::toImpl(v8::Local<v8::Object>::Cast(v8File)); EXPECT_FALSE(file->hasBackingFile()); EXPECT_EQ(File::IsNotUserVisible, file->getUserVisibility()); EXPECT_EQ("hello.txt", file->name()); }
TEST(SerializedScriptValueTest, UserSelectedFile) { V8TestingScope scope; String filePath = testing::blinkRootDir(); filePath.append("/Source/bindings/core/v8/SerializedScriptValueTest.cpp"); File* originalFile = File::create(filePath); ASSERT_TRUE(originalFile->hasBackingFile()); ASSERT_EQ(File::IsUserVisible, originalFile->getUserVisibility()); ASSERT_EQ(filePath, originalFile->path()); v8::Local<v8::Value> v8OriginalFile = toV8(originalFile, scope.context()->Global(), scope.isolate()); RefPtr<SerializedScriptValue> serializedScriptValue = SerializedScriptValue::serialize(scope.isolate(), v8OriginalFile, nullptr, nullptr, ASSERT_NO_EXCEPTION); v8::Local<v8::Value> v8File = serializedScriptValue->deserialize(scope.isolate()); ASSERT_TRUE(V8File::hasInstance(v8File, scope.isolate())); File* file = V8File::toImpl(v8::Local<v8::Object>::Cast(v8File)); EXPECT_TRUE(file->hasBackingFile()); EXPECT_EQ(File::IsUserVisible, file->getUserVisibility()); EXPECT_EQ(filePath, file->path()); }
TEST(AnimationEffectInputTest, LooslySorted) { V8TestingScope scope; Vector<Dictionary> jsKeyframes; v8::Local<v8::Object> keyframe1 = v8::Object::New(scope.isolate()); v8::Local<v8::Object> keyframe2 = v8::Object::New(scope.isolate()); v8::Local<v8::Object> keyframe3 = v8::Object::New(scope.isolate()); setV8ObjectPropertyAsString(scope.isolate(), keyframe1, "width", "100px"); setV8ObjectPropertyAsString(scope.isolate(), keyframe1, "offset", "0"); setV8ObjectPropertyAsString(scope.isolate(), keyframe2, "width", "200px"); setV8ObjectPropertyAsString(scope.isolate(), keyframe3, "width", "0px"); setV8ObjectPropertyAsString(scope.isolate(), keyframe3, "offset", "1"); jsKeyframes.push_back( Dictionary(scope.isolate(), keyframe1, scope.getExceptionState())); jsKeyframes.push_back( Dictionary(scope.isolate(), keyframe2, scope.getExceptionState())); jsKeyframes.push_back( Dictionary(scope.isolate(), keyframe3, scope.getExceptionState())); Element* element = appendElement(scope.document()); EffectModel* animationEffect = EffectInput::convert( element, DictionarySequenceOrDictionary::fromDictionarySequence(jsKeyframes), nullptr, scope.getExceptionState()); EXPECT_FALSE(scope.getExceptionState().hadException()); const KeyframeEffectModelBase& keyframeEffect = *toKeyframeEffectModelBase(animationEffect); EXPECT_EQ(1, keyframeEffect.getFrames()[2]->offset()); }
TEST(AnimationEffectInputTest, UnsortedOffsets) { V8TestingScope scope; Vector<Dictionary> jsKeyframes; v8::Local<v8::Object> keyframe1 = v8::Object::New(scope.isolate()); v8::Local<v8::Object> keyframe2 = v8::Object::New(scope.isolate()); setV8ObjectPropertyAsString(scope.isolate(), keyframe1, "width", "0px"); setV8ObjectPropertyAsString(scope.isolate(), keyframe1, "offset", "1"); setV8ObjectPropertyAsString(scope.isolate(), keyframe2, "width", "100px"); setV8ObjectPropertyAsString(scope.isolate(), keyframe2, "offset", "0"); jsKeyframes.push_back( Dictionary(scope.isolate(), keyframe1, scope.getExceptionState())); jsKeyframes.push_back( Dictionary(scope.isolate(), keyframe2, scope.getExceptionState())); Element* element = appendElement(scope.document()); EffectInput::convert( element, DictionarySequenceOrDictionary::fromDictionarySequence(jsKeyframes), nullptr, scope.getExceptionState()); EXPECT_TRUE(scope.getExceptionState().hadException()); EXPECT_EQ(V8TypeError, scope.getExceptionState().code()); }
TEST(AnimationEffectInputTest, OutOfOrderWithNullOffsets) { V8TestingScope scope; Vector<Dictionary> jsKeyframes; v8::Local<v8::Object> keyframe1 = v8::Object::New(scope.isolate()); v8::Local<v8::Object> keyframe2 = v8::Object::New(scope.isolate()); v8::Local<v8::Object> keyframe3 = v8::Object::New(scope.isolate()); v8::Local<v8::Object> keyframe4 = v8::Object::New(scope.isolate()); setV8ObjectPropertyAsString(scope.isolate(), keyframe1, "height", "100px"); setV8ObjectPropertyAsString(scope.isolate(), keyframe1, "offset", "0.5"); setV8ObjectPropertyAsString(scope.isolate(), keyframe2, "height", "150px"); setV8ObjectPropertyAsString(scope.isolate(), keyframe3, "height", "200px"); setV8ObjectPropertyAsString(scope.isolate(), keyframe3, "offset", "0"); setV8ObjectPropertyAsString(scope.isolate(), keyframe4, "height", "300px"); setV8ObjectPropertyAsString(scope.isolate(), keyframe4, "offset", "1"); jsKeyframes.push_back( Dictionary(scope.isolate(), keyframe1, scope.getExceptionState())); jsKeyframes.push_back( Dictionary(scope.isolate(), keyframe2, scope.getExceptionState())); jsKeyframes.push_back( Dictionary(scope.isolate(), keyframe3, scope.getExceptionState())); jsKeyframes.push_back( Dictionary(scope.isolate(), keyframe4, scope.getExceptionState())); Element* element = appendElement(scope.document()); EffectInput::convert( element, DictionarySequenceOrDictionary::fromDictionarySequence(jsKeyframes), nullptr, scope.getExceptionState()); EXPECT_TRUE(scope.getExceptionState().hadException()); }