initial commit

This commit is contained in:
Mahdi Dibaiee
2018-04-26 02:00:45 +04:30
commit dec1523aca
31131 changed files with 80014 additions and 0 deletions

25
impress/test/bootstrap.js vendored Normal file
View File

@ -0,0 +1,25 @@
/*jshint browser:true */
// TODO: This is the bootstrap file for *karma*. Poorly named (since karma is
// only one option, in this repo) but keeping the same name now to avoid
// unnecessary deviation with upstream.
// If you just want to run the tests locally, you can open /qunit_test_runner.html in Firefox.
// That's annoying: karma-qunit doesn't provide the qunit-fixture element
// https://github.com/karma-runner/karma-qunit/issues/18
// This file contains so much HTML, that we will just respectfully disagree about js
/* jshint quotmark:single */
/* global document */
var fix = document.createElement( 'div' );
fix.id = 'qunit-fixture';
fix.innerHTML = [
'\n',
' <iframe id="presentation-iframe"\n',
' src="SET THIS IN YOUR QUNIT TESTS"\n',
' width="595" height="485"\n',
' frameborder="0" marginwidth="0" marginheight="0" scrolling="no"\n',
' style="border:1px solid #CCC; max-width: 100%;">\n',
' </iframe>'
].join( '' );

266
impress/test/core_tests.js Normal file
View File

