Bug 1316780: Part 3 - Capture the current unprivileged stack in browser.test.* assertion functions. r?aswan draft
authorKris Maglione <maglione.k@gmail.com>
Thu, 10 Nov 2016 20:23:45 -0800
changeset 437585 4d5406ba3424e3502ffedc22ed552934ba587e38
parent 437584 36c5a5c4c3f045bd4dbfda9c2fc07328c0b088de
child 437586 9569c6f84292935014d17230e52c4e525c852e1f
push id35454
push usermaglione.k@gmail.com
push dateFri, 11 Nov 2016 04:34:52 +0000
reviewersaswan
bugs1316780
milestone52.0a1
Bug 1316780: Part 3 - Capture the current unprivileged stack in browser.test.* assertion functions. r?aswan MozReview-Commit-ID: AxjMeoodpTX
testing/mochitest/tests/SimpleTest/ExtensionTestUtils.js
testing/mochitest/tests/SimpleTest/SimpleTest.js
toolkit/components/extensions/ext-c-test.js
--- a/testing/mochitest/tests/SimpleTest/ExtensionTestUtils.js
+++ b/testing/mochitest/tests/SimpleTest/ExtensionTestUtils.js
@@ -49,28 +49,28 @@ ExtensionTestUtils.loadExtension = funct
     if (messageHandler.has(msg) || messageAwaiter.has(msg)) {
       throw new Error("only one message handler allowed");
     }
   }
 
   function testHandler(kind, pass, msg, ...args) {
     if (kind == "test-eq") {
       var [expected, actual] = args;
-      SimpleTest.ok(pass, `${msg} - Expected: ${expected}, Actual: ${actual}`);
+      SimpleTest.ok(pass, `${msg} - Expected: ${expected}, Actual: ${actual}`, undefined, args[2]);
     } else if (kind == "test-log") {
       SimpleTest.info(msg);
     } else if (kind == "test-result") {
-      SimpleTest.ok(pass, msg);
+      SimpleTest.ok(pass, msg, undefined, args[0]);
     }
   }
 
   var handler = {
     testResult(kind, pass, msg, ...args) {
       if (kind == "test-done") {
-        SimpleTest.ok(pass, msg);
+        SimpleTest.ok(pass, msg, undefined, args[0]);
         return testResolve(msg);
       }
       testHandler(kind, pass, msg, ...args);
     },
 
     testMessage(msg, ...args) {
       var handler = messageHandler.get(msg);
       if (handler) {
--- a/testing/mochitest/tests/SimpleTest/SimpleTest.js
+++ b/testing/mochitest/tests/SimpleTest/SimpleTest.js
@@ -229,33 +229,34 @@ SimpleTest.setExpected = function () {
     SimpleTest.expected = parent.TestRunner.expected;
   }
 }
 SimpleTest.setExpected();
 
 /**
  * Something like assert.
 **/
-SimpleTest.ok = function (condition, name, diag) {
+SimpleTest.ok = function (condition, name, diag, stack = null) {
 
     var test = {'result': !!condition, 'name': name, 'diag': diag};
     if (SimpleTest.expected == 'fail') {
       if (!test.result) {
         SimpleTest.num_failed++;
         test.result = !test.result;
       }
       var successInfo = {status:"FAIL", expected:"FAIL", message:"TEST-KNOWN-FAIL"};
       var failureInfo = {status:"PASS", expected:"FAIL", message:"TEST-UNEXPECTED-PASS"};
     } else {
       var successInfo = {status:"PASS", expected:"PASS", message:"TEST-PASS"};
       var failureInfo = {status:"FAIL", expected:"PASS", message:"TEST-UNEXPECTED-FAIL"};
     }
 
-    var stack = null;
-    if (!condition) {
+    if (condition) {
+        stack = null;
+    } else if (!stack) {
       stack = (new Error).stack.replace(/^(.*@)http:\/\/mochi.test:8888\/tests\//gm, '    $1').split('\n');
       stack.splice(0, 1);
       stack = stack.join('\n');
     }
 
     SimpleTest._logResult(test, successInfo, failureInfo, stack);
     SimpleTest._tests.push(test);
 };
--- a/toolkit/components/extensions/ext-c-test.js
+++ b/toolkit/components/extensions/ext-c-test.js
@@ -73,36 +73,40 @@ function toSource(value) {
   } catch (e) {
     return "<unknown>";
   }
 }
 
 function makeTestAPI(context) {
   const {extension} = context;
 
+  function getStack() {
+    return new context.cloneScope.Error().stack.replace(/^/gm, "    ");
+  }
+
   function assertTrue(value, msg) {
-    extension.emit("test-result", Boolean(value), String(msg));
+    extension.emit("test-result", Boolean(value), String(msg), getStack());
   }
 
   return {
     test: {
       sendMessage: function(...args) {
         extension.emit("test-message", ...args);
       },
 
       notifyPass: function(msg) {
-        extension.emit("test-done", true, msg);
+        extension.emit("test-done", true, msg, getStack());
       },
 
       notifyFail: function(msg) {
-        extension.emit("test-done", false, msg);
+        extension.emit("test-done", false, msg, getStack());
       },
 
       log: function(msg) {
-        extension.emit("test-log", true, msg);
+        extension.emit("test-log", true, msg, getStack());
       },
 
       fail: function(msg) {
         assertTrue(false, msg);
       },
 
       succeed: function(msg) {
         assertTrue(true, msg);
@@ -120,17 +124,17 @@ function makeTestAPI(context) {
         let equal = expected === actual;
 
         expected = String(expected);
         actual = String(actual);
 
         if (!equal && expected === actual) {
           actual += " (different)";
         }
-        extension.emit("test-eq", equal, String(msg), expected, actual);
+        extension.emit("test-eq", equal, String(msg), expected, actual, getStack());
       },
 
       assertRejects(promise, expectedError, msg) {
         // Wrap in a native promise for consistency.
         promise = Promise.resolve(promise);
 
         if (msg) {
           msg = `: ${msg}`;