jenkins-bot has submitted this change and it was merged.

Change subject: Create APIResultsProvider and APIResultsQueue and add tests
......................................................................


Create APIResultsProvider and APIResultsQueue and add tests

Generalize ResultsQueue and ResultsProvider downstream and
create unit tests.

Change-Id: I5346081317ef7195020b52deae322d70af80cae6
---
M .docs/categories.json
M .docs/eg-iframe.html
M build/modules.json
M demos/ve/desktop.html
M demos/ve/mobile.html
A src/dm/ve.dm.APIResultsProvider.js
A src/dm/ve.dm.APIResultsQueue.js
A tests/dm/ve.dm.APIResultsQueue.test.js
M tests/index.html
9 files changed, 629 insertions(+), 0 deletions(-)

Approvals:
  Esanders: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/.docs/categories.json b/.docs/categories.json
index b82b54c..da35277 100644
--- a/.docs/categories.json
+++ b/.docs/categories.json
@@ -41,6 +41,8 @@
                                        "ve.dm.DocumentSynchronizer",
                                        "ve.dm.IndexValueStore",
                                        "ve.dm.Scalable",
+                                       "ve.dm.APIResultsProvider",
+                                       "ve.dm.APIResultsQueue",
                                        "ve.dm.NodeFactory",
                                        "ve.dm.Surface",
                                        "ve.dm.SurfaceFragment",
diff --git a/.docs/eg-iframe.html b/.docs/eg-iframe.html
index 3159c0e..e0fe8ce 100644
--- a/.docs/eg-iframe.html
+++ b/.docs/eg-iframe.html
@@ -146,6 +146,8 @@
                <script src="../src/dm/ve.dm.AlignableNode.js"></script>
                <script src="../src/dm/ve.dm.FocusableNode.js"></script>
                <script src="../src/dm/ve.dm.Scalable.js"></script>
+               <script src="../src/dm/ve.dm.APIResultsProvider.js"></script>
+               <script src="../src/dm/ve.dm.APIResultsQueue.js"></script>
                <script src="../src/dm/ve.dm.ResizableNode.js"></script>
                <script src="../src/dm/ve.dm.Node.js"></script>
                <script src="../src/dm/ve.dm.BranchNode.js"></script>
diff --git a/build/modules.json b/build/modules.json
index 981741b..f8bcaec 100644
--- a/build/modules.json
+++ b/build/modules.json
@@ -169,6 +169,8 @@
                        "src/dm/ve.dm.AlignableNode.js",
                        "src/dm/ve.dm.FocusableNode.js",
                        "src/dm/ve.dm.Scalable.js",
+                       "src/dm/ve.dm.APIResultsProvider.js",
+                       "src/dm/ve.dm.APIResultsQueue.js",
                        "src/dm/ve.dm.ResizableNode.js",
                        "src/dm/ve.dm.Node.js",
                        "src/dm/ve.dm.BranchNode.js",
@@ -451,6 +453,7 @@
                        "tests/dm/ve.dm.LinearData.test.js",
                        "tests/dm/ve.dm.Transaction.test.js",
                        "tests/dm/ve.dm.TransactionProcessor.test.js",
+                       "tests/dm/ve.dm.APIResultsQueue.test.js",
                        "tests/dm/ve.dm.Surface.test.js",
                        "tests/dm/ve.dm.SurfaceFragment.test.js",
                        "tests/dm/ve.dm.ModelRegistry.test.js",
diff --git a/demos/ve/desktop.html b/demos/ve/desktop.html
index 8b356c9..a266c87 100644
--- a/demos/ve/desktop.html
+++ b/demos/ve/desktop.html
@@ -158,6 +158,8 @@
                <script src="../../src/dm/ve.dm.AlignableNode.js"></script>
                <script src="../../src/dm/ve.dm.FocusableNode.js"></script>
                <script src="../../src/dm/ve.dm.Scalable.js"></script>
