r100394 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r100393‎ | r100394 | r100395 >
Date:23:24, 20 October 2011
Author:krinkle
Status:ok
Tags:
Comment:
[JSTesting] MFT r100385, r100387
---

$ svn merge -r 100384:100385 ../../trunk/phase3
--- Merging r100385 into '.':
U tests/qunit/data/testrunner.js
U tests/qunit/suites/resources/mediawiki/mediawiki.test.js

$ svn merge -r 100386:100387 ../../trunk/phase3
--- Merging r100387 into '.':
U resources/jquery/jquery.qunit.js
U resources/jquery/jquery.qunit.css
Modified paths:
  • /branches/JSTesting/resources/jquery/jquery.qunit.css (modified) (history)
  • /branches/JSTesting/resources/jquery/jquery.qunit.js (modified) (history)
  • /branches/JSTesting/tests/qunit/data/testrunner.js (modified) (history)
  • /branches/JSTesting/tests/qunit/suites/resources/mediawiki/mediawiki.test.js (modified) (history)

Diff [purge]

Index: branches/JSTesting/tests/qunit/data/testrunner.js
@@ -11,6 +11,11 @@
1212 };
1313
1414 /**
 15+ * Configuration
 16+ */
 17+QUnit.config.testTimeout = 5000;
 18+
 19+/**
1520 * Load TestSwarm agent
1621 */
1722 if ( QUnit.urlParams.swarmURL ) {
Index: branches/JSTesting/tests/qunit/suites/resources/mediawiki/mediawiki.test.js
@@ -131,7 +131,7 @@
132132 expect(1);
133133
134134 // Asynchronous ahead
135 - stop(5000);
 135+ stop();
136136
137137 mw.loader.implement( 'is.awesome', [QUnit.fixurl( mw.config.get( 'wgScriptPath' ) + '/tests/qunit/data/defineTestCallback.js' )], {}, {} );
138138
@@ -155,9 +155,9 @@
156156 // Message doesn't exist already
157157 ok( !mw.messages.exists( 'bug29107' ) );
158158
159 - // Async! Include a timeout, as failure in this test leads to neither the
160 - // success nor failure callbacks getting called.
161 - stop(5000);
 159+ // Async! Failure in this test may lead to neither the success nor error callbacks getting called.
 160+ // Due to QUnit's timeout feauture we won't hang here forever if this happends.
 161+ stop();
162162
163163 mw.loader.implement( 'bug29107.messages-only', [], {}, {'bug29107': 'loaded'} );
164164 mw.loader.using( 'bug29107.messages-only', function() {
@@ -180,9 +180,8 @@
181181 base = ('//' + loc.hostname + loc.pathname).replace(/\/[^\/]*$/, ''),
182182 target = base + '/data/qunitOkCall.js?' + (new Date()).getTime();
183183
184 - // Async! Include a timeout, as failure in this test leads to neither the
185 - // success nor failure callbacks getting called.
186 - stop(5000);
 184+ // Async!
 185+ stop();
187186 mw.loader.load( target );
188187 });
189188
Index: branches/JSTesting/resources/jquery/jquery.qunit.js
@@ -1,5 +1,5 @@
22 /**
3 - * QUnit - A JavaScript Unit Testing Framework
 3+ * QUnit 1.2.0pre - A JavaScript Unit Testing Framework
44 *
55 * http://docs.jquery.com/QUnit
66 *
@@ -21,7 +21,9 @@
2222 })()
2323 };
2424
25 -var testId = 0;
 25+var testId = 0,
 26+ toString = Object.prototype.toString,
 27+ hasOwn = Object.prototype.hasOwnProperty;
2628
2729 var Test = function(name, testName, expected, testEnvironmentArg, async, callback) {
2830 this.name = name;
@@ -48,7 +50,7 @@
4951 setup: function() {
5052 if (this.module != config.previousModule) {
5153 if ( config.previousModule ) {
52 - QUnit.moduleDone( {
 54+ runLoggingCallbacks('moduleDone', QUnit, {
5355 name: config.previousModule,
5456 failed: config.moduleStats.bad,
5557 passed: config.moduleStats.all - config.moduleStats.bad,
@@ -57,7 +59,7 @@
5860 }
5961 config.previousModule = this.module;
6062 config.moduleStats = { all: 0, bad: 0 };
61 - QUnit.moduleStart( {
 63+ runLoggingCallbacks( 'moduleStart', QUnit, {
6264 name: this.module
6365 } );
6466 }
@@ -71,9 +73,10 @@
7274 extend(this.testEnvironment, this.testEnvironmentArg);
7375 }
7476
75 - QUnit.testStart( {
76 - name: this.testName
77 - } );
 77+ runLoggingCallbacks( 'testStart', QUnit, {
 78+ name: this.testName,
 79+ module: this.module
 80+ });
7881
7982 // allow utility functions to access the current test environment
8083 // TODO why??
@@ -90,6 +93,7 @@
9194 }
9295 },
9396 run: function() {
 97+ config.current = this;
9498 if ( this.async ) {
9599 QUnit.stop();
96100 }
@@ -108,11 +112,12 @@
109113
110114 // Restart the tests if they're blocking
111115 if ( config.blocking ) {
112 - start();
 116+ QUnit.start();
113117 }
114118 }
115119 },
116120 teardown: function() {
 121+ config.current = this;
117122 try {
118123 this.testEnvironment.teardown.call(this.testEnvironment);
119124 checkPollution();
@@ -121,7 +126,8 @@
122127 }
123128 },
124129 finish: function() {
125 - if ( this.expected && this.expected != this.assertions.length ) {
 130+ config.current = this;
 131+ if ( this.expected != null && this.expected != this.assertions.length ) {
126132 QUnit.ok( false, "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run" );
127133 }
128134
@@ -210,8 +216,9 @@
211217 fail("reset() failed, following Test " + this.testName + ", exception and reset fn follows", e, QUnit.reset);
212218 }
213219
214 - QUnit.testDone( {
 220+ runLoggingCallbacks( 'testDone', QUnit, {
215221 name: this.testName,
 222+ module: this.module,
216223 failed: bad,
217224 passed: this.assertions.length - bad,
218225 total: this.assertions.length
@@ -243,7 +250,7 @@
244251 if (bad) {
245252 run();
246253 } else {
247 - synchronize(run);
 254+ synchronize(run, true);
248255 };
249256 }
250257
@@ -260,7 +267,7 @@
261268 asyncTest: function(testName, expected, callback) {
262269 if ( arguments.length === 2 ) {
263270 callback = expected;
264 - expected = 0;
 271+ expected = null;
265272 }
266273
267274 QUnit.test(testName, expected, callback, true);
@@ -310,8 +317,8 @@
311318 result: a,
312319 message: msg
313320 };
314 - msg = escapeHtml(msg);
315 - QUnit.log(details);
 321+ msg = escapeInnerText(msg);
 322+ runLoggingCallbacks( 'log', QUnit, details );
316323 config.current.assertions.push({
317324 result: a,
318325 message: msg
@@ -387,8 +394,8 @@
388395 QUnit.ok(ok, message);
389396 },
390397
391 - start: function() {
392 - config.semaphore--;
 398+ start: function(count) {
 399+ config.semaphore -= count || 1;
393400 if (config.semaphore > 0) {
394401 // don't start until equal number of stop-calls
395402 return;
@@ -408,28 +415,38 @@
409416 }
410417
411418 config.blocking = false;
412 - process();
 419+ process(true);
413420 }, 13);
414421 } else {
415422 config.blocking = false;
416 - process();
 423+ process(true);
417424 }
418425 },
419426
420 - stop: function(timeout) {
421 - config.semaphore++;
 427+ stop: function(count) {
 428+ config.semaphore += count || 1;
422429 config.blocking = true;
423430
424 - if ( timeout && defined.setTimeout ) {
 431+ if ( config.testTimeout && defined.setTimeout ) {
425432 clearTimeout(config.timeout);
426433 config.timeout = window.setTimeout(function() {
427434 QUnit.ok( false, "Test timed out" );
 435+ config.semaphore = 1;
428436 QUnit.start();
429 - }, timeout);
 437+ }, config.testTimeout);
430438 }
431439 }
432440 };
433441
 442+//We want access to the constructor's prototype
 443+(function() {
 444+ function F(){};
 445+ F.prototype = QUnit;
 446+ QUnit = new F();
 447+ //Make F QUnit's constructor so that we can add to the prototype later
 448+ QUnit.constructor = F;
 449+})();
 450+
434451 // Backwards compatibility, deprecated
435452 QUnit.equals = QUnit.equal;
436453 QUnit.same = QUnit.deepEqual;
@@ -453,7 +470,16 @@
454471 // by default, modify document.title when suite is done
455472 altertitle: true,
456473
457 - urlConfig: ['noglobals', 'notrycatch']
 474+ urlConfig: ['noglobals', 'notrycatch'],
 475+
 476+ //logging callback queues
 477+ begin: [],
 478+ done: [],
 479+ log: [],
 480+ testStart: [],
 481+ testDone: [],
 482+ moduleStart: [],
 483+ moduleDone: []
458484 };
459485
460486 // Load paramaters
@@ -586,8 +612,7 @@
587613 return "null";
588614 }
589615
590 - var type = Object.prototype.toString.call( obj )
591 - .match(/^\[object\s(.*)\]$/)[1] || '';
 616+ var type = toString.call( obj ).match(/^\[object\s(.*)\]$/)[1] || '';
592617
593618 switch (type) {
594619 case 'Number':
@@ -618,10 +643,10 @@
619644 expected: expected
620645 };
621646
622 - message = escapeHtml(message) || (result ? "okay" : "failed");
 647+ message = escapeInnerText(message) || (result ? "okay" : "failed");
623648 message = '<span class="test-message">' + message + "</span>";
624 - expected = escapeHtml(QUnit.jsDump.parse(expected));
625 - actual = escapeHtml(QUnit.jsDump.parse(actual));
 649+ expected = escapeInnerText(QUnit.jsDump.parse(expected));
 650+ actual = escapeInnerText(QUnit.jsDump.parse(actual));
626651 var output = message + '<table><tr class="test-expected"><th>Expected: </th><td><pre>' + expected + '</pre></td></tr>';
627652 if (actual != expected) {
628653 output += '<tr class="test-actual"><th>Result: </th><td><pre>' + actual + '</pre></td></tr>';
@@ -631,12 +656,12 @@
632657 var source = sourceFromStacktrace();
633658 if (source) {
634659 details.source = source;
635 - output += '<tr class="test-source"><th>Source: </th><td><pre>' + escapeHtml(source) + '</pre></td></tr>';
 660+ output += '<tr class="test-source"><th>Source: </th><td><pre>' + escapeInnerText(source) + '</pre></td></tr>';
636661 }
637662 }
638663 output += "</table>";
639664
640 - QUnit.log(details);
 665+ runLoggingCallbacks( 'log', QUnit, details );
641666
642667 config.current.assertions.push({
643668 result: !!result,
@@ -649,6 +674,9 @@
650675 var querystring = "?",
651676 key;
652677 for ( key in params ) {
 678+ if ( !hasOwn.call( params, key ) ) {
 679+ continue;
 680+ }
653681 querystring += encodeURIComponent( key ) + "=" +
654682 encodeURIComponent( params[ key ] ) + "&";
655683 }
@@ -657,23 +685,28 @@
658686
659687 extend: extend,
660688 id: id,
661 - addEvent: addEvent,
 689+ addEvent: addEvent
 690+});
662691
 692+//QUnit.constructor is set to the empty F() above so that we can add to it's prototype later
 693+//Doing this allows us to tell if the following methods have been overwritten on the actual
 694+//QUnit object, which is a deprecated way of using the callbacks.
 695+extend(QUnit.constructor.prototype, {
663696 // Logging callbacks; all receive a single argument with the listed properties
664697 // run test/logs.html for any related changes
665 - begin: function() {},
 698+ begin: registerLoggingCallback('begin'),
666699 // done: { failed, passed, total, runtime }
667 - done: function() {},
 700+ done: registerLoggingCallback('done'),
668701 // log: { result, actual, expected, message }
669 - log: function() {},
 702+ log: registerLoggingCallback('log'),
670703 // testStart: { name }
671 - testStart: function() {},
 704+ testStart: registerLoggingCallback('testStart'),
672705 // testDone: { name, failed, passed, total }
673 - testDone: function() {},
 706+ testDone: registerLoggingCallback('testDone'),
674707 // moduleStart: { name }
675 - moduleStart: function() {},
 708+ moduleStart: registerLoggingCallback('moduleStart'),
676709 // moduleDone: { name, failed, passed, total }
677 - moduleDone: function() {}
 710+ moduleDone: registerLoggingCallback('moduleDone')
678711 });
679712
680713 if ( typeof document === "undefined" || document.readyState === "complete" ) {
@@ -681,7 +714,7 @@
682715 }
683716
684717 QUnit.load = function() {
685 - QUnit.begin({});
 718+ runLoggingCallbacks( 'begin', QUnit, {} );
686719
687720 // Initialize the config, saving the execution queue
688721 var oldconfig = extend({}, config);
@@ -756,12 +789,23 @@
757790
758791 addEvent(window, "load", QUnit.load);
759792
 793+// addEvent(window, "error") gives us a useless event object
 794+window.onerror = function( message, file, line ) {
 795+ if ( QUnit.config.current ) {
 796+ ok( false, message + ", " + file + ":" + line );
 797+ } else {
 798+ test( "global failure", function() {
 799+ ok( false, message + ", " + file + ":" + line );
 800+ });
 801+ }
 802+};
 803+
760804 function done() {
761805 config.autorun = true;
762806
763807 // Log the last module results
764808 if ( config.currentModule ) {
765 - QUnit.moduleDone( {
 809+ runLoggingCallbacks( 'moduleDone', QUnit, {
766810 name: config.currentModule,
767811 failed: config.moduleStats.bad,
768812 passed: config.moduleStats.all - config.moduleStats.bad,
@@ -803,7 +847,7 @@
804848 ].join(" ");
805849 }
806850
807 - QUnit.done( {
 851+ runLoggingCallbacks( 'done', QUnit, {
808852 failed: config.stats.bad,
809853 passed: passed,
810854 total: config.stats.all,
@@ -855,16 +899,14 @@
856900 }
857901 }
858902
859 -function escapeHtml(s) {
 903+function escapeInnerText(s) {
860904 if (!s) {
861905 return "";
862906 }
863907 s = s + "";
864 - return s.replace(/[\&"<>\\]/g, function(s) {
 908+ return s.replace(/[\&<>]/g, function(s) {
865909 switch(s) {
866910 case "&": return "&amp;";
867 - case "\\": return "\\\\";
868 - case '"': return '\"';
869911 case "<": return "&lt;";
870912 case ">": return "&gt;";
871913 default: return s;
@@ -872,26 +914,30 @@
873915 });
874916 }
875917
876 -function synchronize( callback ) {
 918+function synchronize( callback, last ) {
877919 config.queue.push( callback );
878920
879921 if ( config.autorun && !config.blocking ) {
880 - process();
 922+ process(last);
881923 }
882924 }
883925
884 -function process() {
885 - var start = (new Date()).getTime();
 926+function process( last ) {
 927+ var start = new Date().getTime();
 928+ config.depth = config.depth ? config.depth + 1 : 1;
886929
887930 while ( config.queue.length && !config.blocking ) {
888 - if ( config.updateRate <= 0 || (((new Date()).getTime() - start) < config.updateRate) ) {
 931+ if ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) {
889932 config.queue.shift()();
890933 } else {
891 - window.setTimeout( process, 13 );
 934+ window.setTimeout( function(){
 935+ process( last );
 936+ }, 13 );
892937 break;
893938 }
894939 }
895 - if (!config.blocking && !config.queue.length) {
 940+ config.depth--;
 941+ if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) {
896942 done();
897943 }
898944 }
@@ -901,6 +947,9 @@
902948
903949 if ( config.noglobals ) {
904950 for ( var key in window ) {
 951+ if ( !hasOwn.call( window, key ) ) {
 952+ continue;
 953+ }
905954 config.pollution.push( key );
906955 }
907956 }
@@ -951,7 +1000,9 @@
9521001 for ( var prop in b ) {
9531002 if ( b[prop] === undefined ) {
9541003 delete a[prop];
955 - } else {
 1004+
 1005+ // Avoid "Member not found" error in IE8 caused by setting window.constructor
 1006+ } else if ( prop !== "constructor" || a !== window ) {
9561007 a[prop] = b[prop];
9571008 }
9581009 }
@@ -974,9 +1025,27 @@
9751026 document.getElementById( name );
9761027 }
9771028
 1029+function registerLoggingCallback(key){
 1030+ return function(callback){
 1031+ config[key].push( callback );
 1032+ };
 1033+}
 1034+
 1035+// Supports deprecated method of completely overwriting logging callbacks
 1036+function runLoggingCallbacks(key, scope, args) {
 1037+ //debugger;
 1038+ var callbacks;
 1039+ if ( QUnit.hasOwnProperty(key) ) {
 1040+ QUnit[key].call(scope, args);
 1041+ } else {
 1042+ callbacks = config[key];
 1043+ for( var i = 0; i < callbacks.length; i++ ) {
 1044+ callbacks[i].call( scope, args );
 1045+ }
 1046+ }
 1047+}
 1048+
9781049 // Test for equality any JavaScript type.
979 -// Discussions and reference: http://philrathe.com/articles/equiv
980 -// Test suites: http://philrathe.com/tests/equiv
9811050 // Author: Philippe Rathé <prathe@gmail.com>
9821051 QUnit.equiv = function () {
9831052
@@ -1226,7 +1295,12 @@
12271296 type = "document";
12281297 } else if (obj.nodeType) {
12291298 type = "node";
1230 - } else if (typeof obj === "object" && typeof obj.length === "number" && obj.length >= 0) {
 1299+ } else if (
 1300+ // native arrays
 1301+ toString.call( obj ) === "[object Array]" ||
 1302+ // NodeList objects
 1303+ ( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item(0) === obj[0] : ( obj.item( 0 ) === null && typeof obj[0] === "undefined" ) ) )
 1304+ ) {
12311305 type = "array";
12321306 } else {
12331307 type = typeof obj;
@@ -1408,6 +1482,9 @@
14091483 }
14101484
14111485 for (var i in ns) {
 1486+ if ( !hasOwn.call( ns, i ) ) {
 1487+ continue;
 1488+ }
14121489 if (ns[i].rows.length == 1 && typeof(os[i]) != "undefined" && os[i].rows.length == 1) {
14131490 n[ns[i].rows[0]] = {
14141491 text: n[ns[i].rows[0]],
Index: branches/JSTesting/resources/jquery/jquery.qunit.css
@@ -1,5 +1,5 @@
22 /**
3 - * QUnit - A JavaScript Unit Testing Framework
 3+ * QUnit 1.2.0pre - A JavaScript Unit Testing Framework
44 *
55 * http://docs.jquery.com/QUnit
66 *

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r100385[JSTesting] Don't rely on the timeout argument of start/stop. This behavior i...krinkle22:33, 20 October 2011
r100387Updating jquery.qunit from upstream...krinkle22:35, 20 October 2011

Status & tagging log