jenkins-bot has submitted this change and it was merged. ( 
https://gerrit.wikimedia.org/r/344885 )

Change subject: tests: Don't assume 1 wait call per test
......................................................................


tests: Don't assume 1 wait call per test

The delay/timeout logic in actions#fetch will require more than one wait
call, for example.

Changes:
* Update the stub created in setupWait to store all deferred-promise
  pairs and update the integration tests so that they don't use the stub
  accidentally.
* Remove all references to the waitDeferred/waitPromise properties.
* Fix tests that relied on the waitDeferred/waitPromise properties being
  available regardless of whether wait had been called.
* Update outdated or brittle - in the sense that it didn't reference
  constants but their values - inline documentation.

Change-Id: I94345cdf4126b6c540d4fb8135a7a7e4d0507bed
---
M tests/node-qunit/actions.test.js
M tests/node-qunit/integration.test.js
2 files changed, 78 insertions(+), 52 deletions(-)

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



diff --git a/tests/node-qunit/actions.test.js b/tests/node-qunit/actions.test.js
index 6a42800..5798979 100644
--- a/tests/node-qunit/actions.test.js
+++ b/tests/node-qunit/actions.test.js
@@ -66,9 +66,18 @@
        * @param {Object} module
        */
 function setupWait( module ) {
-       module.waitDeferred = $.Deferred();
-       module.waitPromise = module.waitDeferred.promise();
-       module.wait = module.sandbox.stub().returns( module.waitPromise );
+       module.waitDeferreds = [];
+       module.waitPromises = [];
+
+       module.wait = module.sandbox.spy( function () {
+               var deferred = $.Deferred(),
+                       promise = deferred.promise();
+
+               module.waitDeferreds.push( deferred );
+               module.waitPromises.push( promise );
+
+               return promise;
+       } );
 
        mock( '../../src/wait', module.wait );
        // Re-require actions so that it uses the mocked wait module
@@ -101,7 +110,7 @@
                        return that.state;
                };
 
-               // Fake implementation of mw.now
+               // The worst-case implementation of mw.now.
                mw.now = function () { return Date.now(); };
 
                setupWait( this );
@@ -120,7 +129,7 @@
        this.sandbox.stub( mw, 'now' ).returns( new Date() );
        this.sandbox.stub( actions, 'fetch' );
 
-       // Set the state for when dispatch is called. New token is accepted
+       // Stub the state tree being updated by the LINK_DWELL action.
        this.state.preview = {
                activeToken: generateToken()
        };
@@ -147,18 +156,18 @@
 
        // ---
 
-       this.waitPromise.then( function () {
+       this.waitPromises[ 0 ].then( function () {
                assert.strictEqual(
                        dispatch.callCount,
                        2,
-                       'The fetch action is dispatched after 50 ms'
+                       'The fetch action is dispatched after FETCH_COMPLETE 
milliseconds.'
                );
 
                done();
        } );
 
-       // After 50 ms...
-       this.waitDeferred.resolve();
+       // After FETCH_START_DELAY milliseconds...
+       this.waitDeferreds[ 0 ].resolve();
 } );
 
 QUnit.test( '#linkDwell doesn\'t continue when previews are disabled', 
function ( assert ) {
@@ -166,23 +175,28 @@
                event = {},
                dispatch = this.sandbox.spy();
 
+       // Stub the state tree being updated by the LINK_DWELL action.
+       this.state.preview = {
+               enabled: false,
+               activeLink: this.el,
+               activeToken: generateToken()
+       };
+
        actions.linkDwell( this.el, event, /* gateway = */ null, generateToken 
)(
                dispatch,
                this.getState
        );
 
-       this.state.preview = {
-               enabled: false
-       };
+       assert.strictEqual( this.wait.callCount, 1 );
 
-       this.waitPromise.then( function () {
+       this.waitPromises[ 0 ].then( function () {
                assert.strictEqual( dispatch.callCount, 1 );
 
                done();
        } );
 
-       // After 500 ms...
-       this.waitDeferred.resolve();
+       // After FETCH_START_DELAY milliseconds...
+       this.waitDeferreds[ 0 ].resolve();
 } );
 
 QUnit.test( '#linkDwell doesn\'t continue if the token has changed', function 
( assert ) {
@@ -190,11 +204,19 @@
                event = {},
                dispatch = this.sandbox.spy();
 
+       // Stub the state tree being updated by a LINK_DWELL action.
+       this.state.preview = {
+               enabled: true,
+               activeLink: this.el,
+               activeToken: generateToken()
+       };
+
        actions.linkDwell( this.el, event, /* gateway = */ null, generateToken 
)(
                dispatch,
                this.getState
        );
 
+       // Stub the state tree being updated by another LINK_DWELL action.
        this.state.preview = {
                enabled: true,
 
@@ -203,26 +225,27 @@
                // changed, but the active token has.
                activeLink: this.el,
 
-               activeToken: '0123456789'
+               activeToken: 'banana'
        };
 
-       this.waitPromise.then( function () {
+       this.waitPromises[ 0 ].then( function () {
                assert.strictEqual( dispatch.callCount, 1 );
 
                done();
        } );
 
-       // After 500 ms...
-       this.waitDeferred.resolve();
+       // After FETCH_START_DELAY milliseconds...
+       this.waitDeferreds[ 0 ].resolve();
 } );
 
-QUnit.test( '#linkDwell doesn\'t continue if the interaction is the same one', 
function ( assert ) {
+QUnit.test( '#linkDwell dispatches the fetch action', function ( assert ) {
        var done = assert.async(),
                event = {},
                dispatch = this.sandbox.spy();
 
        this.state.preview = {
-               activeToken: '0123456789'
+               enabled: true,
+               activeToken: generateToken()
        };
 
        actions.linkDwell( this.el, event, /* gateway = */ null, generateToken 
)(
@@ -230,14 +253,14 @@
                this.getState
        );
 
-       this.waitPromise.then( function () {
-               assert.strictEqual( dispatch.callCount, 1 );
+       this.waitPromises[ 0 ].then( function () {
+               assert.strictEqual( dispatch.callCount, 2 );
 
                done();
        } );
 
-       // After 500 ms...
-       this.waitDeferred.resolve();
+       // After FETCH_START_DELAY milliseconds...
+       this.waitDeferreds[ 0 ].resolve();
 } );
 
 QUnit.module( 'ext.popups/actions#fetch', {
@@ -293,54 +316,52 @@
                result = {},
                done = assert.async( 2 );
 
-       assert.expect( 4 );
+       assert.expect( 3 );
 
        this.fetch();
 
        this.gatewayPromise.then( function () {
+               assert.deepEqual(
+                       that.dispatch.getCall( 1 ).args[ 0 ],
+                       {
+                               type: 'FETCH_END',
+                               el: that.el,
+                               timestamp: 250
+                       },
+                       'It should dispatch the FETCH_END action when the 
gateway request ends.'
+               );
+
                assert.ok(
                        that.wait.calledWith( 250 ),
                        'FETCH_COMPLETE is delayed by 250 (500 - 250) ms. ' +
                        'If you\'ve changed FETCH_COMPLETE_TARGET_DELAY, then 
have you spoken with #Design about changing this value?'
                );
 
-               that.waitDeferred.resolve();
-
                done();
        } );
 
-       this.waitPromise.then( function () {
-               // Let the wait.then execute to run the dispatch before 
asserting
-               setTimeout( function () {
-                       assert.equal( that.dispatch.callCount, 3, 'dispatch 
called for start and end' );
-                       assert.deepEqual(
-                               that.dispatch.getCall( 1 ).args[ 0 ],
-                               {
-                                       type: 'FETCH_END',
-                                       el: that.el,
-                                       timestamp: 250
-                               },
-                               'It should dispatch the FETCH_END action when 
the gateway request ends.'
-                       );
+       this.now += 250;
+       this.gatewayDeferred.resolve( result );
 
+       this.waitPromises[ 0 ].then( function () {
+               setTimeout( function () {
                        assert.deepEqual(
                                that.dispatch.getCall( 2 ).args[ 0 ],
                                {
                                        type: 'FETCH_COMPLETE',
                                        el: that.el,
-                                       result: result,
-                                       timestamp: 250
+                                       timestamp: 500,
+                                       result: {}
                                },
-                               'It should dispatch the FETCH_COMPLETE action 
when the preview model is resolved.'
+                               'It should dispatch the FETCH_END action when 
the gateway request ends.'
                        );
 
                        done();
                } );
        } );
 
-       // The API request took 250 ms.
        this.now += 250;
-       this.gatewayDeferred.resolve( result );
+       this.waitDeferreds[ 0 ].resolve();
 } );
 
 QUnit.test(
@@ -403,7 +424,7 @@
                'Have you spoken with #Design about changing this value?'
        );
 
-       this.waitPromise.then( function () {
+       this.waitPromises[ 0 ].then( function () {
                assert.ok(
                        dispatch.calledWith( {
                                type: 'ABANDON_END',
@@ -415,8 +436,8 @@
                done();
        } );
 
-       // After 300 ms...
-       this.waitDeferred.resolve();
+       // After ABANDON_END_DELAY milliseconds...
+       this.waitDeferreds[ 0 ].resolve();
 } );
 
 QUnit.module( 'ext.popups/actions#saveSettings' );
diff --git a/tests/node-qunit/integration.test.js 
b/tests/node-qunit/integration.test.js
index 1bbc84c..3584895 100644
--- a/tests/node-qunit/integration.test.js
+++ b/tests/node-qunit/integration.test.js
@@ -1,7 +1,8 @@
 var mock = require( 'mock-require' ),
        Redux = require( 'redux' ),
        ReduxThunk = require( 'redux-thunk' ),
-       wait = require( '../../src/wait' );
+       wait = require( '../../src/wait' ),
+       mw = mediaWiki;
 
 function identity( x ) { return x; }
 function constant( x ) { return function () { return x; }; }
@@ -45,6 +46,9 @@
                var that = this,
                        reducers, actions, registerChangeListener;
 
+               // The worst-case implementation of mw.now.
+               mw.now = function () { return Date.now(); };
+
                this.resetWait = function () {
                        that.waitDeferred = $.Deferred();
                        that.waitPromise = that.waitDeferred.promise();
@@ -56,9 +60,10 @@
 
                mock( '../../src/wait', this.wait );
 
-               // Require modules after the setting require mocks
+               // Require modules after the setting require mocks, 
invalidating the
+               // require cache for modules that depend on the wait function.
+               actions = mock.reRequire( '../../src/actions' );
                reducers = require( '../../src/reducers' );
-               actions = require( '../../src/actions' );
                registerChangeListener = require( '../../src/changeListener' );
 
                this.store = Redux.createStore(

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

Gerrit-MessageType: merged
Gerrit-Change-Id: I94345cdf4126b6c540d4fb8135a7a7e4d0507bed
Gerrit-PatchSet: 5
Gerrit-Project: mediawiki/extensions/Popups
Gerrit-Branch: master
Gerrit-Owner: Phuedx <[email protected]>
Gerrit-Reviewer: Jhernandez <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to