Bug 615546 - SimpleTest.finish() should be asynchronous; (Av1a) SimpleTest.js: Create SimpleTest._finishNow() out of SimpleTest.finish() then call it asynchronously, Fix some (unrelated) nits.
authorSerge Gautherie <sgautherie.bz@free.fr>
Wed, 01 Dec 2010 18:24:03 +0100
changeset 58443 ab44d15573e2c724146b758b4395f0c720e30f48
parent 58442 3e199c023eaf4bbca21690eee72b581e3450753a
child 58444 c3ad6eaa6f2f9b89b32b1b60256e66f0391293c7
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
bugs615546
milestone2.0b8pre
Bug 615546 - SimpleTest.finish() should be asynchronous; (Av1a) SimpleTest.js: Create SimpleTest._finishNow() out of SimpleTest.finish() then call it asynchronously, Fix some (unrelated) nits. r=rcampbell a=(test only).
testing/mochitest/tests/SimpleTest/SimpleTest.js
--- a/testing/mochitest/tests/SimpleTest/SimpleTest.js
+++ b/testing/mochitest/tests/SimpleTest/SimpleTest.js
@@ -7,17 +7,17 @@
  * TODO:
  *  * Support the Test.Simple API used by MochiKit, to be able to test MochiKit
  * itself against IE 5.5
  *
  * NOTE: Pay attention to cross-browser compatibility in this file. For
  * instance, do not use const or JS > 1.5 features which are not yet
  * implemented everywhere.
  *