+               <script src="../../src/dm/ve.dm.APIResultsProvider.js"></script>
+               <script src="../../src/dm/ve.dm.APIResultsQueue.js"></script>
                <script src="../../src/dm/ve.dm.ResizableNode.js"></script>
                <script src="../../src/dm/ve.dm.Node.js"></script>
                <script src="../../src/dm/ve.dm.BranchNode.js"></script>
diff --git a/demos/ve/mobile.html b/demos/ve/mobile.html
index a4fcf15..289f96c 100644
--- a/demos/ve/mobile.html
+++ b/demos/ve/mobile.html
@@ -159,6 +159,8 @@
                <script src="../../src/dm/ve.dm.AlignableNode.js"></script>
                <script src="../../src/dm/ve.dm.FocusableNode.js"></script>
                <script src="../../src/dm/ve.dm.Scalable.js"></script>
+               <script src="../../src/dm/ve.dm.APIResultsProvider.js"></script>
+               <script src="../../src/dm/ve.dm.APIResultsQueue.js"></script>
                <script src="../../src/dm/ve.dm.ResizableNode.js"></script>
                <script src="../../src/dm/ve.dm.Node.js"></script>
                <script src="../../src/dm/ve.dm.BranchNode.js"></script>
diff --git a/src/dm/ve.dm.APIResultsProvider.js 
b/src/dm/ve.dm.APIResultsProvider.js
new file mode 100644
index 0000000..81e53c8
--- /dev/null
+++ b/src/dm/ve.dm.APIResultsProvider.js
@@ -0,0 +1,220 @@
+/*!
+ * VisualEditor DataModel ResourceProvider class.
+ *
+ * @copyright 2011-2015 VisualEditor Team and others; see 
http://ve.mit-license.org
+ */
+
+/**
+ * Resource Provider object.
+ *
+ * @class
+ * @mixins OO.EventEmitter
+ *
+ * @constructor
+ * @param {string} apiurl The URL to the api
+ * @param {Object} [config] Configuration options
+ * @cfg {number} fetchLimit The default number of results to fetch
+ * @cfg {string} lang The language of the API
+ * @cfg {number} offset Initial offset, if relevant, to call results from
+ * @cfg {Object} ajaxSettings The settings for the ajax call
+ * @cfg {Object} staticParams The data parameters that are static and should
+ *  always be sent to the API request, as opposed to user parameters.
+ * @cfg {Object} userParams Initial user parameters to be sent as data to
+ *  the API request. These can change per request, like the search query term
+ *  or sizing parameters for images, etc.
+ */
+ve.dm.APIResultsProvider = function VeDmResourceProvider( apiurl, config ) {
+       config = config || {};
+
+       this.setAPIurl( apiurl );
+       this.fetchLimit = config.fetchLimit || 30;
+       this.lang = config.lang;
+       this.offset = config.offset || 0;
+       this.ajaxSettings = config.ajaxSettings || {};
+
+       this.staticParams = config.staticParams || {};
+       this.userParams = config.userParams || {};
+
+       this.toggleDepleted( false );
+
+       // Mixin constructors
+       OO.EventEmitter.call( this );
+};
+
+/* Setup */
+OO.mixinClass( ve.dm.APIResultsProvider, OO.EventEmitter );
+
+/* Methods */
+
+/**
+ * Get results from the source
+ *
+ * @param {number} howMany Number of results to ask for
+ * @return {jQuery.Promise} Promise that is resolved into an array
+ * of available results, or is rejected if no results are available.
+ */
+ve.dm.APIResultsProvider.prototype.getResults = function () {
+       var xhr,
+               deferred = $.Deferred(),
+               allParams = $.extend( {}, this.getStaticParams(), 
this.getUserParams() );
+
+       xhr = $.getJSON( this.getAPIurl(), allParams )
+               .done( function ( data ) {
+                       if (
+                               $.type( data ) !== 'array' ||
+                               (
+                                       $.type( data ) === 'array' &&
+                                       data.length === 0
+                               )
+                       ) {
+                               deferred.resolve();
+                       } else {
+                               deferred.resolve( data );
+                       }
+               } );
+       return deferred.promise( { abort: xhr.abort } );
+};
+
+/**
+ * Set API url
+ *
+ * @param {string} apiurl API url
+ */
+ve.dm.APIResultsProvider.prototype.setAPIurl = function ( apiurl ) {
+       this.apiurl = apiurl;
+};
+
+/**
+ * Set api url
+ *
+ * @returns {string} API url
+ */
+ve.dm.APIResultsProvider.prototype.getAPIurl = function () {
+       return this.apiurl;
+};
+
+/**
+ * Get the static, non-changing data parameters sent to the API
+ *
+ * @returns {Object} Data parameters
+ */
+ve.dm.APIResultsProvider.prototype.getStaticParams = function () {
+       return this.staticParams;
+};
+
+/**
+ * Get the user-inputted dybamic data parameters sent to the API
+ *
+ * @returns {Object} Data parameters
+ */
+ve.dm.APIResultsProvider.prototype.getUserParams = function () {
+       return this.userParams;
+};
+
+/**
+ * Set the data parameters sent to the API
+ *
+ * @param {Object} params User defined data parameters
+ */
+ve.dm.APIResultsProvider.prototype.setUserParams = function ( params ) {
+       // Assymetrically compare (params is subset of this.userParams)
+       if ( !ve.compare( params, this.userParams, true ) ) {
+               this.userParams = $.extend( {}, this.userParams, params );
+               // Reset offset
+               this.setOffset( 0 );
+               // Reset depleted status
+               this.toggleDepleted( false );
+       }
+};
+
+/**
+ * Get fetch limit or 'page' size. This is the number
+ * of results per request.
+ *
+ * @returns {number} limit
+ */
+ve.dm.APIResultsProvider.prototype.getDefaultFetchLimit = function () {
+       return this.limit;
+};
+
+/**
+ * Set limit
+ *
+ * @param {number} limit Default number of results to fetch from the API
+ */
+ve.dm.APIResultsProvider.prototype.setDefaultFetchLimit = function ( limit ) {
+       this.limit = limit;
+};
+
+/**
+ * Get provider API language
+ *
+ * @returns {string} Provider API language
+ */
+ve.dm.APIResultsProvider.prototype.getLang = function () {
+       return this.lang;
+};
+
+/**
+ * Set provider API language
+ *
+ * @param {string} lang Provider API language
+ */
+ve.dm.APIResultsProvider.prototype.setLang = function ( lang ) {
+       this.lang = lang;
+};
+
+/**
+ * Get result offset
+ *
+ * @returns {number} Offset Results offset for the upcoming request
+ */
+ve.dm.APIResultsProvider.prototype.getOffset = function () {
+       return this.offset;
+};
+
+/**
+ * Set result offset
+ *
+ * @param {number} Results offset for the upcoming request
+ */
+ve.dm.APIResultsProvider.prototype.setOffset = function ( offset ) {
+       this.offset = offset;
+};
+
+/**
+ * Check whether the provider is depleted and has no more results
+ * to hand off.
+ *
+ * @returns {boolean} The provider is depleted
+ */
+ve.dm.APIResultsProvider.prototype.isDepleted = function () {
+       return this.depleted;
+};
+
+/**
+ * Toggle depleted state
+ *
+ * @param {boolean} isDepleted The provider is depleted
+ */
+ve.dm.APIResultsProvider.prototype.toggleDepleted = function ( isDepleted ) {
+       this.depleted = isDepleted !== undefined ? isDepleted : !this.depleted;
+};
+
+/**
+ * Get the default ajax settings
+ *
+ * @returns {Object} Ajax settings
+ */
+ve.dm.APIResultsProvider.prototype.getAjaxSettings = function () {
+       return this.ajaxSettings;
+};
+
+/**
+ * Get the default ajax settings
+ *
+ * @param {Object} settings Ajax settings
+ */
+ve.dm.APIResultsProvider.prototype.setAjaxSettings = function ( settings ) {
+       this.ajaxSettings = settings;
+};
diff --git a/src/dm/ve.dm.APIResultsQueue.js b/src/dm/ve.dm.APIResultsQueue.js
new file mode 100644
index 0000000..2e491fd
--- /dev/null
+++ b/src/dm/ve.dm.APIResultsQueue.js
@@ -0,0 +1,204 @@
+/*!
+ * VisualEditor DataModel ResourceQueue class.
+ *
+ * @copyright 2011-2015 VisualEditor Team and others; see 
http://ve.mit-license.org
+ */
+
+/**
+ * Resource Queue object.
+ *
+ * @class
+ * @mixins OO.EventEmitter
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {number} limit The default number of results to fetch
+ * @cfg {number} threshold The default number of extra results
+ *  that the queue should always strive to have on top of the
+ *  individual requests for items.
+ */
+ve.dm.APIResultsQueue = function VeDmResourceQueue( config ) {
+       config = config || {};
+
+       this.fileRepoPromise = null;
+       this.providers = [];
+       this.providerPromises = [];
+       this.queue = [];
+
+       this.params = {};
+
+       this.limit = config.limit || 20;
+       this.setThreshold( config.threshold || 10 );
+
+       // Mixin constructors
+       OO.EventEmitter.call( this );
+};
+
+/* Setup */
+OO.mixinClass( ve.dm.APIResultsQueue, OO.EventEmitter );
+
+/* Methods */
+
+/**
+ * Set up the queue and its resources.
+ * This should be overrided if there are any setup steps to perform.
+ *
+ * @return {jQuery.Promise} Promise that resolves when the resources
+ *  are set up. Note: The promise must have an .abort() functionality.
+ */
+ve.dm.APIResultsQueue.prototype.setup = function () {
+       return $.Deferred().resolve().promise( { abort: $.noop } );
+};
+
+/**
+ * Get items from the queue
+ *
+ * @param {number} [howMany] How many items to retrieve. Defaults to the
+ *  default limit supplied on initialization.
+ * @return {jQuery.Promise} Promise that resolves into an array of items.
+ */
+ve.dm.APIResultsQueue.prototype.get = function ( howMany ) {
+       var fetchingPromise = null,
+               me = this;
+
+       howMany = howMany || this.limit;
+
+       // Check if the queue has enough items
+       if ( this.queue.length < howMany + this.threshold ) {
+               // Call for more results
+               fetchingPromise = this.queryProviders( howMany + this.threshold 
)
+                       .then( function ( items ) {
+                               // Add to the queue
+                               me.queue = me.queue.concat.apply( me.queue, 
items );
+                       } );
+       }
+
+       return $.when( fetchingPromise )
+               .then( function () {
+                       return me.queue.splice( 0, howMany );
+               } );
+
+};
+
+/**
+ * Get results from all providers
+ *
+ * @param {number} [howMany] How many items to retrieve. Defaults to the
+ *  default limit supplied on initialization.
+ * @return {jQuery.Promise} Promise that is resolved into an array
+ *  of fetched items. Note: The promise must have an .abort() functionality.
+ */
+ve.dm.APIResultsQueue.prototype.queryProviders = function ( howMany ) {
+       var i, len,
+               queue = this;
+
+       // Make sure there are resources set up
+       return this.setup()
+               .then( function () {
+                       // Abort previous requests
+                       for ( i = 0, len = queue.providerPromises.length; i < 
len; i++ ) {
+                               queue.providerPromises[i].abort();
+                       }
+                       queue.providerPromises = [];
+                       // Set up the query to all providers
+                       for ( i = 0, len = queue.providers.length; i < len; i++ 
) {
+                               if ( !queue.providers[i].isDepleted() ) {
+                                       queue.providerPromises.push(
+                                               queue.providers[i].getResults( 
howMany )
+                                       );
+                               }
+                       }
+
+                       return $.when.apply( $, queue.providerPromises )
+                               .then( Array.prototype.concat.bind( [] ) );
+               } );
+};
+
+/**
+ * Set the search query for all the providers.
+ *
+ * This also makes sure to abort any previous promises.
+ *
+ * @param {Object} params API search parameters
+ */
+ve.dm.APIResultsQueue.prototype.setParams = function ( params ) {
+       var i, len;
+       if ( !ve.compare( params, this.params, true ) ) {
+               this.params = ve.extendObject( this.params, params );
+               // Reset queue
+               this.queue = [];
+               // Reset promises
+               for ( i = 0, len = this.providerPromises.length; i < len; i++ ) 
{
+                       this.providerPromises[i].abort();
+               }
+               // Change queries
+               for ( i = 0, len = this.providers.length; i < len; i++ ) {
+                       this.providers[i].setUserParams( this.params );
+               }
+       }
+};
+
+/**
+ * Get the data parameters sent to the API
+ *
+ * @returns {Object} params API search parameters
+ */
+ve.dm.APIResultsQueue.prototype.getParams = function () {
+       return this.params;
+};
+
+/**
+ * Set the providers
+ *
+ * @param {ve.dm.APIResultsProvider[]} providers An array of providers
+ */
+ve.dm.APIResultsQueue.prototype.setProviders = function ( providers ) {
+       this.providers = providers;
+};
+
+/**
+ * Add a provbider to the group
+ *
+ * @param {ve.dm.APIResultsProvider} provider A provider object
+ */
+ve.dm.APIResultsQueue.prototype.addProvider = function ( provider ) {
+       this.providers.push( provider );
+};
+
+/**
+ * Set the providers
+ *
+ * @returns {ve.dm.APIResultsProvider[]} providers An array of providers
+ */
+ve.dm.APIResultsQueue.prototype.getProviders = function () {
+       return this.providers;
+};
+
+/**
+ * Get the queue size
+ *
+ * @return {number} Queue size
+ */
+ve.dm.APIResultsQueue.prototype.getQueueSize = function () {
+       return this.queue.length;
+};
+
+/**
+ * Set queue threshold
+ *
+ * @param {number} threshold Queue threshold, below which we will
+ *  request more items
+ */
+ve.dm.APIResultsQueue.prototype.setThreshold = function ( threshold ) {
+       this.threshold = threshold;
+};
+
+/**
+ * Get queue threshold
+ *
+ * @returns {number} threshold Queue threshold, below which we will
+ *  request more items
+ */
+ve.dm.APIResultsQueue.prototype.getThreshold = function () {
+       return this.threshold;
+};
diff --git a/tests/dm/ve.dm.APIResultsQueue.test.js 
b/tests/dm/ve.dm.APIResultsQueue.test.js
new file mode 100644
index 0000000..4a185e0
--- /dev/null
+++ b/tests/dm/ve.dm.APIResultsQueue.test.js
@@ -0,0 +1,191 @@
+/*!
+ * VisualEditor DataModel ResourceQueue tests.
+ *
+ * @copyright 2011-2015 VisualEditor Team and others; see 
http://ve.mit-license.org
+ */
+
+QUnit.module( 've.dm.APIResultsQueue' );
+
+var itemCounter = 0,
+       responseDelay = 1000,
+       FullResourceProvider = function VeDmFullResourceProvider( config ) {
+               this.timer = null;
+               // Inheritance
+               ve.dm.APIResultsProvider.call( this, '', config );
+       },
+       EmptyResourceProvider = function VeDmEmptyResourceProvider( config ) {
+               this.timer = null;
+               // Inheritance
+               ve.dm.APIResultsProvider.call( this, '', config );
+       },
+       SingleResultResourceProvider = function 
VeDmSingleResultResourceProvider( config ) {
+               this.timer = null;
+               // Inheritance
+               ve.dm.APIResultsProvider.call( this, '', config );
+       };
+
+OO.inheritClass( FullResourceProvider, ve.dm.APIResultsProvider );
+OO.inheritClass( EmptyResourceProvider, ve.dm.APIResultsProvider );
+OO.inheritClass( SingleResultResourceProvider, ve.dm.APIResultsProvider );
+
+FullResourceProvider.prototype.getResults = function ( howMany ) {
+       var i, timer,
+               result = [],
+               deferred = $.Deferred();
+
+       for ( i = itemCounter; i < itemCounter + howMany; i++ ) {
+               result.push( 'result ' + ( i + 1 ) );
+       }
+       itemCounter = i;
+
+       timer = setTimeout(
+               function () {
+                       // Always resolve with some values
+                       deferred.resolve( result );
+               },
+               responseDelay );
+
+       return deferred.promise( { abort: function () { clearTimeout( timer ); 
} } );
+};
+
+EmptyResourceProvider.prototype.getResults = function () {
+       var me = this,
+               deferred = $.Deferred(),
+               timer = setTimeout(
+                       function () {
+                               me.toggleDepleted( true );
+                               // Always resolve with empty value
+                               deferred.resolve( [] );
+                       },
+                       responseDelay );
+
+       return deferred.promise( { abort: function () { clearTimeout( timer ); 
} } );
+};
+
+SingleResultResourceProvider.prototype.getResults = function ( howMany ) {
+       var timer,
+               me = this,
+               deferred = $.Deferred();
+
+       timer = setTimeout(
+               function () {
+                       me.toggleDepleted( howMany > 1 );
+                       // Always resolve with one value
+                       deferred.resolve( [ 'one result (' + ( itemCounter++ + 
1 ) + ')' ] );
+               },
+               responseDelay );
+
+       return deferred.promise( { abort: function () { clearTimeout( timer ); 
} } );
+};
+
+/* Tests */
+
+QUnit.test( 'Query providers', function ( assert ) {
+       var done = assert.async(),
+               providers = [
+                       new FullResourceProvider(),
+                       new EmptyResourceProvider(),
+                       new SingleResultResourceProvider()
+               ],
+               queue = new ve.dm.APIResultsQueue( {
+                       threshold: 2
+               } );
+
+       assert.expect( 15 );
+
+       // Add providers to queue
+       queue.setProviders( providers );
+
+       // Set parameters and fetch
+       queue.setParams( { foo: 'bar' } );
+
+       queue.get( 10 )
+               .then( function ( data ) {
+                       // Check that we received all requested results
+                       assert.equal( 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.equal( queue.getQueueSize(), 3, 'Query 1: 
Remaining queue size.' );
+
+                       // Check if sources are depleted
+                       assert.ok( !providers[ 0 ].isDepleted(), 'Query 1: Full 
provider not depleted.' );
+                       assert.ok( providers[ 1 ].isDepleted(), 'Query 1: Empty 
provider is depleted.' );
+                       assert.ok( providers[ 2 ].isDepleted(), 'Query 1: 
Single result provider is depleted.' );
+
+                       // Ask for more results
+                       return queue.get( 10 );
+               } )
+               .then( function ( 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.equal( data1.length, 10, 'Query 1: Second set of 
results received.' );
+                       assert.equal( queue.getQueueSize(), 5, 'Query 1: 
Remaining queue size.' );
+
+                       // Change the query
+                       queue.setParams( { foo: 'baz' } );
+                       // Check if sources are depleted
+                       assert.ok( !providers[ 0 ].isDepleted(), 'Query 2: Full 
provider not depleted.' );
+                       assert.ok( !providers[ 1 ].isDepleted(), 'Query 2: 
Empty provider not depleted.' );
+                       assert.ok( !providers[ 2 ].isDepleted(), 'Query 2: 
Single result provider not depleted.' );
+
+                       return queue.get( 10 );
+               } )
+               .then( function ( data2 ) {
+                       // This should be the same as the very first result
+                       assert.equal( data2.length, 10, 'Query 2: Results 
received.' );
+                       assert.equal( queue.getQueueSize(), 3, 'Query 2: 
Remaining queue size.' );
+                       // Check if sources are depleted
+                       assert.ok( !providers[ 0 ].isDepleted(), 'Query 2: Full 
provider not depleted.' );
+                       assert.ok( providers[ 1 ].isDepleted(), 'Query 2: Empty 
provider is not depleted.' );
+                       assert.ok( providers[ 2 ].isDepleted(), 'Query 2: 
Single result provider is not depleted.' );
+               } )
+               // Finish the async test
+               .then( done );
+} );
+
+QUnit.test( 'Abort providers', function ( assert ) {
+       var done = assert.async(),
+               completed = false,
+               biggerQueue = new ve.dm.APIResultsQueue( {
+                       threshold: 5
+               } ),
+               providers2 = [
+                       new FullResourceProvider(),
+                       new EmptyResourceProvider(),
+                       new SingleResultResourceProvider()
+               ];
+
+       assert.expect( 1 );
+
+       // Make the delay higher
+       responseDelay = 3000;
+
+       // Add providers to queue
+       biggerQueue.setProviders( providers2 );
+
+       biggerQueue.setParams( { foo: 'bar' } );
+       biggerQueue.get( 100 )
+               .always( function () {
+                       // This should only run if the promise wasn't aborted
+                       completed = true;
+               } );
+
+       // Make the delay higher
+       responseDelay = 5000;
+
+       biggerQueue.setParams( { foo: 'baz' } );
+       biggerQueue.get( 10 )
+               .then( function () {
+                       assert.ok( !completed, 'Provider promises aborted.' );
+               } )
+               // Finish the async test
+               .then( done );
+} );
diff --git a/tests/index.html b/tests/index.html
index 43bd38c..5e2f0ea 100644
--- a/tests/index.html
+++ b/tests/index.html
@@ -101,6 +101,8 @@
                <script src="../src/dm/ve.dm.AlignableNode.js"></script>
                <script src="../src/dm/ve.dm.FocusableNode.js"></script>
                <script src="../src/dm/ve.dm.Scalable.js"></script>
+               <script src="../src/dm/ve.dm.APIResultsProvider.js"></script>
+               <script src="../src/dm/ve.dm.APIResultsQueue.js"></script>
                <script src="../src/dm/ve.dm.ResizableNode.js"></script>
                <script src="../src/dm/ve.dm.Node.js"></script>
                <script src="../src/dm/ve.dm.BranchNode.js"></script>
@@ -345,6 +347,7 @@
                <script src="../tests/dm/ve.dm.LinearData.test.js"></script>
                <script src="../tests/dm/ve.dm.Transaction.test.js"></script>
                <script 
src="../tests/dm/ve.dm.TransactionProcessor.test.js"></script>
+               <script 
src="../tests/dm/ve.dm.APIResultsQueue.test.js"></script>
                <script src="../tests/dm/ve.dm.Surface.test.js"></script>
                <script 
src="../tests/dm/ve.dm.SurfaceFragment.test.js"></script>
                <script src="../tests/dm/ve.dm.ModelRegistry.test.js"></script>

-- 
To view, visit https://gerrit.wikimedia.org/r/189627
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I5346081317ef7195020b52deae322d70af80cae6
Gerrit-PatchSet: 15
Gerrit-Project: VisualEditor/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Mooeypoo <mor...@gmail.com>
Gerrit-Reviewer: Esanders <esand...@wikimedia.org>
Gerrit-Reviewer: Krinkle <krinklem...@gmail.com>
Gerrit-Reviewer: Mooeypoo <mor...@gmail.com>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to