@ -0,0 +1,266 @@
/*
* Copyright 2016 Henrik Ingo (@henrikingo)
*
* Released under the MIT license. See LICENSE file.
*/
/* global document, console, setTimeout, loadIframe, initPresentation, _impressSupported, QUnit */
QUnit.module( "Core Tests" );
QUnit.test( "Initialize Impress.js", function( assert ) {
console.log( "Begin init() test" );
// Init triggers impress:init and impress:stepenter events, which we want to catch.
var doneInit = assert.async();
var doneStepEnter = assert.async();
var doneSync = assert.async();
loadIframe( "test/core_tests_presentation.html", assert, function() {
var iframe = document.getElementById( "presentation-iframe" );
var iframeDoc = iframe.contentDocument;
var iframeWin = iframe.contentWindow;
var root = iframeDoc.querySelector( "div#impress" );
// Catch events triggered by init()
var assertInit = function() {
assert.ok( true, "impress:init event triggered." );
var canvas = iframeDoc.querySelector( "div#impress > div" );
// Delay and duration don't become set before the first transition actually happened
assert.equal( canvas.style.transitionDelay,
"0ms",
"canvas.style.transitionDelay initialized correctly" );
assert.equal( canvas.style.transitionDuration,
"0ms",
"canvas.style.transitionDuration initialized correctly" );
doneInit();
console.log( "End init() test (async)" );
};
var assertInitWrapper = function() {
setTimeout( function() { assertInit(); }, 10 );
};
root.addEventListener( "impress:init", assertInitWrapper );
root.addEventListener( "impress:stepenter", function( event ) {
assert.ok( true, "impress:stepenter event triggered." );
var step1 = iframeDoc.querySelector( "div#step-1" );
assert.equal( event.target, step1,
event.target.id + " triggered impress:stepenter event." );
doneStepEnter();
} );
// Synchronous code and assertions
assert.ok( iframeWin.impress,
"impress declared in global scope" );
assert.strictEqual( iframeWin.impress().init(), undefined,
"impress().init() called." );
assert.strictEqual( iframeWin.impress().init(), undefined,
"It's ok to call impress().init() a second time, it's a no-op." );
// The asserts below are true immediately after impress().init() returns.
// Therefore we test them here, not in an event handler.
var notSupportedClass = iframeDoc.body.classList.contains( "impress-not-supported" );
var yesSupportedClass = iframeDoc.body.classList.contains( "impress-supported" );
if ( !_impressSupported() ) {
assert.ok( notSupportedClass,
"body.impress-not-supported class still there." );
assert.ok( !yesSupportedClass,
"body.impress-supported class was NOT added." );
} else {
assert.ok( !notSupportedClass,
"body.impress-not-supported class was removed." );
assert.ok( yesSupportedClass,
"body.impress-supported class was added." );
assert.ok( !iframeDoc.body.classList.contains( "impress-disabled" ),
"body.impress-disabled is removed." );
assert.ok( iframeDoc.body.classList.contains( "impress-enabled" ),
"body.impress-enabled is added." );
var canvas = iframeDoc.querySelector( "div#impress > div" );
assert.ok( !canvas.classList.contains( "step" ) && canvas.id === "",
"Additional 'canvas' div inserted between div#impress root and steps." );
assert.equal( canvas.style.transform,
"rotateZ(0deg) rotateY(0deg) rotateX(0deg) translate3d(1000px, 0px, 0px)",
"canvas.style.transform initialized correctly" );
assert.equal( canvas.style.transformOrigin,
"left top 0px",
"canvas.style.transformOrigin initialized correctly" );
assert.equal( canvas.style.transformStyle,
"preserve-3d",
"canvas.style.transformStyle initialized correctly" );
assert.equal( canvas.style.transitionProperty,
"all",
"canvas.style.transitionProperty initialized correctly" );
assert.equal( canvas.style.transitionTimingFunction,
"ease-in-out",
"canvas.style.transitionTimingFunction initialized correctly" );
assert.equal( iframeDoc.documentElement.style.height,
"100%",
"documentElement.style.height is 100%" );
// Steps initialization
var step1 = iframeDoc.querySelector( "div#step-1" );
assert.equal( step1.style.position,
"absolute",
"Step position is 'absolute'." );
assert.ok( step1.classList.contains( "active" ),
"Step 1 has active css class." );
}
doneSync();
console.log( "End init() test (sync)" );
} ); // LoadIframe()
} );
// Note: Here we focus on testing the core functionality of moving between
// steps, the css classes set and unset, and events triggered.
// TODO: more complex animations and check position, transitions, delays, etc...
QUnit.test( "Impress Core API", function( assert ) {
console.log( "Begin core api test" );
var done = assert.async();
loadIframe( "test/core_tests_presentation.html", assert, function() {
initPresentation( assert, function() {
var iframe = document.getElementById( "presentation-iframe" );
var iframeDoc = iframe.contentDocument;
var iframeWin = iframe.contentWindow;
// Impress.js itself uses event listeners to manipulate most CSS classes.
// Wait a short while before checking, to avoid race.
// (See assertStepEnterWrapper and assertStepLeaveWrapper.)
var wait = 5; // Milliseconds
var step1 = iframeDoc.querySelector( "div#step-1" );
var step2 = iframeDoc.querySelector( "div#step-2" );
var step3 = iframeDoc.querySelector( "div#step-3" );
var step4 = iframeDoc.querySelector( "div#fourth" );
var root = iframeDoc.querySelector( "div#impress" );
// On impress:stepenter, we do some assertions on the "entered" object.
// On impress:stepleave, we do some assertions on the "left" object.
// Finally we call next() to initialize the next transition, and it starts all over again.
var i = 0;
var sequence = [ { left: step1,
entered: step2,
next: function() { return iframeWin.impress().goto( 2 ); },
text: "goto(<number>) called and returns ok (2->3)" },
{ left: step2,
entered: step3,
next: function() { return iframeWin.impress().goto( "fourth" ); },
text: "goto(<string>) called and returns ok (3->4)" },
{ left: step3,
entered: step4,
next: function() { return iframeWin.impress().next(); },
text: "next() wraps around to first step (4->1)" },
{ left: step4,
entered: step1,
next: function() { return iframeWin.impress().prev(); },
text: "prev() wraps around to last step (1->4)" },
{ left: step1,
entered: step4,
next: function() { return iframeWin.impress().prev(); },
text: "prev() called and returns ok (4->3)" },
{ left: step4,
entered: step3,
next: function() { return iframeWin.impress().goto( 0 ); },
text: "End of test suite, return to first step with goto(0)." },
{ left: step3,
entered: step1,
next: false } // False = end of sequence
];
// When both assertStepEnter and assertStepLeave are done, we can go to next step in sequence.
var readyCount = 0;
var readyForNext = function() {
readyCount++;
if ( readyCount % 2 === 0 ) {
if ( sequence[ i ].next ) {
assert.ok( sequence[ i ].next(), sequence[ i ].text );
i++;
assertImmediately();
} else {
done();
console.log( "End core api test" );
}
}
};
// Things to check on impress:stepenter event -----------------------------//
var assertStepEnter = function( event ) {
assert.equal( event.target, sequence[ i ].entered,
event.target.id + " triggered impress:stepenter event." );
assert.ok( event.target.classList.contains( "present" ),
event.target.id + " set present css class." );
assert.ok( !event.target.classList.contains( "future" ),
event.target.id + " unset future css class." );
assert.ok( !event.target.classList.contains( "past" ),
event.target.id + " unset past css class." );
assert.equal( "#/" + event.target.id, iframeWin.location.hash,
"Hash is " + "#/" + event.target.id );
// Just by way of comparison, check transitionDuration again, in a non-init transition
var canvas = iframeDoc.querySelector( "div#impress > div" );
assert.equal( canvas.style.transitionDelay,
"0ms",
"canvas.style.transitionDelay set correctly" );
assert.equal( canvas.style.transitionDuration,
"1000ms",
"canvas.style.transitionDuration set correctly" );
readyForNext();
};
var assertStepEnterWrapper = function( event ) {
setTimeout( function() { assertStepEnter( event ); }, wait );
};
root.addEventListener( "impress:stepenter", assertStepEnterWrapper );
// Things to check on impress:stepleave event -----------------------------//
var assertStepLeave = function( event ) {
assert.equal( event.target, sequence[ i ].left,
event.target.id + " triggered impress:stepleave event." );
assert.ok( !event.target.classList.contains( "present" ),
event.target.id + " unset present css class." );
assert.ok( !event.target.classList.contains( "future" ),
event.target.id + " unset future css class." );
assert.ok( event.target.classList.contains( "past" ),
event.target.id + " set past css class." );
readyForNext();
};
var assertStepLeaveWrapper = function( event ) {
setTimeout( function() { assertStepLeave( event ); }, wait );
};
root.addEventListener( "impress:stepleave", assertStepLeaveWrapper );
// Things to check immediately after impress().goto() ---------------------------//
var assertImmediately = function() {
assert.ok( sequence[ i ].entered.classList.contains( "active" ),
sequence[ i ].entered.id + " set active css class." );
assert.ok( !sequence[ i ].left.classList.contains( "active" ),
sequence[ i ].left.id + " unset active css class." );
};
// Done with setup. Start testing! -----------------------------------------------//
// Do no-op tests first, then trigger the sequence of transitions we setup above. //
assert.strictEqual( iframeWin.impress().goto( iframeDoc.querySelector( "div#impress" ) ),
false,
"goto() to a non-step element fails, as it should." );
assert.strictEqual( iframeWin.impress().goto(),
false,
"goto(<nothing>) fails, as it should." );
// This starts executing the sequence above
assert.ok( iframeWin.impress().next(),
"next() called and returns ok (1->2)" );
} ); // InitPresentation()
} ); // LoadIframe()
} );

