Divec has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/277594

Change subject: Emulated setTimeout for unit testing
......................................................................

Emulated setTimeout for unit testing

Bug: T130064
Change-Id: I25f524836a182797d799e67321eda1f1f78bed12
---
M Gruntfile.js
A tests/TestTimer.js
M tests/core.test.js
3 files changed, 158 insertions(+), 52 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/oojs/ui refs/changes/94/277594/1

diff --git a/Gruntfile.js b/Gruntfile.js
index 5490b85..0632f79 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -404,6 +404,7 @@
                                        'dist/oojs-ui-apex.js',
                                        'dist/oojs-ui-mediawiki.js',
                                        'tests/QUnit.assert.equalDomElement.js',
+                                       'tests/TestTimer.js',
                                        'tests/**/*.test.js'
                                ],
                                reporters: [ 'dots' ],
diff --git a/tests/TestTimer.js b/tests/TestTimer.js
new file mode 100644
index 0000000..7c07670
--- /dev/null
+++ b/tests/TestTimer.js
@@ -0,0 +1,76 @@
+/*!
+ * OO UI TestTimer class.
+ *
+ * @copyright 2011-2016 OOjs UI Team and others; see http://ve.mit-license.org
+ */
+
+/**
+ * @class
+ *
+ * @constructor
+ */
+OO.ui.TestTimer = function TestTimer() {
+       this.pendingCalls = [];
+       this.nextId = 1;
+};
+
+/* Inheritance */
+
+OO.initClass( OO.ui.TestTimer );
+
+/* Methods */
+
+/**
+ * Emulated setTimeout; just pushes the call into a queue
+ *
+ * @param {Function} f The function to call
+ * @param {number} [timeout] Minimum wait time in ms
+ * @return {number} Timeout id for cancellation
+ */
+OO.ui.TestTimer.prototype.setTimeout = function ( f, timeout ) {
+       this.pendingCalls.push( {
+               id: this.nextId,
+               f: f,
+               timeout: timeout || 0
+       } );
+       return this.nextId++;
+};
+
+/**
+ * Emulated clearTimeout; just blanks the queued call function
+ *
+ * @param {number} id Timeout id for cancellation
+ */
+OO.ui.TestTimer.prototype.clearTimeout = function ( id ) {
+       this.pendingCalls.forEach( function ( call ) {
+               if ( call.id === id ) {
+                       call.f = null;
+               }
+       } );
+};
+
+/**
+ * Run queued calls
+ *
+ * @param {number} [interval] Apparent passed time since last call (defaults 
to infinite)
+ */
+OO.ui.TestTimer.prototype.runPending = function ( interval ) {
+       var calls, i, len, call;
+       calls = this.pendingCalls.splice( 0, this.pendingCalls.length ).sort( 
function ( a, b ) {
+               return a.timeout - b.timeout;
+       } );
+       for ( i = 0, len = calls.length; i < len; i++ ) {
+               call = calls[ i ];
+               if ( interval === undefined || call.timeout <= interval ) {
+                       if ( call.f ) {
+                               call.f();
+                       }
+               } else {
+                       this.pendingCalls.push( {
+                               id: call.id,
+                               f: call.f,
+                               timeout: call.timeout - interval
+                       } );
+               }
+       }
+};
diff --git a/tests/core.test.js b/tests/core.test.js
index c26f207..a3f517c 100644
--- a/tests/core.test.js
+++ b/tests/core.test.js
@@ -94,57 +94,86 @@
        }
 } );
 
