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