( function ( mw ) {
QUnit.module( 'mediawiki.requestIdleCallback', QUnit.newMwEnvironment( {
setup: function () {
- var time = mw.now(),
- clock = this.clock = this.sandbox.useFakeTimers();
+ var clock = this.clock = this.sandbox.useFakeTimers();
- this.tick = function ( forward ) {
- time += forward;
- clock.tick( forward );
- };
this.sandbox.stub( mw, 'now', function () {
- return time;
+ return +new Date();
} );
- // Don't test the native version (if available)
- this.mwRIC = mw.requestIdleCallback;
- mw.requestIdleCallback = mw.requestIdleCallbackInternal;
- },
- teardown: function () {
- mw.requestIdleCallback = this.mwRIC;
+ this.tick = function ( forward ) {
+ return clock.tick( forward || 1 );
+ };
+
+ // Always test the polyfill, not native
+ this.sandbox.stub( mw, 'requestIdleCallback', mw.requestIdleCallbackInternal );
}
} ) );
- // Basic scheduling of callbacks
- QUnit.test( 'callback', 3, function ( assert ) {
- var sequence,
- tick = this.tick;
+ QUnit.test( 'callback', function ( assert ) {
+ var sequence;
mw.requestIdleCallback( function () {
sequence.push( 'x' );
- tick( 30 );
} );
mw.requestIdleCallback( function () {
- tick( 5 );
sequence.push( 'y' );
- tick( 30 );
} );
- // Task Z is not run in the first sequence because the
- // first two tasks consumed the available 50ms budget.
mw.requestIdleCallback( function () {
sequence.push( 'z' );
- tick( 30 );
} );
sequence = [];
- tick( 1000 );
- assert.deepEqual( sequence, [ 'x', 'y' ] );
-
- sequence = [];
- tick( 1000 );
- assert.deepEqual( sequence, [ 'z' ] );
-
- sequence = [];
- tick( 1000 );
- assert.deepEqual( sequence, [] );
+ this.tick();
+ assert.deepEqual( sequence, [ 'x', 'y', 'z' ] );
} );
- // Schedule new callbacks within a callback that tick
- // the clock. If the budget is exceeded, the newly scheduled
- // task is delayed until the next idle period.
- QUnit.test( 'nest-tick', 3, function ( assert ) {
- var sequence,
- tick = this.tick;
+ QUnit.test( 'nested', function ( assert ) {
+ var sequence;
mw.requestIdleCallback( function () {
sequence.push( 'x' );
- tick( 30 );
} );
// Task Y is a task that schedules another task.
mw.requestIdleCallback( function () {
function other() {
sequence.push( 'y' );
- tick( 35 );
}
mw.requestIdleCallback( other );
} );
mw.requestIdleCallback( function () {
sequence.push( 'z' );
- tick( 30 );
} );
sequence = [];
- tick( 1000 );
+ this.tick();
assert.deepEqual( sequence, [ 'x', 'z' ] );
sequence = [];
- tick( 1000 );
+ this.tick();
assert.deepEqual( sequence, [ 'y' ] );
-
- sequence = [];
- tick( 1000 );
- assert.deepEqual( sequence, [] );
} );
- // Schedule new callbacks within a callback that run quickly.
- // Note how the newly scheduled task gets to run as part of the
- // current idle period (budget allowing).
- QUnit.test( 'nest-quick', 2, function ( assert ) {
+ QUnit.test( 'timeRemaining', function ( assert ) {
var sequence,
- tick = this.tick;
-
- mw.requestIdleCallback( function () {
- sequence.push( 'x' );
- mw.requestIdleCallback( function () {
- sequence.push( 'x-expand' );
- } );
- } );
- mw.requestIdleCallback( function () {
- sequence.push( 'y' );
+ tick = this.tick,
+ jobs = [
+ { time: 10, key: 'a' },
+ { time: 20, key: 'b' },
+ { time: 10, key: 'c' },
+ { time: 20, key: 'd' },
+ { time: 10, key: 'e' }
+ ];
+
+ mw.requestIdleCallback( function doWork( deadline ) {
+ var job;
+ while ( jobs[ 0 ] && deadline.timeRemaining() > 15 ) {
+ job = jobs.shift();
+ tick( job.time );
+ sequence.push( job.key );
+ }
+ if ( jobs[ 0 ] ) {
+ mw.requestIdleCallback( doWork );
+ }
} );
sequence = [];
- tick( 1000 );
- assert.deepEqual( sequence, [ 'x', 'y', 'x-expand' ] );
+ tick();
+ assert.deepEqual( sequence, [ 'a', 'b', 'c' ] );
sequence = [];
- tick( 1000 );
- assert.deepEqual( sequence, [] );
+ tick();
+ assert.deepEqual( sequence, [ 'd', 'e' ] );
} );
+ if ( window.requestIdleCallback ) {
+ QUnit.test( 'native', function ( assert ) {
+ var done = assert.async();
+ // Remove polyfill and clock stub
+ mw.requestIdleCallback.restore();
+ this.clock.restore();
+ mw.requestIdleCallback( function () {
+ assert.expect( 0 );
+ done();
+ } );
+ } );
+ }
+
}( mediaWiki ) );