jellyfin-web/dashboard-ui/bower_components/velocity/test/index.html
2015-09-26 10:51:26 -04:00

1565 lines
64 KiB
HTML

<!DOCTYPE HTML>
<html>
<head>
<title>Velocity.js Tests</title>
<link rel="stylesheet" href="qunit-1.14.0.css" type="text/css" media="screen" />
<script type="text/javascript" src="qunit-1.14.0.js"></script>
<script type="text/javascript" src="jquery-1.4.3.js"></script>
<script type="text/javascript" src="when.js"></script>
<script type="text/javascript" no="zepto.js"></script>
<script type="text/javascript" src="../velocity.js"></script>
<script type="text/javascript" src="../velocity.ui.js"></script>
<style>
#details {
margin: 0 auto;
margin-bottom: 1em;
width: 800px;
padding: 0;
line-height: 1.35em;
list-style: none;
}
</style>
</head>
<body>
<ul id="details">
<li>
Unit tests: <i><b>current document</b>.</i>
</li>
<li>
Performance tests: <i>See <b>Performance</b> pane in <a href="../../index.html#performance">docs</a>.</i>
</li>
<li>
Property support tests: <i>Run the Property Support pane's <a href="../../index.html#propertiesTest">auto-cycler</a>.</i>
</li>
<li>
Visual tests: <i>See <a href="../../demo.html"><b>demo</b></a>. Read demo's source for intended behavior.</i>
</li>
</ul>
<div id="qunit"></div>
<div id="qunit-stage"></div>
<script>
// Needed tests:
// - new stop behvaior
// - e/p/o shorthands
/*********************
Helper Functions
*********************/
/* IE detection: https://gist.github.com/julianshapiro/9098609 */
var IE = (function() {
if (document.documentMode) {
return document.documentMode;
} else {
for (var i = 7; i > 0; i--) {
var div = document.createElement("div");
div.innerHTML = "<!--[if IE " + i + "]><span></span><![endif]-->";
if (div.getElementsByTagName("span").length) {
div = null;
return i;
}
div = null;
}
}
return undefined;
})();
var isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
var isAndroid = /Android/i.test(navigator.userAgent);
function applyStartValues (element, startValues) {
Velocity.Utilities.each(startValues, function(property, startValue) {
element.style[property] = startValue;
});
}
/*********************
IE<=7 Reversion
*********************/
if (IE <= 7 && $.fn.velocity) {
alert("Velocity wasn't reverted to jQuery's $.animate() for IE<=7.");
}
/*******************
jQuery Shim
*******************/
var $ = (window.jQuery || window.Zepto);
Data = function(element) {
return Velocity.Utilities.data(element, "velocity");
}
if ($ && $.Velocity) {
window.Velocity = $.Velocity;
}
/*******************
Setup: Targets
*******************/
var $qunitStage = document.getElementById("qunit-stage");
var targetsFragment = document.createDocumentFragment(),
targetsIndex = 0,
$targets,
$targetSet,
defaultStyles = {
opacity: 1,
width: 1,
height: 1,
marginBottom: 1,
colorGreen: 200
};
for (var i = 0; i < 100; i++) {
var div = document.createElement("div");
div.className = "target";
div.style.opacity = defaultStyles.opacity;
div.style.color = "rgb(125, " + defaultStyles.colorGreen + ", 125)";
div.style.width = defaultStyles.width + "px";
div.style.height = defaultStyles.height + "px";
div.style.marginBottom = defaultStyles.marginBottom + "px";
div.style.textShadow = "0px 0px " + defaultStyles.textShadowBlur + "px red";
targetsFragment.appendChild(div);
div = null;
}
$qunitStage.appendChild(targetsFragment);
$targets = $qunitStage.querySelectorAll(".target");
function getTarget () {
var newTarget = $targets[targetsIndex++];
return newTarget;
}
/********************
Setup: Settings
********************/
var pluginName = "velocity",
defaultProperties = {
opacity: defaultStyles.opacity / 2,
width: defaultStyles.width * 2,
height: defaultStyles.height * 2,
colorGreen: defaultStyles.colorGreen / 2
},
defaultOptions = {
queue: "",
duration: 300,
easing: "swing",
begin: null,
complete: null,
progress: null,
display: null,
loop: false,
delay: false,
mobileHA: true,
_cacheValues: true
},
asyncCheckDuration = defaultOptions.duration / 2,
completeCheckDuration = defaultOptions.duration * 2
Velocity.defaults = defaultOptions;
/****************
Arguments
****************/
QUnit.test("Arguments", function() {
var testComplete = function() { /* Do nothing */ },
testDuration = 1000,
testEasing = "easeInSine",
testOptions = {
queue: defaultOptions.queue,
duration: testDuration,
easing: testEasing,
begin: null,
complete: testComplete,
progress: null,
display: "block",
loop: false,
delay: false,
mobileHA: false,
_cacheValues: defaultOptions._cacheValues
};
/**********************
Invalid Arguments
**********************/
var $target1 = getTarget();
/* No arguments: Ensure an error isn't thrown and that the $targeted elements are returned to the chain. */
Velocity();
Velocity($target1);
Velocity($target1, {});
Velocity($target1, {}, testDuration);
/* Invalid arguments: Ensure an error isn't thrown. */
Velocity($target1, "fakeArg1", "fakeArg2");
/****************
Overloading
****************/
var $target3 = getTarget();
Velocity($target3, defaultProperties, testDuration);
equal(Data($target3, pluginName).opts.duration, testDuration, "Overload variation #2.");
var $target4 = getTarget();
Velocity($target4, defaultProperties, testEasing);
equal(Data($target4, pluginName).opts.easing, testEasing, "Overload variation #3.");
var $target5 = getTarget();
Velocity($target5, defaultProperties, testComplete);
equal(Data($target5, pluginName).opts.complete, testComplete, "Overload variation #4.");
var $target6 = getTarget();
Velocity($target6, defaultProperties, testDuration, [ 0.42, 0, 0.58, 1 ]);
equal(Data($target6, pluginName).opts.duration, testDuration, "Overload variation #5a.");
equal(Data($target6, pluginName).opts.easing(0.2), 0.0816598562658975, "Overload variation #5b.");
var $target7 = getTarget();
Velocity($target7, defaultProperties, testDuration, testComplete);
equal(Data($target7, pluginName).opts.duration, testDuration, "Overload variation #6a.");
equal(Data($target7, pluginName).opts.complete, testComplete, "Overload variation #6b.");
var $target8 = getTarget();
Velocity($target8, defaultProperties, testDuration, testEasing, testComplete);
equal(Data($target8, pluginName).opts.duration, testDuration, "Overload variation #7a.");
equal(Data($target8, pluginName).opts.easing, testEasing, "Overload variation #7b.");
equal(Data($target8, pluginName).opts.complete, testComplete, "Overload variation #7c.");
var $target9 = getTarget();
Velocity($target9, defaultProperties, testOptions);
deepEqual(Data($target9, pluginName).opts, testOptions, "Overload variation #8: options object.");
var $target10 = getTarget();
Velocity({ elements: $target10, properties: defaultProperties, options: testOptions });
deepEqual(Data($target10, pluginName).opts, testOptions, "Overload variation #9: single object w/ map.");
var $target11 = getTarget();
Velocity({ elements: $target11, properties: "fadeOut", options: testOptions });
strictEqual(Data($target11, pluginName).tweensContainer.opacity.endValue, 0, "Overload variation #9: single object w/ redirect.");
var $target12 = getTarget();
Velocity($target12, { opacity: [ 0.75, "spring", 0.25 ]}, testDuration);
equal(Data($target12, pluginName).tweensContainer.opacity.startValue, 0.25, "Overload variation #10a.");
equal(Data($target12, pluginName).tweensContainer.opacity.easing, "spring", "Overload variation #10b.");
equal(Data($target12, pluginName).tweensContainer.opacity.endValue, 0.75, "Overload variation #10c.");
var $target13 = getTarget();
Velocity($target13, { opacity: [ 0.75, 0.25 ]}, testDuration);
equal(Data($target13, pluginName).tweensContainer.opacity.startValue, 0.25, "Overload variation #11a.");
equal(Data($target13, pluginName).tweensContainer.opacity.endValue, 0.75, "Overload variation #11b.");
var $target14 = getTarget();
Velocity($target14, { opacity: [ 0.75, "spring" ]}, testDuration);
equal(Data($target14, pluginName).tweensContainer.opacity.endValue, 0.75, "Overload variation #12a.");
equal(Data($target14, pluginName).tweensContainer.opacity.easing, "spring", "Overload variation #12b.");
var $target15 = getTarget();
Velocity($target15, defaultProperties, "fast", testEasing);
equal(Data($target15, pluginName).opts.duration, 200, "Overload variation #13a.");
var $target16 = getTarget();
Velocity($target16, defaultProperties, "normal");
equal(Data($target16, pluginName).opts.duration, 400, "Overload variation #13b.");
if ($) {
var $target17 = getTarget();
$($target17).velocity(defaultProperties, testOptions);
deepEqual(Data($target17, pluginName).opts, testOptions, "$.fn.: Utility function variation #1: options object.");
var $target18 = getTarget();
$($target18).velocity({ properties: defaultProperties, options: testOptions });
deepEqual(Data($target18, pluginName).opts, testOptions, "$.fn.: Utility function variation #2: single object.");
var $target19 = getTarget();
$($target19).velocity(defaultProperties, testDuration, testEasing, testComplete);
equal(Data($target19, pluginName).opts.duration, testDuration, "$.fn.: Utility function variation #2a.");
equal(Data($target19, pluginName).opts.easing, testEasing, "$.fn.: Utility function variation #2b.");
equal(Data($target19, pluginName).opts.complete, testComplete, "$.fn.: Utility function variation #2c.");
var $target20 = getTarget();
deepEqual($($target20), $($target20).velocity(defaultProperties, testDuration, testEasing, testComplete).velocity(defaultProperties, testDuration, testEasing, testComplete), "$.fn.: Elements passed back to the call stack.");
}
});
/******************
CSS Object
******************/
/* Note: We don't bother checking all of the GET/SET-related CSS object's functions, as most are repeatedly tested indirectly via the other tests. */
QUnit.test("CSS Object", function() {
var CSS = Velocity.CSS;
var testHookRoot = "boxShadow",
testHookRootValue = IE >=9 ? "1px 2px 3px 4px black" : "black 1px 2px 3px 4px",
testHook = "boxShadowY",
testHookValueExtracted = "2px",
testHookValueInject = "10px",
testHookRootValueInjected = "1px 10px 3px 4px"
/* Hooks manipulation. */
equal(CSS.Hooks.getRoot(testHook), testHookRoot, "Hooks.getRoot() returned root.");
/* Hooks have no effect if they're unsupported (which is the case for our hooks on <=IE8), thus we just ensure that errors aren't thrown. */
if (IE <=8) {
CSS.Hooks.extractValue(testHook, testHookRootValue);
CSS.Hooks.injectValue(testHook, testHookValueInject, testHookRootValue)
} else {
equal(CSS.Hooks.extractValue(testHook, testHookRootValue), testHookValueExtracted, "Hooks.extractValue() returned value #1.");
/* Check for a match anywhere in the string since browser differ in where they inject the color value. */
equal(CSS.Hooks.injectValue(testHook, testHookValueInject, testHookRootValue).indexOf(testHookRootValueInjected) != -1, true, "Hooks.extractValue() returned value #2.");
}
/* Varied start color formats. Ensure that all variations of red output contain the same color copmonents when Normalized: "255 0 0". */
var redVariations = [
"rgb(255, 0, 0)",
"rgba(255,0,0,0.5)",
"#ff0000",
"red"
];
Velocity.Utilities.each(redVariations, function(i, redVariation) {
equal(/255 0 0/.test(CSS.Normalizations.registered["color"]("extract", null, redVariation)), true, "Normalizations.extractValue() returned red color variation #" + i + ".");
});
var testPropertyFake = "fakeProperty";
/* Property name functions. */
equal(CSS.Names.prefixCheck(testPropertyFake)[0], testPropertyFake, "Names.prefixCheck() returned unmatched property untouched.");
equal(CSS.Names.prefixCheck(testPropertyFake)[1], false, "Names.prefixCheck() indicated that unmatched property waws unmatched.");
equal(CSS.Values.isCSSNullValue("rgba(0,0,0,0)"), true, "Values.isCSSNullValue() matched null value #1.");
equal(CSS.Values.isCSSNullValue("none"), true, "Values.isCSSNullValue() matched null value #2.");
equal(CSS.Values.isCSSNullValue(10), false, "Values.isCSSNullValue() didn't match non-null value.");
var testUnitProperty1 = "rotateZ",
testUnitPropertyUnit1 = "deg",
testUnitProperty2 = "width",
testUnitPropertyUnit2 = "px",
testElementType1 = document.createElement("div"),
testElementTypeDisplay1 = "block",
testElementType2 = document.createElement("span"),
testElementTypeDisplay2 = "inline";
/* CSS value functions. */
equal(CSS.Values.getUnitType(testUnitProperty1), testUnitPropertyUnit1, "Unit type #1 was retrieved.");
equal(CSS.Values.getUnitType(testUnitProperty2), testUnitPropertyUnit2, "Unit type #2 was retrieved.");
/* Class addition/removal. */
var $target1 = getTarget();
$target1.className = "";
CSS.Values.addClass($target1, "one");
equal($target1.className, "one", "First class was added.");
CSS.Values.addClass($target1, "two");
equal($target1.className, "one two", "Second class was added.");
CSS.Values.removeClass($target1, "two");
equal($target1.className.replace(/^\s+|\s+$/g, ""), "one", "Second class was removed.");
CSS.Values.removeClass($target1, "one");
equal($target1.className.replace(/^\s+|\s+$/g, ""), "", "First class was removed.");
});
/****************************
Start Value Calculation
****************************/
QUnit.test("Start Value Calculation", function() {
var testStartValues = { paddingLeft: "10px", height: "100px", paddingRight: "50%", marginLeft: "100px", marginBottom: "33%", marginTop: "100px", lineHeight: "30px", wordSpacing: "40px", backgroundColorRed: "123" };
/* Properties not previously defined on the element. */
var $target1 = getTarget();
Velocity($target1, testStartValues)
equal(Data($target1, pluginName).tweensContainer.paddingLeft.startValue, 0, "Undefined standard start value was calculated.");
equal(Data($target1, pluginName).tweensContainer.backgroundColorRed.startValue, 255, "Undefined start value hook was calculated.");
/* Properties previously defined on the element. */
var $target2 = getTarget();
Velocity($target2, defaultProperties)
equal(Data($target2, pluginName).tweensContainer.width.startValue, parseFloat(defaultStyles.width), "Defined start value #1 was calculated.");
equal(Data($target2, pluginName).tweensContainer.opacity.startValue, parseFloat(defaultStyles.opacity), "Defined start value #2 was calculated.");
equal(Data($target2, pluginName).tweensContainer.colorGreen.startValue, parseFloat(defaultStyles.colorGreen), "Defined hooked start value was calculated.");
/* Properties that shouldn't cause start values to be unit-converted. */
var testPropertiesEndNoConvert = { paddingLeft: "20px", height: "40px", paddingRight: "75%" };
var $target3 = getTarget();
applyStartValues($target3, testStartValues);
Velocity($target3, testPropertiesEndNoConvert);
equal(Data($target3, pluginName).tweensContainer.paddingLeft.startValue, parseFloat(testStartValues.paddingLeft), "Start value #1 wasn't unit converted.");
equal(Data($target3, pluginName).tweensContainer.height.startValue, parseFloat(testStartValues.height), "Start value #2 wasn't unit converted.");
equal(Data($target3, pluginName).tweensContainer.paddingRight.startValue, parseFloat(testStartValues.paddingRight), "Start value #3 wasn't unit converted.");
/* Properties that should cause start values to be unit-converted. */
var testPropertiesEndConvert = { paddingLeft: "20%", height: "40%", lineHeight: "0.5em", wordSpacing: "2rem", marginLeft: "10vw", marginTop: "5vh", marginBottom: "100px" };
parentWidth = $qunitStage.clientWidth,
parentHeight = $qunitStage.clientHeight,
parentFontSize = Velocity.CSS.getPropertyValue($qunitStage, "fontSize"),
remSize = parseFloat(Velocity.CSS.getPropertyValue(document.body, "fontSize"));
var $target4 = getTarget();
applyStartValues($target4, testStartValues);
Velocity($target4, testPropertiesEndConvert);
/* Long decimal results can be returned after unit conversion, and Velocity's code and the code here can differ in precision. So, we round floor values before comparison. */
equal(Math.floor(Data($target4, pluginName).tweensContainer.paddingLeft.startValue), Math.floor((parseFloat(testStartValues.paddingLeft) / parentWidth) * 100), "Horizontal property converted to %.");
equal(Math.floor(Data($target4, pluginName).tweensContainer.height.startValue), Math.floor((parseFloat(testStartValues.height) / parentHeight) * 100), "Vertical property converted to %.");
equal(Math.floor(Data($target4, pluginName).tweensContainer.lineHeight.startValue), Math.floor(parseFloat(testStartValues.lineHeight) / parseFloat(parentFontSize)), "Property converted to em.");
equal(Math.floor(Data($target4, pluginName).tweensContainer.wordSpacing.startValue), Math.floor(parseFloat(testStartValues.wordSpacing) / parseFloat(remSize)), "Property converted to rem.");
equal(Math.floor(Data($target4, pluginName).tweensContainer.marginBottom.startValue), parseFloat(testStartValues.marginBottom) / 100 * parseFloat($target4.parentNode.offsetWidth), "Property converted to px.");
if (!(IE<=8) && !isAndroid) {
equal(Math.floor(Data($target4, pluginName).tweensContainer.marginLeft.startValue), Math.floor(parseFloat(testStartValues.marginLeft) / window.innerWidth * 100), "Horizontal property converted to vw.");
equal(Math.floor(Data($target4, pluginName).tweensContainer.marginTop.startValue), Math.floor(parseFloat(testStartValues.marginTop) / window.innerHeight * 100), "Vertical property converted to vh.");
}
/* jQuery TRBL deferring. */
var testPropertiesTRBL = { left: "1000px" };
var $TRBLContainer = document.createElement("div");
$TRBLContainer.setAttribute("id", "TRBLContainer");
$TRBLContainer.style.marginLeft = testPropertiesTRBL.left;
$TRBLContainer.style.width = "100px";
$TRBLContainer.style.height = "100px";
document.body.appendChild($TRBLContainer);
var $target5 = getTarget();
$target5.style.position = "absolute";
$TRBLContainer.appendChild($target5);
Velocity($target5, testPropertiesTRBL);
equal(Math.round(Data($target5, pluginName).tweensContainer.left.startValue), Math.round(parseFloat(testPropertiesTRBL.left) + parseFloat(Velocity.CSS.getPropertyValue(document.body, "marginLeft"))), "TRBL value was deferred to jQuery.");
});
/**************************
End Value Calculation
**************************/
QUnit.asyncTest("End Value Calculation", function() {
/* Standard properties without operators. */
var $target1 = getTarget();
Velocity($target1, defaultProperties);
setTimeout(function() {
equal(Data($target1, pluginName).tweensContainer.width.endValue, defaultProperties.width, "Standard end value #1 was calculated.");
equal(Data($target1, pluginName).tweensContainer.opacity.endValue, defaultProperties.opacity, "Standard end value #2 was calculated.");
}, asyncCheckDuration);
/* Standard properties with operators. */
var testIncrementWidth = "5px",
testDecrementOpacity = 0.25,
testMultiplyMarginBottom = 4,
testDivideHeight = 2;
var $target2 = getTarget();
Velocity($target2, { width: "+=" + testIncrementWidth, opacity: "-=" + testDecrementOpacity, marginBottom: "*=" + testMultiplyMarginBottom, height: "/=" + testDivideHeight });
setTimeout(function() {
equal(Data($target2, pluginName).tweensContainer.width.endValue, defaultStyles.width + parseFloat(testIncrementWidth), "Incremented end value was calculated.");
equal(Data($target2, pluginName).tweensContainer.opacity.endValue, defaultStyles.opacity - testDecrementOpacity, "Decremented end value was calculated.");
equal(Data($target2, pluginName).tweensContainer.marginBottom.endValue, defaultStyles.marginBottom * testMultiplyMarginBottom, "Multiplied end value was calculated.");
equal(Data($target2, pluginName).tweensContainer.height.endValue, defaultStyles.height / testDivideHeight, "Divided end value was calculated.");
start();
}, asyncCheckDuration);
});
/**********************
End Value Setting
**********************/
QUnit.asyncTest("End Value Setting (Note: Browser Tab Must Have Focus Due to rAF)", function() {
/* Transforms and the properties that are hooked by Velocity aren't supported below IE9. */
if (!(IE < 9)) {
var testHooks = {
boxShadowBlur: "10px", // "black 0px 0px 10px 0px"
boxShadowSpread: "20px", // "black 0px 0px 0px 20px"
textShadowBlur: "30px" // "black 0px 0px 30px"
};
/* Hooks. */
var $target3 = getTarget();
Velocity($target3, testHooks);
setTimeout(function() {
/* Check for a match anywhere in the string since browser differ in where they inject the color value. */
equal(/0px 0px 10px 20px/.test(Velocity.CSS.getPropertyValue($target3, "boxShadow")), true, "Hook end value #1 was set.");
/* textShadow isn't supported below IE10. */
if (!IE || IE >= 10) {
equal(/0px 0px 30px/.test(Velocity.CSS.getPropertyValue($target3, "textShadow")), true, "Hook end value #2 was set.");
}
}, completeCheckDuration);
if (!(IE < 10) && !Velocity.State.isGingerbread) {
var testTransforms = {
translateY: "10em", // Should stay the same
translateX: "20px", // Should stay the same
scaleX: "1.50", // Should remain unitless
translateZ: "30", // Should become "10px"
scaleY: "1.50deg" // Should be ignored entirely since it uses an invalid unit
},
testTransformsOutput = "matrix3d(1.5, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 20, 160, 30, 1)";
/* Transforms. */
var $target4 = getTarget();
Velocity($target4, testTransforms);
setTimeout(function() {
/* Check for a match anywhere in the string since browser differ in where they inject the color value. */
equal(Velocity.CSS.getPropertyValue($target4, "transform"), testTransformsOutput, "Transform end value was set.");
/* Ensure previous transform values are reused. */
Velocity($target4, { translateX: parseFloat(testTransforms.translateX) / 2 });
equal(Data($target4, pluginName).tweensContainer.translateX.startValue, parseFloat(testTransforms.translateX), "Previous transform value was reused.");
}, completeCheckDuration);
}
if (!Velocity.State.isGingerbread) {
/* SVG. */
var $svgRoot = document.createElementNS("http://www.w3.org/2000/svg", "svg"),
$svgRect = document.createElementNS("http://www.w3.org/2000/svg", "rect"),
svgStartValues = { x: 100, y: 10, width: 250, height: "30%" },
svgEndValues = { x: 200, width: "50%", strokeDasharray: 10, height: "40%", rotateZ: "90deg", rotateX: "45deg" };
$svgRoot.setAttribute("width", 1000);
$svgRoot.setAttribute("height", 1000);
$svgRect.setAttribute("x", svgStartValues.x);
$svgRect.setAttribute("y", svgStartValues.y);
$svgRect.setAttribute("width", svgStartValues.width);
$svgRect.setAttribute("height", svgStartValues.height);
$svgRoot.appendChild($svgRect);
$qunitStage.appendChild($svgRoot);
Velocity($svgRect, svgEndValues, defaultOptions);
setTimeout(function() {
equal(Math.round(Data($svgRect, pluginName).tweensContainer.x.startValue), svgStartValues.x, "SVG dimensional attribute #1 value was retrieved.");
equal(Math.round(parseFloat(Velocity.CSS.getPropertyValue($svgRect, "x"))), svgEndValues.x, "SVG dimensional attribute #1 end value was set.");
equal(Math.round(Data($svgRect, pluginName).tweensContainer.width.startValue), parseFloat(svgStartValues.width)/1000 * 100, "SVG dimensional attribute #2 value was retrieved.");
equal(Math.round(parseFloat(Velocity.CSS.getPropertyValue($svgRect, "width"))), parseFloat(svgEndValues.width)/100 * 1000, "SVG dimensional attribute #2 end value was set.");
equal(Math.round(Data($svgRect, pluginName).tweensContainer.height.startValue), parseFloat(svgStartValues.height), "SVG dimensional attribute #3 value was retrieved.");
equal(Math.round(parseFloat(Velocity.CSS.getPropertyValue($svgRect, "height"))), parseFloat(svgEndValues.height)/100 * 1000, "SVG dimensional attribute #3 end value was set.");
equal(Math.round(Data($svgRect, pluginName).tweensContainer.rotateZ.startValue), 0, "SVG 2D transform value was retrieved.");
equal(Math.round(parseFloat(Velocity.CSS.getPropertyValue($svgRect, "rotateZ"))), parseFloat(svgEndValues.rotateZ), "SVG 2D transform end value was set.");
if (!IE) {
equal(Math.round(Data($svgRect, pluginName).tweensContainer.rotateX.startValue), 0, "SVG 3D transform value was retrieved.");
equal(Math.round(parseFloat(Velocity.CSS.getPropertyValue($svgRect, "rotateX"))), parseFloat(svgEndValues.rotateX), "SVG 3D transform end value was set.");
}
equal(Math.round(Data($svgRect, pluginName).tweensContainer.strokeDasharray.startValue), 0, "SVG CSS style value was retrieved.");
equal(parseFloat(Velocity.CSS.getPropertyValue($svgRect, "strokeDasharray")), svgEndValues.strokeDasharray, "SVG CSS style end value was set.");
}, completeCheckDuration);
}
}
/* Standard properties. */
var $target1 = getTarget();
Velocity($target1, defaultProperties, { });
setTimeout(function() {
equal(parseFloat(Velocity.CSS.getPropertyValue($target1, "width")), defaultProperties.width, "Standard end value #1 was set.");
equal(parseFloat(Velocity.CSS.getPropertyValue($target1, "opacity")), defaultProperties.opacity, "Standard end value #2 was set.");
start();
}, completeCheckDuration);
});
/**********************
End Value Caching
**********************/
QUnit.asyncTest("End Value Caching", function() {
expect(4);
var newProperties = { height: "50px", width: "250px" };
var $target1 = getTarget();
Velocity($target1, defaultProperties, function() {
applyStartValues($target1, newProperties);
/* Called after the last call is complete (stale). Ensure that the newly-set (via $.css()) properties are used. */
Velocity($target1, defaultProperties);
setTimeout(function() {
equal(Data($target1, pluginName).tweensContainer.width.startValue, parseFloat(newProperties.width), "Stale end value #1 wasn't pulled.");
equal(Data($target1, pluginName).tweensContainer.height.startValue, parseFloat(newProperties.height), "Stale end value #2 wasn't pulled.");
}, asyncCheckDuration);
});
var $target2 = getTarget();
Velocity($target2, defaultProperties);
Velocity($target2, newProperties, function() {
/* Chained onto a previous call (fresh). */
equal(Data($target2, pluginName).tweensContainer.width.startValue, defaultProperties.width, "Chained end value #1 was pulled.");
equal(Data($target2, pluginName).tweensContainer.height.startValue, defaultProperties.height, "Chained end value #2 was pulled.");
start();
});
});
/****************
Queueing
****************/
QUnit.asyncTest("Queueing", function() {
expect(1);
var $target1 = getTarget();
Velocity($target1, { opacity: 0 });
Velocity($target1, { width: 2 });
setTimeout(function() {
/* Ensure that the second call hasn't started yet. */
equal(parseFloat(Velocity.CSS.getPropertyValue($target1, "width")), defaultStyles.width, "Queued calls chain.");
start();
}, asyncCheckDuration);
});
/******************
Option: Queue
******************/
QUnit.asyncTest("Option: Queue", function() {
expect(5);
var testQueue = "custom";
var $target1 = getTarget();
Velocity($target1, defaultProperties, { queue: testQueue });
Velocity($target1, defaultProperties, { queue: testQueue });
Velocity($target1, defaultProperties, { queue: testQueue });
equal(Velocity.Utilities.queue($target1, testQueue).length, 3, "Custom queue was appended to.");
equal(Data($target1, pluginName).isAnimating, false, "Custom queue didn't auto-dequeue.");
Velocity.Utilities.dequeue($target1, testQueue);
equal(Data($target1, pluginName).isAnimating, true, "Dequeue custom queue.");
Velocity($target1, "stop", testQueue);
equal(Velocity.Utilities.queue($target1, testQueue).length, 0, "Stopped custom queue.");
var $target2 = getTarget();
Velocity($target2, { opacity: 0 });
Velocity($target2, { width: 10 }, { queue: false });
setTimeout(function() {
/* Ensure that the second call starts immediately. */
notEqual(Velocity.CSS.getPropertyValue($target2, "width"), defaultStyles.width, "Parallel calls don't queue.");
start();
}, asyncCheckDuration);
});
/* Helpful redirect for testing custom and parallel queues. */
// var $div2 = $("#DataBody-PropertiesDummy");
// $.fn.velocity.defaults.duration = 1000;
// $div2.velocity("scroll", { queue: "test" })
// $div2.velocity({width: 100}, { queue: "test" })
// $div2.velocity({ borderWidth: 50 }, { queue: "test" })
// $div2.velocity({height: 20}, { queue: "test" })
// $div2.velocity({marginLeft: 200}, { queue: "test" })
// $div2.velocity({paddingTop: 60});
// $div2.velocity({marginTop: 100});
// $div2.velocity({paddingRight: 40});
// $div2.velocity({marginTop: 0})
// $div2.dequeue("test")
/******************
Option: Delay
******************/
QUnit.asyncTest("Option: Delay (Note: Browser Tab Must Have Focus Due to rAF)", function() {
expect(2);
var testDelay = defaultOptions.duration * 2;
var $target = getTarget();
Velocity($target, defaultProperties, { delay: testDelay });
setTimeout(function() {
equal(parseFloat(Velocity.CSS.getPropertyValue($target, "width")), defaultStyles.width, "Delayed calls don't start immediately");
}, asyncCheckDuration);
setTimeout(function() {
equal(parseFloat(Velocity.CSS.getPropertyValue($target, "width")), defaultProperties.width, "Delayed calls eventually start.");
start();
}, completeCheckDuration + testDelay);
});
/********************
Option: Easing
********************/
QUnit.asyncTest("Option: Easing", function() {
expect(5);
var $target1 = getTarget();
/* Ensure that a fake easing doesn't throw an error. */
Velocity($target1, defaultProperties, { easing: "fake" });
equal(true, true, "Fake easing didn't throw error.");
/* Ensure that an improperly-formmated bezier curve array doesn't throw an error. */
var $target2 = getTarget();
Velocity($target2, defaultProperties, { easing: [ "a", 0.5, 0.5, 0.5 ] });
Velocity($target2, defaultProperties, { easing: [ 0.5, 0.5, 0.5 ] });
equal(true, true, "Invalid bezier curve didn't throw error.");
/* Ensure that a properly-formatted bezier curve array returns a bezier function. */
var $target3 = getTarget();
var easingBezierArray = [ 0.27, -0.65, 0.78, 0.19 ],
easingBezierTestPercent = 0.25,
easingBezierTestValue = /^-0\.23/;
Velocity($target3, defaultProperties, { easing: easingBezierArray });
setTimeout(function() {
equal(easingBezierTestValue.test(Data($target3, pluginName).tweensContainer.width.easing(easingBezierTestPercent)), true, "Array converted into bezier function.");
}, asyncCheckDuration);
/* Ensure that a properly-formatted spring RK4 array returns a bezier function. */
var $target4 = getTarget();
var easingSpringRK4Array = [ 250, 12 ],
easingSpringRK4TestPercent = 0.25,
easingSpringRK4TestValue = /^1\.21/;
Velocity($target4, defaultProperties, { easing: easingSpringRK4Array });
setTimeout(function() {
equal(easingSpringRK4TestValue.test(Data($target4, pluginName).tweensContainer.width.easing(easingSpringRK4TestPercent)), true, "Array converted into springRK4 function.");
}, asyncCheckDuration);
/* Ensure that a properly-formatted step easing array returns a step function. */
var $target5 = getTarget();
var easingStepArray = [ 4 ],
easingStepTestPercent = 0.35,
easingStepTestValue = /^0\.25/;
Velocity($target5, defaultProperties, { easing: easingStepArray });
setTimeout(function() {
equal(easingStepTestValue.test(Data($target5, pluginName).tweensContainer.width.easing(easingStepTestPercent)), true, "Array converted into Step function.");
start();
}, asyncCheckDuration);
});
/********************
Option: Display
********************/
QUnit.asyncTest("Option: Display", function() {
var testDisplayBlock = "block",
testDisplayNone = "none",
testDisplayBlank = "";
var $target1 = getTarget();
/* Async checks are used since the display property is set inside processCallsTick(). */
Velocity($target1, defaultProperties, { display: testDisplayBlock });
setTimeout(function() {
equal(Velocity.CSS.getPropertyValue($target1, "display"), testDisplayBlock, "Display:'block' was set immediately.");
}, asyncCheckDuration);
var $target2 = getTarget();
Velocity($target2, defaultProperties, { display: testDisplayNone });
setTimeout(function() {
notEqual(Velocity.CSS.getPropertyValue($target2, "display"), 0, "Display:'none' was not set immediately.");
}, asyncCheckDuration);
setTimeout(function() {
equal(Velocity.CSS.getPropertyValue($target2, "display"), 0, "Display:'none' was set upon completion.");
}, completeCheckDuration);
var $target3 = getTarget();
Velocity($target3, defaultProperties, { display: testDisplayBlank });
setTimeout(function() {
equal(Velocity.CSS.getPropertyValue($target3, "display"), "block", "Display:'' was set immediately.");
start();
}, completeCheckDuration);
});
/***********************
Option: Visibility
***********************/
QUnit.asyncTest("Option: Visibility", function() {
var testVisibilityBlock = "visible",
testVisibilityNone = "hidden",
testVisibilityBlank = "";
var $target1 = getTarget();
/* Async checks are used since the visibility property is set inside processCallsTick(). */
Velocity($target1, defaultProperties, { visibility: testVisibilityBlock });
setTimeout(function() {
equal(Velocity.CSS.getPropertyValue($target1, "visibility"), testVisibilityBlock, "visibility:'visible' was set immediately.");
}, asyncCheckDuration);
var $target2 = getTarget();
Velocity($target2, defaultProperties, { visibility: testVisibilityNone });
setTimeout(function() {
notEqual(Velocity.CSS.getPropertyValue($target2, "visibility"), 0, "visibility:'hidden' was not set immediately.");
}, asyncCheckDuration);
setTimeout(function() {
equal(Velocity.CSS.getPropertyValue($target2, "visibility"), "hidden", "visibility:'hidden' was set upon completion.");
}, completeCheckDuration);
var $target3 = getTarget();
Velocity($target3, defaultProperties, { display: testVisibilityBlank });
setTimeout(function() {
equal(/visible|inherit/.test(Velocity.CSS.getPropertyValue($target3, "visibility")), true, "visibility:'' was set immediately.");
start();
}, completeCheckDuration);
});
/******************
Option: Loop
******************/
QUnit.asyncTest("Option: Loop", function() {
expect(6);
var testOptions = { delay: 500, easing: "spring" };
var $target1 = getTarget();
Velocity($target1, defaultProperties, { loop: 2, delay: testOptions.delay, easing: testOptions.easing });
/* We expect 1 delay followed by 1 call for a total of 4 cycles, which equates to 8 queue items. */
equal(Velocity.Utilities.queue($target1).length, 8, "Loop call produced 'reverse' calls.");
var $target2 = getTarget();
Velocity($target2, defaultProperties, { loop: true, delay: testOptions.delay, easing: testOptions.easing });
setTimeout(function() {
equal(Data($target1, pluginName).opts.delay, testOptions.delay, "Delay option was passed into second loop call (jQuery object).");
equal(Data($target1, pluginName).opts.easing, testOptions.easing, "Easing option was passed into second loop call (jQuery object).");
equal(Data($target2, pluginName).opts.delay, testOptions.delay, "Delay option was passed into second infinite loop call (jQuery object).");
equal(Data($target2, pluginName).opts.easing, testOptions.easing, "Easing option was passed into second infinite loop call (jQuery object).");
equal(Velocity.Utilities.queue($target2).length, 2, "Infinite loop is running.");
start();
}, completeCheckDuration + testOptions.delay);
});
/*******************
Option: Begin
*******************/
QUnit.asyncTest("Option: Begin", function() {
expect(1);
var $targetSet = [ getTarget(), getTarget() ];
Velocity($targetSet, defaultProperties, {
duration: asyncCheckDuration,
begin: function() {
deepEqual(this, $targetSet, "Elements passed into callback.");
start();
}
});
});
/*********************
Option: Complete
*********************/
QUnit.asyncTest("Option: Complete", function() {
expect(1);
var $targetSet = [ getTarget(), getTarget() ];
Velocity($targetSet, defaultProperties, {
duration: asyncCheckDuration,
complete: function() {
deepEqual(this, $targetSet, "Elements passed into callback.");
start();
}
});
});
/*********************
Option: Progress
*********************/
QUnit.asyncTest("Option: Progress", function() {
expect(3);
var alreadyCalled = false;
var $target = getTarget();
Velocity($target, defaultProperties, {
duration: asyncCheckDuration,
progress: function(elements, percentComplete, msRemaining) {
if (!alreadyCalled) {
deepEqual(this, [ $target ], "Elements passed into progress.");
equal(percentComplete >= 0 && percentComplete <= 1, true, "percentComplete passed into progress.");
equal(msRemaining > asyncCheckDuration - 50, true, "msRemaining passed into progress.");
alreadyCalled = true;
start();
}
}
});
});
/*********************
Command: Reverse
*********************/
QUnit.asyncTest("Command: Reverse", function() {
expect(5);
var testEasing = "spring";
var $target = getTarget();
/* Ensure an error isn't thrown when there's no previous animation to reverse to. */
Velocity($target, "reverse");
Velocity($target, { opacity: defaultProperties.opacity, width: defaultProperties.width }, { easing: testEasing });
Velocity($target, "reverse", function() {
equal(parseFloat(Velocity.CSS.getPropertyValue($target, "opacity")), defaultStyles.opacity, "Reversed to initial property #1.");
equal(parseFloat(Velocity.CSS.getPropertyValue($target, "width")), defaultStyles.width, "Reversed to initial property #2.");
});
/* Check chained reverses. */
Velocity($target, "reverse", function() {
equal(parseFloat(Velocity.CSS.getPropertyValue($target, "opacity")), defaultProperties.opacity, "Reversed to reversed property #1.");
equal(parseFloat(Velocity.CSS.getPropertyValue($target, "width")), defaultProperties.width, "Reversed to reversed property #2.");
/* Ensure the options were passed through until the end. */
equal(Data($target, pluginName).opts.easing, testEasing, "Options object passed through.");
start();
});
});
/******************
Command: Stop
******************/
QUnit.asyncTest("Command: Stop", function() {
expect(4);
var $target1 = getTarget();
/* Ensure an error isn't thrown when "stop" is called on a $target that isn't animating. */
Velocity($target1, "stop");
Velocity($target1, defaultProperties, defaultOptions);
Velocity($target1, { top: 0 }, defaultOptions);
Velocity($target1, { width: 0 }, defaultOptions);
Velocity($target1, "stop", true);
/* Ensure "stop" has removed all queued animations. */
/* We're using the element's queue length as a proxy. 0 and 1 both mean that the element's queue has been cleared -- a length of 1 just indicates that the animation is in progress. */
setTimeout(function() {
equal(Velocity.Utilities.queue($target1).length <= 1, true, "Queue cleared.");
}, 1);
var $target2 = getTarget();
Velocity($target2, { opacity: 0 }, Velocity.Utilities.extend({}, defaultOptions, { delay: 1000 }));
Velocity($target2, { width: 0 }, defaultOptions);
Velocity($target2, "stop");
var $target3 = getTarget();
Velocity($target3, { opacity: 0 }, Velocity.Utilities.extend({}, defaultOptions, { delay: 1000 }));
Velocity($target3, { width: 0 }, defaultOptions);
Velocity($target3, { width: 100 }, defaultOptions);
Velocity($target3, "stop", true);
setTimeout(function() {
equal(Data($target2, pluginName).tweensContainer.opacity, undefined, "Active call stopped.");
notEqual(Data($target2, pluginName).tweensContainer.width, undefined, "Next queue item started.");
equal(Velocity.Utilities.queue($target3, "").length, 0, "Full queue array cleared.");
start();
}, asyncCheckDuration);
});
/******************
Command: Finish
******************/
QUnit.asyncTest("Command: Finish / FinishAll", function() {
expect(9);
var $target1 = getTarget();
/* Ensure an error isn't thrown when "finish" is called on a $target that isn't animating. */
Velocity($target1, "finish");
/* Animate to defaultProperties, and then "finish" to jump to the end of it. */
Velocity($target1, defaultProperties, Velocity.Utilities.extend({}, defaultOptions, { delay: 1000}));
Velocity($target1, "finish");
setTimeout(function() {
/* Ensure "finish" has removed all queued animations. */
/* We're using the element's queue length as a proxy. 0 and 1 both mean that the element's queue has been cleared -- a length of 1 just indicates that the animation is in progress. */
equal(Velocity.Utilities.queue($target1).length <= 1, true, "Queue cleared.");
/* End result of the animation should be applied */
equal(parseFloat(Velocity.CSS.getPropertyValue($target1, "width")), defaultProperties.width, "Standard end value #1 was set.");
equal(parseFloat(Velocity.CSS.getPropertyValue($target1, "opacity")), defaultProperties.opacity, "Standard end value #2 was set.");
}, asyncCheckDuration);
var $target2 = getTarget();
Velocity($target2, { opacity: 0 }, Velocity.Utilities.extend({}, defaultOptions, { delay: 1000 }));
Velocity($target2, { width: 0 }, defaultOptions);
Velocity($target2, "finish");
var $target3 = getTarget();
Velocity($target3, { opacity: 0, width: 50 }, Velocity.Utilities.extend({}, defaultOptions, { delay: 1000 }));
Velocity($target3, { width: 0 }, defaultOptions);
Velocity($target3, { width: 100 }, defaultOptions);
Velocity($target3, "finish", true);
var $target4 = getTarget();
Velocity($target4, { opacity: 0, width: 50 }, Velocity.Utilities.extend({}, defaultOptions, { delay: 1000 }));
Velocity($target4, { width: 0 }, defaultOptions);
Velocity($target4, { width: 100 }, defaultOptions);
Velocity($target4, "finishAll", true);
setTimeout(function() {
equal(Data($target2, pluginName).tweensContainer.opacity, undefined, "Active call stopped.");
notEqual(Data($target2, pluginName).tweensContainer.width, undefined, "Next queue item started.");
equal(Velocity.Utilities.queue($target3, "").length, 0, "Full queue array cleared.");
equal(parseFloat(Velocity.CSS.getPropertyValue($target3, "width")), 50, "Just the first call's width was applied.");
equal(Velocity.Utilities.queue($target4, "").length, 0, "Full queue array cleared.");
equal(parseFloat(Velocity.CSS.getPropertyValue($target4, "width")), 100, "The last call's width was applied.");
start();
}, asyncCheckDuration);
});
/***********************
Feature: Redirects
***********************/
QUnit.asyncTest("Feature: Redirects", function() {
var $target1 = getTarget(),
$target2 = getTarget(),
redirectOptions = { duration: 1500 };
(window.jQuery || window.Zepto || window).Velocity.Redirects.test = function (element, options, elementIndex, elementsLength) {
if (elementIndex === 0) {
deepEqual(element, $target1, "Element passed through #1.");
deepEqual(options, redirectOptions, "Options object passed through #1.");
equal(elementIndex, 0, "Element index passed through #1.");
equal(elementsLength, 2, "Elements length passed through #1.");
} else if (elementIndex === 1) {
deepEqual(element, $target2, "Element passed through #2.");
deepEqual(options, redirectOptions, "Options object passed through #2.");
equal(elementIndex, 1, "Element index passed through #2.");
equal(elementsLength, 2, "Elements length passed through #2.");
start();
}
}
Velocity([ $target1, $target2 ], "test", redirectOptions);
});
/************************
Feature: animating
************************/
QUnit.asyncTest("Feature: 'velocity-animating' Class", function() {
var $target1 = getTarget();
Velocity($target1, defaultProperties, function(element) {
equal(/velocity-animating/.test($target1.className), false, "Class removed.");
start();
}
);
setTimeout(function() {
equal(/velocity-animating/.test($target1.className), true, "Class added.");
}, asyncCheckDuration);
});
/***********************
Feature: Promises
***********************/
QUnit.asyncTest("Feature: Promises", function() {
expect(5);
var $target1 = getTarget();
Velocity($target1, defaultProperties, 10000).then(function(elements) {
deepEqual(elements, [ $target1 ], "Active call fulfilled.");
});
Velocity($target1, defaultProperties, 10000).then(function(elements) {
deepEqual(elements, [ $target1 ], "Queued call fulfilled.");
});
Velocity($target1, "stop", true).then(function(elements) {
deepEqual(elements, [ $target1 ], "Stop call fulfilled.");
});
var $target2 = getTarget(),
$target3 = getTarget();
Velocity([ $target2, $target3 ], "fake", defaultOptions)["catch"](function(error) {
equal(error instanceof Error, true, "Invalid command caused promise rejection.");
});
Velocity([ $target2, $target3 ], defaultProperties, defaultOptions).then(function(elements) {
deepEqual(elements, [ $target2, $target3 ], "Elements passed back into resolved promise.");
start();
});
});
/*****************************
Feature: Value Functions
*****************************/
QUnit.test("Feature: Value Functions", function() {
var testWidth = 10;
var $target1 = getTarget(),
$target2 = getTarget();
Velocity([ $target1, $target2 ], { width: function (i, total) { return (i + 1)/total * testWidth; } });
equal(Data($target1, pluginName).tweensContainer.width.endValue, parseFloat(testWidth) / 2, "Function value #1 passed to tween.");
equal(Data($target2, pluginName).tweensContainer.width.endValue, parseFloat(testWidth), "Function value #2 passed to tween.");
});
/***************************
Feature: Forcefeeding
***************************/
QUnit.test("Feature: Forcefeeding", function() {
/* Note: Start values are always converted into pixels. W test the conversion ratio we already know to avoid additional work. */
var testStartWidth = "1rem", testStartWidthToPx = "16px",
testStartHeight = "10px";
var $target = getTarget();
Velocity($target, { width: [ 100, "linear", testStartWidth ], height: [ 100, testStartHeight ], opacity: [ defaultProperties.opacity, "easeInQuad" ]});
equal(Data($target, pluginName).tweensContainer.width.startValue, parseFloat(testStartWidthToPx), "Forcefed value #1 passed to tween.");
equal(Data($target, pluginName).tweensContainer.height.startValue, parseFloat(testStartHeight), "Forcefed value #2 passed to tween.");
equal(Data($target, pluginName).tweensContainer.opacity.startValue, defaultStyles.opacity, "Easing was misinterpreted as forcefed value.");
});
/*********************************
Feature: Colors (Shorthands)
*********************************/
QUnit.test("Feature: Colors (Shorthands)", function() {
var $target = getTarget();
Velocity($target, { borderColor: "#7871c2", color: [ "#297dad", "spring", "#5ead29" ] });
equal(Data($target, pluginName).tweensContainer.borderColorRed.endValue, 120, "Hex #1a component.");
equal(Data($target, pluginName).tweensContainer.borderColorGreen.endValue, 113, "Hex #1b component.");
equal(Data($target, pluginName).tweensContainer.borderColorBlue.endValue, 194, "Hex #1c component.");
equal(Data($target, pluginName).tweensContainer.colorRed.easing, "spring", "Per-property easing.");
equal(Data($target, pluginName).tweensContainer.colorRed.startValue, 94, "Forcefed hex #2a component.");
equal(Data($target, pluginName).tweensContainer.colorGreen.startValue, 173, "Forcefed hex #2b component.");
equal(Data($target, pluginName).tweensContainer.colorBlue.startValue, 41, "Forcefed hex #2c component.");
equal(Data($target, pluginName).tweensContainer.colorRed.endValue, 41, "Hex #3a component.");
equal(Data($target, pluginName).tweensContainer.colorGreen.endValue, 125, "Hex #3b component.");
equal(Data($target, pluginName).tweensContainer.colorBlue.endValue, 173, "Hex #3c component.");
});
/**********************************
Packaged Effect: slideUp/Down
**********************************/
QUnit.asyncTest("Packaged Effect: slideUp/Down", function() {
var $target1 = getTarget(),
$target2 = getTarget();
var initialStyles = {
display: "none",
paddingTop: "123px"
};
$target1.style.display = initialStyles.display;
$target1.style.paddingTop = initialStyles.paddingTop;
Velocity($target1, "slideDown",
{
begin: function(elements) {
deepEqual(elements, [ $target1 ], "slideDown: Begin callback returned.");
},
complete: function(elements) {
deepEqual(elements, [ $target1 ], "slideDown: Complete callback returned.");
equal(Velocity.CSS.getPropertyValue($target1, "display"), Velocity.CSS.Values.getDisplayType($target1), "slideDown: display set to default.");
notEqual(Velocity.CSS.getPropertyValue($target1, "height"), 0, "slideDown: height set.");
equal(Velocity.CSS.getPropertyValue($target1, "paddingTop"), initialStyles.paddingTop, "slideDown: paddingTop set.");
}
}
).then(function(elements) {
deepEqual(elements, [ $target1 ], "slideDown: Promise fulfilled.");
});
Velocity($target2, "slideUp",
{
begin: function(elements) {
deepEqual(elements, [ $target2 ], "slideUp: Begin callback returned.");
},
complete: function(elements) {
deepEqual(elements, [ $target2 ], "slideUp: Complete callback returned.");
equal(Velocity.CSS.getPropertyValue($target2, "display"), 0, "slideUp: display set to none.");
notEqual(Velocity.CSS.getPropertyValue($target2, "height"), 0, "slideUp: height reset.");
equal(Velocity.CSS.getPropertyValue($target1, "paddingTop"), initialStyles.paddingTop, "slideUp: paddingTop reset.");
}
}
).then(function(elements) {
deepEqual(elements, [ $target2 ], "slideUp: Promise fulfilled.");
start();
});
});
/***********************
UI Pack: Callbacks
***********************/
QUnit.asyncTest("UI Pack: Callbacks", function() {
expect(3);
var $targets = [ getTarget(), getTarget() ];
Velocity($targets, "transition.bounceIn",
{
begin: function(elements) {
deepEqual(elements, $targets, "Begin callback returned.");
},
complete: function(elements) {
deepEqual(elements, $targets, "Complete callback returned.");
}
}
).then(function(elements) {
deepEqual(elements, $targets, "Promise fulfilled.");
start();
});
});
/*********************
UI Pack: In/Out
*********************/
QUnit.asyncTest("UI Pack: In/Out", function() {
expect(8);
var $target1 = getTarget();
Velocity($target1, "transition.bounceIn", defaultOptions.duration);
var $target2 = getTarget();
Velocity($target2, "transition.bounceIn", { duration: defaultOptions.duration, display: "inline" });
var $target3 = getTarget();
Velocity($target3, "transition.bounceOut", defaultOptions.duration);
var $target4 = getTarget();
Velocity($target4, "transition.bounceOut", { duration: defaultOptions.duration, display: null });
var $target5 = getTarget();
$target5.style.visibility = "hidden";
Velocity($target5, "transition.bounceIn", { duration: defaultOptions.duration, visibility: "visible" });
var $target6 = getTarget();
$target6.style.visibility = "visible";
Velocity($target6, "transition.bounceOut", { duration: defaultOptions.duration, visibility: "hidden" });
setTimeout(function() {
notEqual(Velocity.CSS.getPropertyValue($target3, "display"), 0, "Out: display not prematurely set to none.");
notEqual(Velocity.CSS.getPropertyValue($target6, "visibility"), "hidden", "Out: visibility not prematurely set to hidden.");
}, asyncCheckDuration)
setTimeout(function() {
equal(Velocity.CSS.getPropertyValue($target1, "display"), Velocity.CSS.Values.getDisplayType($target1), "In: display set to default.");
equal(Velocity.CSS.getPropertyValue($target2, "display"), "inline", "In: Custom inline value set.");
equal(Velocity.CSS.getPropertyValue($target3, "display"), 0, "Out: display set to none.");
equal(Velocity.CSS.getPropertyValue($target4, "display"), Velocity.CSS.Values.getDisplayType($target3), "Out: No display value set.");
equal(Velocity.CSS.getPropertyValue($target5, "visibility"), "visible", "In: visibility set to visible.");
equal(Velocity.CSS.getPropertyValue($target6, "visibility"), "hidden", "Out: visibility set to hidden.");
start();
}, completeCheckDuration)
});
/**************************
UI Pack: Call Options
**************************/
QUnit.asyncTest("UI Pack: Call Options", function() {
expect(7);
var UICallOptions1 = {
delay: 123,
duration: defaultOptions.duration,
loop: true, // Should get ignored
easing: "spring" // Should get ignored
};
var $target1 = getTarget();
Velocity($target1, "transition.slideLeftIn", UICallOptions1);
setTimeout(function() {
// Note: We can do this because transition.slideLeftIn is composed of a single call.
equal(Data($target1, pluginName).opts.delay, UICallOptions1.delay, "Whitelisted option passed in.");
notEqual(Data($target1, pluginName).opts.loop, UICallOptions1.loop, "Non-whitelisted option not passed in #1a.");
notEqual(Data($target1, pluginName).opts.easing, UICallOptions1.easing, "Non-whitelisted option not passed in #1a.");
equal(!/velocity-animating/.test(Data($target1, pluginName).className), true, "Duration option passed in.");
}, completeCheckDuration);
var UICallOptions2 = {
stagger: 100,
duration: defaultOptions.duration,
backwards: true
};
var $targets = [ getTarget(), getTarget(), getTarget() ];
Velocity($targets, "transition.slideLeftIn", UICallOptions2);
setTimeout(function() {
equal(Data($targets[0], pluginName).opts.delay, UICallOptions2.stagger * 2, "Backwards stagger delay passed in #1a.");
equal(Data($targets[1], pluginName).opts.delay, UICallOptions2.stagger * 1, "Backwards stagger delay passed in #1b.");
equal(Data($targets[2], pluginName).opts.delay, UICallOptions2.stagger * 0, "Backwards stagger delay passed in #1c.");
start();
}, completeCheckDuration);
});
/****************************
UI Pack: RegisterEffect
****************************/
QUnit.asyncTest("UI Pack: RegisterEffect", function() {
expect(2);
var effectDefaultDuration = 800;
Velocity.RegisterUI("callout.twirl", {
defaultDuration: effectDefaultDuration,
calls: [
[ { rotateZ: 1080 }, 0.50 ],
[ { scaleX: 0.5 }, 0.25, { easing: "spring" } ],
[ { scaleX: 1 }, 0.25, { easing: "spring" } ]
]
});
var $target1 = getTarget();
Velocity($target1, "callout.twirl");
setTimeout(function() {
equal(parseFloat(Velocity.CSS.getPropertyValue($target1, "rotateZ")), 1080, "First call's property animated.");
equal(parseFloat(Velocity.CSS.getPropertyValue($target1, "scaleX")), 1, "Last call's property animated.");
start();
}, effectDefaultDuration * 1.50);
});
/*************************
UI Pack: RunSequence
*************************/
QUnit.asyncTest("UI Pack: RunSequence", function() {
expect(3);
var $target1 = getTarget(),
$target2 = getTarget(),
$target3 = getTarget();
var mySequence = [
{ elements: $target1, properties: { opacity: defaultProperties.opacity } },
{ elements: $target2, properties: { height: defaultProperties.height } },
{ elements: $target3, properties: { width: defaultProperties.width }, options: {
delay: 100,
sequenceQueue: false,
complete: function() {
equal(parseFloat(Velocity.CSS.getPropertyValue($target1, "opacity")), defaultProperties.opacity, "First call's property animated.");
equal(parseFloat(Velocity.CSS.getPropertyValue($target2, "height")), defaultProperties.height, "Second call's property animated.");
equal(parseFloat(Velocity.CSS.getPropertyValue($target3, "width")), defaultProperties.width, "Last call's property animated.");
start();
}
}
}
];
Velocity.RunSequence(mySequence);
});
/*********************
Command: Scroll
*********************/
if ($) {
/* Window scrolling. */
QUnit.asyncTest("Command: Scroll (Window)", function() {
var $details = $("#details"),
$scrollTarget1 = $("<div>Scroll target #1. Should stop 50 pixels above this point.</div>"),
$scrollTarget2 = $("<div>Scroll target #2. Should stop 50 pixels before this point.</div>"),
scrollOffset = -50;
$scrollTarget1
.css({ position: "relative", top: 3000, height: 100, paddingBottom: 10000 })
.appendTo($("body"));
$scrollTarget2
.css({ position: "absolute", top: 100, left: 3000, width: 100, paddingRight: 15000 })
.appendTo($("body"));
$scrollTarget1
.velocity("scroll", { duration: 500, offset: scrollOffset, complete: function() {
equal(Math.abs(Velocity.State.scrollAnchor[Velocity.State.scrollPropertyTop] - ($scrollTarget1.offset().top + scrollOffset)) <= 100, true, "Page scrolled top with a scroll offset.");
}
})
.velocity({ opacity: 0.5 }, function() {
$details
.velocity({ opacity: 0.5 }, 500)
.velocity("scroll", 500)
.velocity({ opacity: 1 }, 500, function() {
//alert(Velocity.State.scrollAnchor[Velocity.State.scrollPropertyTop] + " " + ($details.offset().top + scrollOffset))
equal(Math.abs(Velocity.State.scrollAnchor[Velocity.State.scrollPropertyTop] - ($details.offset().top + scrollOffset)) <= 100, true, "Page scroll top was chained.");
//$scrollTarget1.remove();
$scrollTarget2
.velocity("scroll", { duration: 500, axis: "x", offset: scrollOffset, complete: function() {
/* Phones can reposition the browser's scroll position by a 10 pixels or so, so we just check for a value that's within that range. */
equal(Math.abs(Velocity.State.scrollAnchor[Velocity.State.scrollPropertyLeft] - ($scrollTarget2.offset().left + scrollOffset)) <= 100, true, "Page scrolled left with a scroll offset.");
}
})
.velocity({ opacity: 0.5 }, function() {
$details
.velocity({ opacity: 0.5 }, 500)
.velocity("scroll", { duration: 500, axis: "x" })
.velocity({ opacity: 1 }, 500, function() {
equal(Math.abs(Velocity.State.scrollAnchor[Velocity.State.scrollPropertyLeft] - ($details.offset().left + scrollOffset)) <= 100, true, "Page scroll left was chained.");
start();
});
});
});
});
});
/* Element scrolling. */
QUnit.asyncTest("Command: Scroll (Element)", function() {
expect(2);
var $scrollTarget1 = $("\
<div id='scroller'>\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
<div id='scrollerChild1'>\
Stop #1\
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\
</div>\
cccccccccccccccccccccccccccccccccccccccccccccccccccccccc\
cccccccccccccccccccccccccccccccccccccccccccccccccccccccc\
cccccccccccccccccccccccccccccccccccccccccccccccccccccccc\
cccccccccccccccccccccccccccccccccccccccccccccccccccccccc\
cccccccccccccccccccccccccccccccccccccccccccccccccccccccc\
<div id='scrollerChild2'>\
Stop #2\
dddddddddddddddddddddddddddddddddddddddddddddddddddddddd\
dddddddddddddddddddddddddddddddddddddddddddddddddddddddd\
dddddddddddddddddddddddddddddddddddddddddddddddddddddddd\
dddddddddddddddddddddddddddddddddddddddddddddddddddddddd\
dddddddddddddddddddddddddddddddddddddddddddddddddddddddd\
</div>\
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\
</div>\
");
$scrollTarget1
.css({ position: "absolute", backgroundColor: "white", top: 100, left: "50%", width: 500, height: 100, overflowY: "scroll" })
.appendTo($("body"));
/* Test with a jQuery object container. */
$("#scrollerChild1").velocity("scroll", { container: $("#scroller"), duration: 750, complete: function() {
/* Test with a raw DOM element container. */
$("#scrollerChild2").velocity("scroll", { container: $("#scroller")[0], duration: 750, complete: function() {
/* This test is purely visual. */
ok(true);
$scrollTarget1.remove();
var $scrollTarget2 = $("\
<div id='scroller'>\
<div id='scrollerChild1' style='float: left; width: 20%;'>\
Stop #1\
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\
cccccccccccccccccccccccccccccccccccccccccccccccccccccccc\
cccccccccccccccccccccccccccccccccccccccccccccccccccccccc\
cccccccccccccccccccccccccccccccccccccccccccccccccccccccc\
cccccccccccccccccccccccccccccccccccccccccccccccccccccccc\
cccccccccccccccccccccccccccccccccccccccccccccccccccccccc\
</div>\
<div id='scrollerChild2' style='float: right; width: 20%;'>\
Stop #2\
dddddddddddddddddddddddddddddddddddddddddddddddddddddddd\
dddddddddddddddddddddddddddddddddddddddddddddddddddddddd\
dddddddddddddddddddddddddddddddddddddddddddddddddddddddd\
dddddddddddddddddddddddddddddddddddddddddddddddddddddddd\
dddddddddddddddddddddddddddddddddddddddddddddddddddddddd\
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\
</div>\
</div>\
");
$scrollTarget2
.css({ position: "absolute", backgroundColor: "white", top: 100, left: "50%", width: 100, height: 500, overflowX: "scroll" })
.appendTo($("body"));
/* Test with a jQuery object container. */
$("#scrollerChild2").velocity("scroll", { axis: "x", container: $("#scroller"), duration: 750, complete: function() {
/* Test with a raw DOM element container. */
$("#scrollerChild1").velocity("scroll", { axis: "x", container: $("#scroller")[0], duration: 750, complete: function() {
/* This test is purely visual. */
ok(true);
$scrollTarget2.remove();
start();
}
});
}
});
}
});
}
});
});
}
</script>
</body>
</html>