-**/
+ */
 
 if (typeof(SimpleTest) == "undefined") {
     var SimpleTest = {};
 }
 
 var parentRunner = null;
 if (typeof(parent) != "undefined" && parent.TestRunner) {
     parentRunner = parent.TestRunner;
@@ -29,17 +29,17 @@ if (typeof(parent) != "undefined" && par
 //Simple test to see if we are running in e10s IPC
 var ipcMode = false;
 if (parentRunner) {
   ipcMode = parentRunner.ipcMode;
 }
 
 /**
  * Check for OOP test plugin
-**/
+ */
 SimpleTest.testPluginIsOOP = function () {
     netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
     var prefservice = Components.classes["@mozilla.org/preferences-service;1"]
                                 .getService(Components.interfaces.nsIPrefBranch);
 
     var testPluginIsOOP = false;
     if (navigator.platform.indexOf("Mac") == 0) {
         var xulRuntime = Components.classes["@mozilla.org/xre/app-info;1"]
@@ -72,27 +72,27 @@ if (parentRunner) {
     SimpleTest._logEnabled = parentRunner.logEnabled;
 }
 
 SimpleTest._tests = [];
 SimpleTest._stopOnLoad = true;
 
 /**
  * Something like assert.
-**/
+ */
 SimpleTest.ok = function (condition, name, diag) {
     var test = {'result': !!condition, 'name': name, 'diag': diag};
     if (SimpleTest._logEnabled)
         SimpleTest._logResult(test, "TEST-PASS", "TEST-UNEXPECTED-FAIL");
     SimpleTest._tests.push(test);
 };
 
 /**
  * Roughly equivalent to ok(a==b, name)
-**/
+ */
 SimpleTest.is = function (a, b, name) {
     var repr = MochiKit.Base.repr;
     var pass = (a == b);
     var diag = pass ? repr(a) + " should equal " + repr(b)
                     : "got " + repr(a) + ", expected " + repr(b)
     SimpleTest.ok(pass, name, diag);
 };
 
@@ -131,17 +131,17 @@ SimpleTest._logResult = function(test, p
           parentRunner.logger.log(msg);
       else
           parentRunner.logger.error(msg);
   }
 };
 
 /**
  * Copies of is and isnot with the call to ok replaced by a call to todo.
-**/
+ */
 
 SimpleTest.todo_is = function (a, b, name) {
     var repr = MochiKit.Base.repr;
     var pass = (a == b);
     var diag = pass ? repr(a) + " should equal " + repr(b)
                     : "got " + repr(a) + ", expected " + repr(b);
     SimpleTest.todo(pass, name, diag);
 };
@@ -152,17 +152,17 @@ SimpleTest.todo_isnot = function (a, b, 
     var diag = pass ? repr(a) + " should not equal " + repr(b)
                     : "didn't expect " + repr(a) + ", but got it";
     SimpleTest.todo(pass, name, diag);
 };
 
 
 /**
  * Makes a test report, returns it as a DIV element.
-**/
+ */
 SimpleTest.report = function () {
     var DIV = MochiKit.DOM.DIV;
     var passed = 0;
     var failed = 0;
     var todo = 0;
 
     // Report tests which did not actually check anything.
     if (SimpleTest._tests.length == 0)
@@ -200,38 +200,38 @@ SimpleTest.report = function () {
             DIV({'class': 'tests_failed'}, "Failed: " + failed),
             DIV({'class': 'tests_todo'}, "Todo: " + todo)),
         results
     );
 };
 
 /**
  * Toggle element visibility
-**/
+ */
 SimpleTest.toggle = function(el) {
     if (MochiKit.Style.computedStyle(el, 'display') == 'block') {
         el.style.display = 'none';
     } else {
         el.style.display = 'block';
     }
 };
 
 /**
  * Toggle visibility for divs with a specific class.
-**/
+ */
 SimpleTest.toggleByClass = function (cls, evt) {
     var elems = getElementsByTagAndClassName('div', cls);
     MochiKit.Base.map(SimpleTest.toggle, elems);
     if (evt)
         evt.preventDefault();
 };
 
 /**
  * Shows the report in the browser
-**/
+ */
 
 SimpleTest.showReport = function() {
     var togglePassed = A({'href': '#'}, "Toggle passed checks");
     var toggleFailed = A({'href': '#'}, "Toggle failed checks");
     var toggleTodo = A({'href': '#'}, "Toggle todo checks");
     togglePassed.onclick = partial(SimpleTest.toggleByClass, 'test_ok');
     toggleFailed.onclick = partial(SimpleTest.toggleByClass, 'test_not_ok');
     toggleTodo.onclick = partial(SimpleTest.toggleByClass, 'test_todo');
@@ -256,22 +256,22 @@ SimpleTest.showReport = function() {
     addNode(SPAN(null, " "));
     addNode(toggleFailed);
     addNode(SPAN(null, " "));
     addNode(toggleTodo);
     addNode(SimpleTest.report());
 };
 
 /**
- * Tells SimpleTest to don't finish the test when the document is loaded,
- * useful for asynchronous tests.
+ * Tells SimpleTest harness not to finish the test automatically.
+ * Asynchronous tests must call this function.
  *
- * When SimpleTest.waitForExplicitFinish is called,
- * explicit SimpleTest.finish() is required.
-**/
+ * After this function has been called,
+ * an explicit call to SimpleTest.finish is required to finish the test.
+ */
 SimpleTest.waitForExplicitFinish = function () {
     SimpleTest._stopOnLoad = false;
 };
 
 /**
  * Multiply the timeout the parent runner uses for this test by the
  * given factor.
  *
@@ -508,52 +508,66 @@ SimpleTest.waitForClipboard = function(a
 /**
  * Executes a function shortly after the call, but lets the caller continue
  * working (or finish).
  */
 SimpleTest.executeSoon = function(aFunc) {
     if ("Components" in window && "classes" in window.Components) {
         try {
             netscape.security.PrivilegeManager
-              .enablePrivilege("UniversalXPConnect");
+                             .enablePrivilege("UniversalXPConnect");
             var tm = Components.classes["@mozilla.org/thread-manager;1"]
-                       .getService(Components.interfaces.nsIThreadManager);
-
+                               .getService(Components.interfaces.nsIThreadManager);
             tm.mainThread.dispatch({
                 run: function() {
                     aFunc();
                 }
             }, Components.interfaces.nsIThread.DISPATCH_NORMAL);
             return;
         } catch (ex) {
             // If the above fails (most likely because of enablePrivilege
             // failing, fall through to the setTimeout path.
         }
     }
+
     setTimeout(aFunc, 0);
 }
 
 /**
- * Finishes the tests. This is automatically called, except when
- * SimpleTest.waitForExplicitFinish() has been invoked.
-**/
+ * Finishes the test, after letting it actually end first.
+ *
+ * Tests must call this function when they have called
+ * SimpleTest.waitForExplicitFinish before.
+ */
 SimpleTest.finish = function () {
+  SimpleTest.executeSoon(SimpleTest._finishNow);
+};
+
+/**
+ * Finishes the test, now.
+ *
+ * Not to be directly called by tests.
+ */
+SimpleTest._finishNow = function () {
     if (parentRunner) {
-        /* We're running in an iframe, and the parent has a TestRunner */
+        // The test is running in an iframe, and its parent has a TestRunner.
         parentRunner.testFinished(SimpleTest._tests);
     } else {
+        // The test is running alone in the window.
         SimpleTest.showReport();
     }
 };
 
-
+/**
+ * Automatically call SimpleTest._finishNow when the document has loaded,
+ * except when SimpleTest.waitForExplicitFinish has been called.
+ */
 addLoadEvent(function() {
-    if (SimpleTest._stopOnLoad) {
-        SimpleTest.finish();
-    }
+    if (SimpleTest._stopOnLoad)
+      SimpleTest._finishNow();
 });
 
 //  --------------- Test.Builder/Test.More isDeeply() -----------------
 
 
 SimpleTest.DNE = {dne: 'Does not exist'};
 SimpleTest.LF = "\r\n";
 SimpleTest._isRef = function (object) {
@@ -774,12 +788,12 @@ window.onerror = function simpletestOner
       ok(false, funcIdentifier + "Exception thrown by gOldOnError()", e);
       // Log its stack.
       if (e.stack)
         ok(false, funcIdentifier + "JavaScript error stack:\n" + e.stack);
     }
   }
 
   if (!SimpleTest._stopOnLoad) {
-    // Need to finish() manually here, yet let the test actually end first.
-    SimpleTest.executeSoon(SimpleTest.finish);
+    // Call finish, as the test (hopefully) doesn't run anymore.
+    SimpleTest.finish();
   }
 }