View File

@ -0,0 +1,23 @@
<!DOCTYPE html>
<!--
Copyright 2016 Henrik Ingo (@henrikingo)
Released under the MIT license. See LICENSE file.
-->
<html>
<head>
<meta charset="utf-8">
<title>The presentation steps used in an iframe in core_tests.js</title>
</head>
<!-- id is used by syn -->
<body class="impress-not-supported" id="bodyid">
<div id="impress">
<div class="step" data-x="-1000" data-y="0">First slide</div>
<div class="step" data-x="-800" data-y="0">Second slide <br /><a href="#fourth" id="linktofourth">link to fourth slide</a></div>
<div class="step" data-x="-600" data-y="0">Third slide<br /><a href="#step-1" id="linktofirst">link to first slide</a></div>
<div class="step" id="fourth" data-x="-400" data-y="0">Fourth slide</div>
</div>
<script src="../js/impress.js"></script>
<!-- See http://bitovi.com/blog/2010/07/syn-a-standalone-synthetic-event-library.html for simple usage guide. -->
<script src="../node_modules/syn/dist/global/syn.js"></script>
</body>
</html>

107
impress/test/helpers.js Normal file
View File

@ -0,0 +1,107 @@
// This file contains so much HTML, that we will just respectfully disagree about js
/* jshint quotmark:single */
/* global document, console, setTimeout, navigator, QUnit */
/* exported loadIframe, initPresentation, _impressSupported */
// Log all QUnit assertions to console.log(), so that they are visible in karma output
QUnit.log( function( details ) {
console.log( 'QUnit.log: ', details.result, details.message );
} );
var loadIframe = function( src, assert, callback ) {
console.log( 'Begin loadIframe' );
// When running in Karma, the #qunit-fixture appears from somewhere and we can't set its
// contents in advance.
var fix = document.getElementById( 'qunit-fixture' );
fix.innerHTML = [
'\n',
' <iframe id="presentation-iframe"\n',
' width="595" height="485"\n',
' frameborder="0" marginwidth="0" marginheight="0" scrolling="no"\n',
' style="border:1px solid #CCC; max-width: 100%;">\n',
' </iframe>'
].join( '' );
var iframe = document.getElementById( 'presentation-iframe' );
var onLoad = function() {
assert.ok( true,
'Presentation loaded. iframe.src = ' + iframe.src );
try {
assert.ok( iframe.contentDocument,
'Verifying that tests can access the presentation inside the iframe. ' +
'Note: On Firefox this fails when using paths with "../" parts for the iframe.' );
}
catch ( err ) {
assert.ok( false,
'Error when trying to access presentation in iframe. Note: When using Chrome with ' +
'local files (file:///) this will fail with SecurityError. ' +
'You can however use Chrome over Karma.' );
}
console.log( 'End loadIframe' );
callback();
};
iframe.addEventListener( 'load', onLoad );
assert.ok( iframe.src = src,
'Setting iframe.src = ' + src );
};
var initPresentation = function( assert, callback, rootId ) {
console.log( 'Begin initPresentation' );
var iframe = document.getElementById( 'presentation-iframe' );
var iframeDoc = iframe.contentDocument;
var iframeWin = iframe.contentWindow;
// Impress:stepenter is the last event triggered in init(), so we wait for that.
var waitForStepEnter = function( event ) {
assert.ok( true, 'impress (' + event.target.id + ') is now initialized.' );
iframeDoc.removeEventListener( 'impress:stepenter', waitForStepEnterWrapper );
console.log( 'End initPresentation' );
callback();
};
// Unfortunately, impress.js uses the impress:stepenter event internally to
// do some things related to entering a step. This causes a race condition when
// we listen for the same event and expect it to be done with everything.
// We wait 5 ms to resolve the race condition, then it's safe to start testing.
var waitForStepEnterWrapper = function( event ) {
setTimeout( function() { waitForStepEnter( event ); }, 5 );
};
iframeDoc.addEventListener( 'impress:stepenter', waitForStepEnterWrapper );
assert.strictEqual( iframeWin.impress( rootId ).init(), undefined, 'Initializing impress.' );
};
// Helper function to determine whether this browser is supported by
// impress.js or not. Copied from impress.js itself.
var _impressSupported = function() {
var pfx = ( function() {
var style = document.createElement( 'dummy' ).style,
prefixes = 'Webkit Moz O ms Khtml'.split( ' ' ),
memory = {};
return function( prop ) {
if ( typeof memory[ prop ] === 'undefined' ) {
var ucProp = prop.charAt( 0 ).toUpperCase() + prop.substr( 1 ),
props = ( prop + ' ' + prefixes.join( ucProp + ' ' ) + ucProp ).split( ' ' );
memory[ prop ] = null;
for ( var i in props ) {
if ( style[ props[ i ] ] !== undefined ) {
memory[ prop ] = props[ i ];
break;
}
}
}
return memory[ prop ];
};
} )();
var ua = navigator.userAgent.toLowerCase();
return ( pfx( 'perspective' ) !== null ) &&
( document.body.classList ) &&
( document.body.dataset ) &&
( ua.search( /(iphone)|(ipod)|(android)/ ) === -1 );
};

