2018-11-12 16:33:24 +00:00
|
|
|
( function () {
|
2014-01-30 07:22:26 +00:00
|
|
|
var MTH = {};
|
|
|
|
|
2014-04-14 18:32:30 +00:00
|
|
|
MTH.enterFullscreenMock = function () {
|
2014-01-30 07:22:26 +00:00
|
|
|
this.first().addClass( 'jq-fullscreened' ).data( 'isFullscreened', true );
|
2014-04-14 18:32:30 +00:00
|
|
|
|
2014-01-30 07:22:26 +00:00
|
|
|
$( document ).trigger( $.Event( 'jq-fullscreen-change', { element: this, fullscreen: true } ) );
|
|
|
|
};
|
|
|
|
|
2014-04-14 18:32:30 +00:00
|
|
|
MTH.exitFullscreenMock = function () {
|
2014-01-30 07:22:26 +00:00
|
|
|
this.first().removeClass( 'jq-fullscreened' ).data( 'isFullscreened', false );
|
|
|
|
|
|
|
|
$( document ).trigger( $.Event( 'jq-fullscreen-change', { element: this, fullscreen: false } ) );
|
|
|
|
};
|
|
|
|
|
2014-10-03 09:15:28 +00:00
|
|
|
/**
|
|
|
|
* Returns the exception thrown by callback, or undefined if no exception was thrown.
|
2016-07-18 13:49:27 +00:00
|
|
|
*
|
2014-10-03 09:15:28 +00:00
|
|
|
* @param {Function} callback
|
2016-12-14 13:09:10 +00:00
|
|
|
* @return {Error}
|
2014-10-03 09:15:28 +00:00
|
|
|
*/
|
2014-04-14 18:32:30 +00:00
|
|
|
MTH.getException = function ( callback ) {
|
|
|
|
var ex;
|
|
|
|
try {
|
|
|
|
callback();
|
|
|
|
} catch ( e ) {
|
|
|
|
ex = e;
|
|
|
|
}
|
|
|
|
return ex;
|
|
|
|
};
|
|
|
|
|
2017-06-02 09:29:41 +00:00
|
|
|
/**
|
|
|
|
* Creates an mw.storage-like object.
|
|
|
|
*
|
|
|
|
* @param {Object} storage localStorage stub with getItem, setItem, removeItem methods
|
2017-07-10 09:42:42 +00:00
|
|
|
* @return {mw.SafeStorage} Local storage-like object
|
2017-06-02 09:29:41 +00:00
|
|
|
*/
|
|
|
|
MTH.createLocalStorage = function ( storage ) {
|
|
|
|
return new ( Object.getPrototypeOf( mw.storage ) ).constructor( storage );
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns an mw.storage that mimicks lack of localStorage support.
|
|
|
|
*
|
2017-07-10 09:42:42 +00:00
|
|
|
* @return {mw.SafeStorage} Local storage-like object
|
2017-06-02 09:29:41 +00:00
|
|
|
*/
|
|
|
|
MTH.getUnsupportedLocalStorage = function () {
|
|
|
|
return this.createLocalStorage( undefined );
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns an mw.storage that mimicks localStorage being disabled in browser.
|
|
|
|
*
|
2017-07-10 09:42:42 +00:00
|
|
|
* @return {mw.SafeStorage} Local storage-like object
|
2017-06-02 09:29:41 +00:00
|
|
|
*/
|
|
|
|
MTH.getDisabledLocalStorage = function () {
|
|
|
|
var e = function () {
|
|
|
|
throw new Error( 'Error' );
|
|
|
|
};
|
|
|
|
|
|
|
|
return this.createLocalStorage( {
|
|
|
|
getItem: e,
|
|
|
|
setItem: e,
|
|
|
|
removeItem: e
|
|
|
|
} );
|
|
|
|
};
|
|
|
|
|
2014-10-03 09:15:28 +00:00
|
|
|
/**
|
|
|
|
* Returns a fake local storage which is not saved between reloads.
|
2016-07-18 13:49:27 +00:00
|
|
|
*
|
|
|
|
* @param {Object} [initialData]
|
2017-07-10 09:42:42 +00:00
|
|
|
* @return {mw.SafeStorage} Local storage-like object
|
2014-10-03 09:15:28 +00:00
|
|
|
*/
|
|
|
|
MTH.getFakeLocalStorage = function ( initialData ) {
|
2016-11-19 09:51:38 +00:00
|
|
|
var bag = new mw.Map();
|
2016-11-02 22:29:04 +00:00
|
|
|
bag.set( initialData );
|
2014-10-03 09:15:28 +00:00
|
|
|
|
2017-06-02 09:29:41 +00:00
|
|
|
return this.createLocalStorage( {
|
2014-10-03 09:15:28 +00:00
|
|
|
getItem: function ( key ) { return bag.get( key ); },
|
|
|
|
setItem: function ( key, value ) { bag.set( key, value ); },
|
|
|
|
removeItem: function ( key ) { bag.set( key, null ); }
|
2017-06-02 09:29:41 +00:00
|
|
|
} );
|
2014-10-03 09:15:28 +00:00
|
|
|
};
|
|
|
|
|
2016-04-03 09:18:26 +00:00
|
|
|
/**
|
|
|
|
* Returns a viewer object with all the appropriate placeholder functions.
|
2016-07-18 13:49:27 +00:00
|
|
|
*
|
2019-05-10 14:59:47 +00:00
|
|
|
* @return {mw.mmv.MultimediaViewer}
|
2016-04-03 09:18:26 +00:00
|
|
|
*/
|
|
|
|
MTH.getMultimediaViewer = function () {
|
|
|
|
return new mw.mmv.MultimediaViewer( {
|
2019-02-05 23:59:52 +00:00
|
|
|
imageQueryParameter: function () {},
|
|
|
|
language: function () {},
|
|
|
|
recordVirtualViewBeaconURI: function () {},
|
2016-04-03 09:18:26 +00:00
|
|
|
extensions: function () {
|
2016-07-18 13:49:27 +00:00
|
|
|
return { jpg: 'default' };
|
2016-04-03 09:18:26 +00:00
|
|
|
}
|
|
|
|
} );
|
|
|
|
};
|
|
|
|
|
2017-05-05 15:53:28 +00:00
|
|
|
MTH.asyncPromises = [];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Given a method/function that returns a promise, this'll return a function
|
|
|
|
* that just wraps the original & returns the original result, but also
|
|
|
|
* executes an assert.async() right before it's called, and resolves that
|
|
|
|
* async after that promise has completed.
|
|
|
|
*
|
|
|
|
* Example usage: given a method `bootstrap.openImage` that returns a
|
|
|
|
* promise, just call it like this to wrap this functionality around it:
|
|
|
|
* `bootstrap.openImage = asyncMethod( bootstrap.openImage, bootstrap );`
|
|
|
|
*
|
|
|
|
* Now, every time some part of the code calls this function, it'll just
|
|
|
|
* execute as it normally would, but your tests won't finish until these
|
|
|
|
* functions (and any .then tacked on to them) have completed.
|
|
|
|
*
|
|
|
|
* This method will make sure your tests don't end prematurely (before the
|
|
|
|
* promises have been resolved), but that's it. If you need to run
|
|
|
|
* additional code after all promises have resolved, you can call the
|
|
|
|
* complementary `waitForAsync`, which will return a promise that doesn't
|
|
|
|
* resolve until all of these promises have.
|
|
|
|
*
|
|
|
|
* @param {Object} object
|
|
|
|
* @param {string} method
|
|
|
|
* @param {QUnit.assert} [assert]
|
|
|
|
* @return {Function}
|
|
|
|
*/
|
|
|
|
MTH.asyncMethod = function ( object, method, assert ) {
|
|
|
|
return function () {
|
|
|
|
// apply arguments to original promise
|
|
|
|
var promise = object[ method ].apply( object, arguments ),
|
|
|
|
done;
|
|
|
|
|
|
|
|
this.asyncPromises.push( promise );
|
|
|
|
|
|
|
|
if ( assert ) {
|
|
|
|
done = assert.async();
|
|
|
|
// use setTimeout to ensure `done` is not the first callback handler
|
|
|
|
// to execute (possibly ending the test's wait right before
|
|
|
|
// the result of the promise is executed)
|
|
|
|
setTimeout( promise.then.bind( null, done, done ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
return promise;
|
|
|
|
}.bind( this );
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a promise that will not resolve until all of the promises that
|
|
|
|
* were created in functions upon which `asyncMethod` was called have
|
|
|
|
* resolved.
|
|
|
|
*
|
2020-06-26 10:45:20 +00:00
|
|
|
* @return {jQuery.Promise}
|
2017-05-05 15:53:28 +00:00
|
|
|
*/
|
|
|
|
MTH.waitForAsync = function () {
|
|
|
|
var deferred = $.Deferred();
|
|
|
|
|
|
|
|
// it's possible that, before this function call, some code was executed
|
|
|
|
// that triggers async code that will eventually end up `asyncPromises`
|
|
|
|
// in order to give that code a chance to run, we'll add another promise
|
|
|
|
// to the array, that will only resolve at the end of the current call
|
|
|
|
// stack (using setTimeout)
|
|
|
|
this.asyncPromises.push( deferred.promise() );
|
|
|
|
setTimeout( deferred.resolve );
|
|
|
|
|
|
|
|
return QUnit.whenPromisesComplete.apply( null, this.asyncPromises ).then(
|
|
|
|
function () {
|
|
|
|
this.asyncPromises = [];
|
|
|
|
}.bind( this )
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2014-02-25 02:28:49 +00:00
|
|
|
mw.mmv.testHelpers = MTH;
|
2018-11-12 16:33:24 +00:00
|
|
|
}() );
|