mediawiki.jqueryMsg: Abort test if a language request fails
authorTimo Tijhof <krinklemail@gmail.com>
Thu, 16 Apr 2015 00:28:28 +0000 (01:28 +0100)
committerTimo Tijhof <krinklemail@gmail.com>
Thu, 16 Apr 2015 01:40:38 +0000 (02:40 +0100)
Follows-up 365b6f3.

If one of the requests fails, stop the test. This avoids one test
from leaking into the next test if it times out. And also makes
the error in question easier to handle. Most subsequent errors
tend to be cascading failures from earlier ones in this case.

It will still run other qunit tests within this module and other modules,
it only aborts the subtest for "Match PHP parser" in mediawiki.jqueryMsg.

To test:
* Change getMwLanguage() and append a bogus string to the request url,
  e.g. 'load.fail.php'.
* It will fail as expected with 'Language "en" failed to load.' and QUnit
  reports that it expected 49 more assertions, and moves on to the next test.

Change-Id: Id77bf43ef0b7a031db2fdb1d6c1bb8b2c64e689c

tests/qunit/suites/resources/mediawiki/mediawiki.jqueryMsg.test.js

index 7e23e2f..5dcd941 100644 (file)
        /**
         * @param {Function[]} tasks List of functions that perform tasks
         *  that may be asynchronous. Invoke the callback parameter when done.
-        * @param {Function} done When all tasks are done.
+        * @param {Function} complete Called when all tasks are done, or when the sequence is aborted.
         * @return
         */
-       function process( tasks, done ) {
-               function run() {
+       function process( tasks, complete ) {
+               function abort() {
+                       tasks.splice( 0, tasks.length );
+                       next();
+               }
+               function next() {
+                       if ( !tasks ) {
+                               // This happens if after the process is completed, one of our callbacks is
+                               // invoked. This can happen if a test timed out but the process was still
+                               // running. In that case, ignore it. Don't invoke complete() a second time.
+                               return;
+                       }
                        var task = tasks.shift();
                        if ( task ) {
-                               task( run );
+                               task( next, abort );
                        } else {
-                               done();
+                               // Remove tasks list to indicate the process is final.
+                               tasks = null;
+                               complete();
                        }
                }
-               run();
+               next();
        }
 
        QUnit.test( 'Replace', 16, function ( assert ) {
        QUnit.test( 'Match PHP parser', mw.libs.phpParserData.tests.length, function ( assert ) {
                mw.messages.set( mw.libs.phpParserData.messages );
                var tasks = $.map( mw.libs.phpParserData.tests, function ( test ) {
-                       return function ( next ) {
+                       return function ( next, abort ) {
                                getMwLanguage( test.lang )
-                                       .done( function ( langClass ) {
+                                       .then( function ( langClass ) {
                                                mw.config.set( 'wgUserLanguage', test.lang );
                                                var parser = new mw.jqueryMsg.parser( { language: langClass } );
                                                assert.equal(
                                                        test.result,
                                                        test.name
                                                );
-                                       } )
-                                       .fail( function () {
+                                       }, function () {
                                                assert.ok( false, 'Language "' + test.lang + '" failed to load.' );
                                        } )
-                                       .always( next );
+                                       .then( next, abort );
                        };
                } );
 
                mw.messages.set( 'formatnum-msg', '{{formatnum:$1}}' );
                mw.messages.set( 'formatnum-msg-int', '{{formatnum:$1|R}}' );
                var queue = $.map( formatnumTests, function ( test ) {
-                       return function ( next ) {
+                       return function ( next, abort ) {
                                getMwLanguage( test.lang )
-                                       .done( function ( langClass ) {
+                                       .then( function ( langClass ) {
                                                mw.config.set( 'wgUserLanguage', test.lang );
                                                var parser = new mw.jqueryMsg.parser( { language: langClass } );
                                                assert.equal(
                                                        test.result,
                                                        test.description
                                                );
-                                       } )
-                                       .fail( function () {
+                                       }, function () {
                                                assert.ok( false, 'Language "' + test.lang + '" failed to load' );
                                        } )
-                                       .always( next );
+                                       .then( next, abort );
                        };
                } );
                QUnit.stop();