201 lines
6.1 KiB
JavaScript
201 lines
6.1 KiB
JavaScript
/*!
|
|
* VisualEditor DataModel ResourceQueue tests.
|
|
*
|
|
* @copyright 2011-2018 VisualEditor Team and others; see http://ve.mit-license.org
|
|
*/
|
|
|
|
QUnit.module( 'mediawiki.widgets.APIResultsQueue' );
|
|
|
|
( function () {
|
|
let itemCounter = 0;
|
|
const FullResourceProvider = function ( config ) {
|
|
this.timer = null;
|
|
this.responseDelay = 1;
|
|
// Inheritance
|
|
FullResourceProvider.super.call( this, '', config );
|
|
};
|
|
const EmptyResourceProvider = function ( config ) {
|
|
this.timer = null;
|
|
this.responseDelay = 1;
|
|
// Inheritance
|
|
EmptyResourceProvider.super.call( this, '', config );
|
|
};
|
|
const SingleResultResourceProvider = function ( config ) {
|
|
this.timer = null;
|
|
this.responseDelay = 1;
|
|
// Inheritance
|
|
SingleResultResourceProvider.super.call( this, '', config );
|
|
};
|
|
|
|
OO.inheritClass( FullResourceProvider, mw.widgets.APIResultsProvider );
|
|
OO.inheritClass( EmptyResourceProvider, mw.widgets.APIResultsProvider );
|
|
OO.inheritClass( SingleResultResourceProvider, mw.widgets.APIResultsProvider );
|
|
|
|
FullResourceProvider.prototype.getResults = function ( howMany ) {
|
|
const result = [],
|
|
deferred = $.Deferred();
|
|
|
|
let i;
|
|
for ( i = itemCounter; i < itemCounter + howMany; i++ ) {
|
|
result.push( 'result ' + ( i + 1 ) );
|
|
}
|
|
itemCounter = i;
|
|
|
|
const timer = setTimeout(
|
|
() => {
|
|
// Always resolve with some values
|
|
deferred.resolve( result );
|
|
},
|
|
this.responseDelay );
|
|
|
|
return deferred.promise( { abort: function () {
|
|
clearTimeout( timer );
|
|
} } );
|
|
};
|
|
|
|
EmptyResourceProvider.prototype.getResults = function () {
|
|
const provider = this,
|
|
deferred = $.Deferred(),
|
|
timer = setTimeout(
|
|
() => {
|
|
provider.toggleDepleted( true );
|
|
// Always resolve with empty value
|
|
deferred.resolve( [] );
|
|
},
|
|
this.responseDelay );
|
|
|
|
return deferred.promise( { abort: function () {
|
|
clearTimeout( timer );
|
|
} } );
|
|
};
|
|
|
|
SingleResultResourceProvider.prototype.getResults = function ( howMany ) {
|
|
const provider = this,
|
|
deferred = $.Deferred();
|
|
|
|
const timer = setTimeout(
|
|
() => {
|
|
provider.toggleDepleted( howMany > 1 );
|
|
// Always resolve with one value
|
|
deferred.resolve( [ 'one result (' + ( itemCounter++ + 1 ) + ')' ] );
|
|
},
|
|
this.responseDelay );
|
|
|
|
return deferred.promise( { abort: function () {
|
|
clearTimeout( timer );
|
|
} } );
|
|
};
|
|
|
|
/* Tests */
|
|
|
|
QUnit.test( 'Query providers', ( assert ) => {
|
|
const done = assert.async(),
|
|
providers = [
|
|
new FullResourceProvider(),
|
|
new EmptyResourceProvider(),
|
|
new SingleResultResourceProvider()
|
|
],
|
|
queue = new mw.widgets.APIResultsQueue( {
|
|
threshold: 2
|
|
} );
|
|
|
|
// Add providers to queue
|
|
queue.setProviders( providers );
|
|
|
|
// Set parameters and fetch
|
|
queue.setParams( { foo: 'bar' } );
|
|
|
|
queue.get( 10 )
|
|
.then( ( data ) => {
|
|
// Check that we received all requested results
|
|
assert.strictEqual( data.length, 10, 'Query 1: Results received.' );
|
|
// We've asked for 10 items + 2 threshold from all providers.
|
|
// Provider 1 returned 12 results
|
|
// Provider 2 returned 0 results
|
|
// Provider 3 returned 1 results
|
|
// Overall 13 results. 10 were retrieved. 3 left in queue.
|
|
assert.strictEqual( queue.getQueueSize(), 3, 'Query 1: Remaining queue size.' );
|
|
|
|
// Check if sources are depleted
|
|
assert.strictEqual( providers[ 0 ].isDepleted(), false, 'Query 1: Full provider not depleted.' );
|
|
assert.strictEqual( providers[ 1 ].isDepleted(), true, 'Query 1: Empty provider is depleted.' );
|
|
assert.strictEqual( providers[ 2 ].isDepleted(), true, 'Query 1: Single result provider is depleted.' );
|
|
|
|
// Ask for more results
|
|
return queue.get( 10 );
|
|
} )
|
|
.then( ( data1 ) => {
|
|
// This time, only provider 1 was queried, because the other
|
|
// two were marked as depleted.
|
|
// * We asked for 10 items
|
|
// * There are currently 3 items in the queue
|
|
// * The queue queried provider #1 for 12 items
|
|
// * The queue returned 10 results as requested
|
|
// * 5 results are now left in the queue.
|
|
assert.strictEqual( data1.length, 10, 'Query 1: Second set of results received.' );
|
|
assert.strictEqual( queue.getQueueSize(), 5, 'Query 1: Remaining queue size.' );
|
|
|
|
// Change the query
|
|
queue.setParams( { foo: 'baz' } );
|
|
// Check if sources are depleted
|
|
assert.strictEqual( providers[ 0 ].isDepleted(), false, 'Query 2: Full provider not depleted.' );
|
|
assert.strictEqual( providers[ 1 ].isDepleted(), false, 'Query 2: Empty provider not depleted.' );
|
|
assert.strictEqual( providers[ 2 ].isDepleted(), false, 'Query 2: Single result provider not depleted.' );
|
|
|
|
return queue.get( 10 );
|
|
} )
|
|
.then( ( data2 ) => {
|
|
// This should be the same as the very first result
|
|
assert.strictEqual( data2.length, 10, 'Query 2: Results received.' );
|
|
assert.strictEqual( queue.getQueueSize(), 3, 'Query 2: Remaining queue size.' );
|
|
// Check if sources are depleted
|
|
assert.strictEqual( providers[ 0 ].isDepleted(), false, 'Query 2: Full provider not depleted.' );
|
|
assert.strictEqual( providers[ 1 ].isDepleted(), true, 'Query 2: Empty provider is not depleted.' );
|
|
assert.strictEqual( providers[ 2 ].isDepleted(), true, 'Query 2: Single result provider is not depleted.' );
|
|
} )
|
|
// Finish the async test
|
|
.then( done );
|
|
} );
|
|
|
|
QUnit.test( 'Abort providers', ( assert ) => {
|
|
const done = assert.async(),
|
|
biggerQueue = new mw.widgets.APIResultsQueue( {
|
|
threshold: 5
|
|
} ),
|
|
providers = [
|
|
new FullResourceProvider(),
|
|
new EmptyResourceProvider(),
|
|
new SingleResultResourceProvider()
|
|
];
|
|
let completed = false;
|
|
|
|
// Make the delay higher
|
|
providers.forEach( ( provider ) => {
|
|
provider.responseDelay = 3;
|
|
} );
|
|
|
|
// Add providers to queue
|
|
biggerQueue.setProviders( providers );
|
|
|
|
biggerQueue.setParams( { foo: 'bar' } );
|
|
biggerQueue.get( 100 )
|
|
.always( () => {
|
|
// This should only run if the promise wasn't aborted
|
|
completed = true;
|
|
} );
|
|
|
|
// Make the delay higher
|
|
providers.forEach( ( provider ) => {
|
|
provider.responseDelay = 5;
|
|
} );
|
|
|
|
biggerQueue.setParams( { foo: 'baz' } );
|
|
biggerQueue.get( 10 )
|
|
.then( () => {
|
|
assert.strictEqual( completed, false, 'Provider promises aborted.' );
|
|
} )
|
|
// Finish the async test
|
|
.then( done );
|
|
} );
|
|
}() );
|