View File

@ -0,0 +1,18 @@
<!DOCTYPE html>
<!--
Copyright 2016 Henrik Ingo (@henrikingo)
Released under the MIT license. See LICENSE file.
-->
<html>
<head>
<meta charset="utf-8">
<title>A test presentation with non-default value for the root div id</title>
</head>
<body class="impress-not-supported">
<div id="non-default-id">
<div class="step" data-x="-1000" data-y="0">First slide</div>
<div class="step" data-x="-800" data-y="0">Second slide</div>
</div>
<script src="../js/impress.js"></script>
</body>
</html>

144
impress/test/non_default.js Normal file
View File

@ -0,0 +1,144 @@
/*
* Copyright 2016 Henrik Ingo (@henrikingo)
*
* Released under the MIT license. See LICENSE file.
*/
/* global document, console, setTimeout, loadIframe, initPresentation, _impressSupported, QUnit */
QUnit.module( "Non Default Values" );
QUnit.test( "Initialize Impress.js", function( assert ) {
console.log( "Begin init() test" );
// Init triggers impress:init and impress:stepenter events, which we want to catch.
var doneInit = assert.async();
var doneStepEnter = assert.async();
var doneSync = assert.async();
loadIframe( "test/non_default.html", assert, function() {
var iframe = document.getElementById( "presentation-iframe" );
var iframeDoc = iframe.contentDocument;
var iframeWin = iframe.contentWindow;
var root = iframeDoc.querySelector( "div#non-default-id" );
// Catch events triggered by init()
var assertInit = function() {
assert.ok( true, "impress:init event triggered." );
doneInit();
console.log( "End init() test (async)" );
};
var assertInitWrapper = function() {
setTimeout( function() { assertInit(); }, 10 );
};
root.addEventListener( "impress:init", assertInitWrapper );
root.addEventListener( "impress:stepenter", function( event ) {
assert.ok( true, "impress:stepenter event triggered." );
var step1 = iframeDoc.querySelector( "div#step-1" );
assert.equal( event.target, step1,
event.target.id + " triggered impress:stepenter event." );
doneStepEnter();
} );
// Synchronous code and assertions
assert.ok( iframeWin.impress,
"impress declared in global scope" );
assert.strictEqual( iframeWin.impress( "non-default-id" ).init(), undefined,
"impress().init() called with 'non-default-id'." );
assert.strictEqual( iframeWin.impress( "non-default-id" ).init(), undefined,
"It's ok to call impress().init() a second time, it's a no-op." );
// The asserts below are true immediately after impress().init() returns.
// Therefore we test them here, not in an event handler.
var notSupportedClass = iframeDoc.body.classList.contains( "impress-not-supported" );
var yesSupportedClass = iframeDoc.body.classList.contains( "impress-supported" );
if ( !_impressSupported() ) {
assert.ok( notSupportedClass,
"body.impress-not-supported class still there." );
assert.ok( !yesSupportedClass,
"body.impress-supported class was NOT added." );
} else {
assert.ok( !notSupportedClass,
"body.impress-not-supported class was removed." );
assert.ok( yesSupportedClass,
"body.impress-supported class was added." );
assert.ok( !iframeDoc.body.classList.contains( "impress-disabled" ),
"body.impress-disabled is removed." );
assert.ok( iframeDoc.body.classList.contains( "impress-enabled" ),
"body.impress-enabled is added." );
// Steps initialization
var step1 = iframeDoc.querySelector( "div#step-1" );
assert.equal( step1.style.position,
"absolute",
"Step position is 'absolute'." );
assert.ok( step1.classList.contains( "active" ),
"Step 1 has active css class." );
}
doneSync();
console.log( "End init() test (sync)" );
} ); // LoadIframe()
} );
QUnit.test( "Non default root id, API tests", function( assert ) {
console.log( "Begin api test" );
var done = assert.async();
loadIframe( "test/non_default.html", assert, function() {
initPresentation( assert, function() {
var iframe = document.getElementById( "presentation-iframe" );
var iframeDoc = iframe.contentDocument;
var iframeWin = iframe.contentWindow;
var wait = 5; // Milliseconds
var step1 = iframeDoc.querySelector( "div#step-1" );
var step2 = iframeDoc.querySelector( "div#step-2" );
var root = iframeDoc.querySelector( "div#non-default-id" );
// Things to check on impress:stepenter event -----------------------------//
var assertStepEnter = function( event ) {
assert.equal( event.target, step2,
event.target.id + " triggered impress:stepenter event." );
assert.ok( event.target.classList.contains( "present" ),
event.target.id + " set present css class." );
assert.ok( !event.target.classList.contains( "future" ),
event.target.id + " unset future css class." );
assert.ok( !event.target.classList.contains( "past" ),
event.target.id + " unset past css class." );
assert.equal( "#/" + event.target.id, iframeWin.location.hash,
"Hash is " + "#/" + event.target.id );
done();
};
var assertStepEnterWrapper = function( event ) {
setTimeout( function() { assertStepEnter( event ); }, wait );
};
root.addEventListener( "impress:stepenter", assertStepEnterWrapper );
// Done with setup. Start testing! -----------------------------------------------//
assert.strictEqual( iframeWin.impress( "non-default-id" ).goto(),
false,
"goto(<nothing>) fails, as it should." );
// This starts executing the sequence above
assert.ok( iframeWin.impress( "non-default-id" ).next(),
"impress('non-default-id').next() called and returns ok (1->2)" );
// Things to check immediately after impress().goto() ---------------------------//
assert.ok( step2.classList.contains( "active" ),
step2.id + " set active css class." );
assert.ok( !step1.classList.contains( "active" ),
step1.id + " unset active css class." );
}, "non-default-id" ); // InitPresentation()
} ); // LoadIframe()
} );