-QUnit.asyncTest( 'debounce', 4, function ( assert ) {
-       var
-               realSetTimeout = window.setTimeout,
-               ourSetTimeout = function () {
-                       setTimeoutCalled++;
-                       return realSetTimeout.apply( window, arguments );
-               },
-               funCalled,
-               setTimeoutCalled,
-               fun = function () {
-                       funCalled++;
-               },
-               cases = [
-                       function () {
-                               var fun50 = OO.ui.debounce( fun, 50 );
-                               funCalled = 0;
-                               setTimeoutCalled = 0;
-                               window.setTimeout = ourSetTimeout;
-                               fun50();
-                               fun50();
-                               window.setTimeout = realSetTimeout;
-                               setTimeout( function () {
-                                       assert.strictEqual( setTimeoutCalled, 
2, 'wait=50: setTimeout was called twice' );
-                                       assert.strictEqual( funCalled, 1, 
'wait=50: debounced function was executed once' );
-                                       maybeFinishTest();
-                               }, 100 );
-                       },
-                       function () {
-                               var fun0 = OO.ui.debounce( fun );
-                               funCalled = 0;
-                               setTimeoutCalled = 0;
-                               window.setTimeout = ourSetTimeout;
-                               fun0();
-                               fun0();
-                               window.setTimeout = realSetTimeout;
-                               setTimeout( function () {
-                                       assert.strictEqual( setTimeoutCalled, 
1, 'wait=0: setTimeout was called once' );
-                                       assert.strictEqual( funCalled, 1, 
'wait=0: debounced function was executed once' );
-                                       maybeFinishTest();
-                               }, 100 );
-                       }
-               ],
-               casesDone = 0,
-               maybeFinishTest = function () {
-                       if ( casesDone === 2 ) {
-                               QUnit.start();
-                       } else {
-                               cases[ casesDone ]();
-                               casesDone++;
-                       }
-               };
+QUnit.test( 'debounce', 4, function ( assert ) {
+       var f,
+               log = [],
+               testTimer = new OO.ui.TestTimer(),
+               setTimeoutReal = window.setTimeout,
+               clearTimeoutReal = window.clearTimeout;
+       window.setTimeout = testTimer.setTimeout.bind( testTimer );
+       window.clearTimeout = testTimer.clearTimeout.bind( testTimer );
+       try {
+               f = OO.ui.debounce( log.push.bind( log ), 50 );
+               f( 1 );
+               testTimer.runPending( 20 );
+               log.push( 'a' );
+               f( 2 );
+               testTimer.runPending( 20 );
+               log.push( 'b' );
+               f( 3 );
+               testTimer.runPending( 20 );
+               log.push( 'c' );
+               f( 4 );
+               testTimer.runPending( 20 );
+               log.push( 'd' );
+               testTimer.runPending( 20 );
+               log.push( 'e' );
+               testTimer.runPending( 20 );
+               log.push( 'f' );
+               testTimer.runPending( 20 );
+               assert.deepEqual( log, [ 'a', 'b', 'c', 'd', 'e', 4, 'f' ], 
'debounce 50 ms' );
 
-       maybeFinishTest();
+               log = [];
+               f = OO.ui.debounce( log.push.bind( log ), 50, true );
+               f( 1 );
+               testTimer.runPending( 20 );
+               log.push( 'a' );
+               f( 2 );
+               testTimer.runPending( 20 );
+               log.push( 'b' );
+               f( 3 );
+               testTimer.runPending( 20 );
+               log.push( 'c' );
+               f( 4 );
+               testTimer.runPending( 20 );
+               log.push( 'd' );
+               testTimer.runPending( 20 );
+               log.push( 'e' );
+               testTimer.runPending( 20 );
+               log.push( 'f' );
+               testTimer.runPending( 20 );
+               assert.deepEqual( log, [ 1, 'a', 'b', 'c', 'd', 'e', 'f' ], 
'debounce 50 ms immediate' );
+
+               log = [];
+               f = OO.ui.debounce( log.push.bind( log ), 0 );
+               f( 1 );
+               log.push( 'a' );
+               f( 2 );
+               log.push( 'b' );
+               testTimer.runPending();
+               f( 3 );
+               log.push( 'c' );
+               testTimer.runPending();
+               log.push( 'd' );
+               assert.deepEqual( log, [ 'a', 'b', 1, 'c', 3, 'd' ], 'debounce 
0 ms' );
+               testTimer.runPending();
+
+               log = [];
+               f = OO.ui.debounce( log.push.bind( log ), 0, true );
+               f( 1 );
+               log.push( 'a' );
+               f( 2 );
+               log.push( 'b' );
+               testTimer.runPending();
+               f( 3 );
+               log.push( 'c' );
+               testTimer.runPending();
+               log.push( 'd' );
+               assert.deepEqual( log, [ 1, 'a', 'b', 3, 'c', 'd' ], 'debounce 
0 ms immediate' );
+               testTimer.runPending();
+
+       } finally {
+               window.setTimeout = setTimeoutReal;
+               window.clearTimeout = clearTimeoutReal;
+       }
 } );

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I25f524836a182797d799e67321eda1f1f78bed12
Gerrit-PatchSet: 1
Gerrit-Project: oojs/ui
Gerrit-Branch: master
Gerrit-Owner: Divec <[email protected]>

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

Reply via email to