Bug 1187701 - add_task function for mochitest chrome and plain; r=jmaher
authorArthur Edelstein <arthuredelstein@gmail.com>
Mon, 03 Aug 2015 11:14:10 -0600
changeset 287616 4e05c3afe0e088176a720bdd594c283008f3f4d5
parent 287615 2f16fb18314a58cbf5e242b000d7ae560401ab97
child 287617 3fc1d9ffd07981c15cff6447383ed79710dd3752
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjmaher
bugs1187701
milestone42.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1187701 - add_task function for mochitest chrome and plain; r=jmaher
testing/mochitest/chrome/chrome.ini
testing/mochitest/chrome/test_sanityAddTask.xul
testing/mochitest/chrome/test_sanitySpawnTask.xul
testing/mochitest/tests/Harness_sanity/mochitest.ini
testing/mochitest/tests/Harness_sanity/test_add_task.html
testing/mochitest/tests/Harness_sanity/test_spawn_task.html
testing/mochitest/tests/SimpleTest/SpawnTask.js
--- a/testing/mochitest/chrome/chrome.ini
+++ b/testing/mochitest/chrome/chrome.ini
@@ -1,13 +1,14 @@
 [DEFAULT]
 skip-if = buildapp == 'b2g' || os == 'android'
 support-files = test-dir/test-file
 
 [test_sample.xul]
+[test_sanityAddTask.xul]
 [test_sanityChromeUtils.xul]
 skip-if = buildapp == 'mulet'
 [test_sanityPluginUtils.html]
 skip-if = buildapp == 'mulet'
 [test_sanityException.xul]
 [test_sanityException2.xul]
 [test_sanityManifest.xul]
 fail-if = true
new file mode 100644
--- /dev/null
+++ b/testing/mochitest/chrome/test_sanityAddTask.xul
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this
+   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
+                 type="text/css"?>
+<window title="Test spawnTawk function"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SpawnTask.js"/>
+  <script type="application/javascript">
+    <![CDATA[
+
+      // Check that we can 'add_task' a few times and all tasks run asynchronously before test finishes.
+
+      add_task(function* () {
+        var x = yield Promise.resolve(1);
+        is(x, 1, "task yields Promise value as expected");
+      });
+
+      add_task(function* () {
+        var x = yield [Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)];
+        is(x.join(""), "123", "task yields Promise value as expected");
+      });
+
+      add_task(function* () {
+        var x = yield (function* () {
+          return 3;
+        }());
+        is(x, 3, "task yields generator function return value as expected");
+      });
+
+    ]]>
+  </script>
+  <body xmlns="http://www.w3.org/1999/xhtml" >
+  </body>
+</window>
+
+
+
+
--- a/testing/mochitest/chrome/test_sanitySpawnTask.xul
+++ b/testing/mochitest/chrome/test_sanitySpawnTask.xul
@@ -53,18 +53,18 @@
       }
       var val8 = yield externalGeneratorFunction();
       is(val8, 8, "External generator also spawned.");
       var val9 = yield nestedFunction();
       is(val9, 9, "Nested generator functions work.");
       return 10;
     };
 
-    spawnTask(variousTests).then(function(result) {
-      is(result, 10, "spawnTask(...) returns promise");
+    spawn_task(variousTests).then(function(result) {
+      is(result, 10, "spawn_task(...) returns promise");
       SimpleTest.finish();
     });
     ]]>
   </script>
 
   <body xmlns="http://www.w3.org/1999/xhtml" >
   </body>
 </window>
--- a/testing/mochitest/tests/Harness_sanity/mochitest.ini
+++ b/testing/mochitest/tests/Harness_sanity/mochitest.ini
@@ -1,12 +1,13 @@
 [DEFAULT]
 skip-if = buildapp == 'mulet' || buildapp == 'b2g'
 [test_TestsRunningAfterSimpleTestFinish.html]
 skip-if = true #depends on fix for bug 1048446
+[test_add_task.html]
 [test_sanity.html]
 [test_sanityException.html]
 [test_sanityException2.html]
 [test_sanityParams.html]
 [test_sanityWindowSnapshot.html]
 skip-if = (toolkit == 'android' && processor == 'x86') #x86 only
 [test_SpecialPowersExtension.html]
 [test_SpecialPowersExtension2.html]
new file mode 100644
--- /dev/null
+++ b/testing/mochitest/tests/Harness_sanity/test_add_task.html
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test for mochitest add_task, found in SpawnTask.js</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Mozilla Bug 1187701</a>
+<p id="display"></p>
+<div id="content" style="display: none"></div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+// Check that we can 'add_task' a few times and all tasks run asynchronously before test finishes.
+
+add_task(function* () {
+  var x = yield Promise.resolve(1);
+  is(x, 1, "task yields Promise value as expected");
+});
+
+add_task(function* () {
+  var x = yield [Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)];
+  is(x.join(""), "123", "task yields Promise value as expected");
+});
+
+add_task(function* () {
+  var x = yield (function* () {
+    return 3;
+  }());
+  is(x, 3, "task yields generator function return value as expected");
+});
+</script>
+</pre>
+</body>
+</html>
+
--- a/testing/mochitest/tests/Harness_sanity/test_spawn_task.html
+++ b/testing/mochitest/tests/Harness_sanity/test_spawn_task.html
@@ -55,18 +55,18 @@ var variousTests = function* () {
   }
   var val8 = yield externalGeneratorFunction();
   is(val8, 8, "External generator also spawned.");
   var val9 = yield nestedFunction();
   is(val9, 9, "Nested generator functions work.");
   return 10;
 };
 
-spawnTask(variousTests).then(function(result) {
-  is(result, 10, "spawnTask(...) returns promise");
+spawn_task(variousTests).then(function(result) {
+  is(result, 10, "spawn_task(...) returns promise");
   SimpleTest.finish();
 });
 
 
 </script>
 </pre>
 </body>
 </html>
--- a/testing/mochitest/tests/SimpleTest/SpawnTask.js
+++ b/testing/mochitest/tests/SimpleTest/SpawnTask.js
@@ -1,18 +1,18 @@
 // # SpawnTask.js
 // Directly copied from the "co" library by TJ Holowaychuk.
 // See https://github.com/tj/co/tree/4.6.0
 // For use with mochitest-plain and mochitest-chrome.
 
-// __spawnTask(generatorFunction)__.
+// spawn_task(generatorFunction):
 // Expose only the `co` function, which is very similar to Task.spawn in Task.jsm.
-// We call this function spawnTask to make its purpose more plain, and to
+// We call this function spawn_task to make its purpose more plain, and to
 // reduce the chance of name collisions.
-var spawnTask = (function () {
+var spawn_task = (function () {
 
 /**
  * slice() reference.
  */
 
 var slice = Array.prototype.slice;
 
 /**
@@ -237,8 +237,47 @@ function isGeneratorFunction(obj) {
  */
 
 function isObject(val) {
   return Object == val.constructor;
 }
 
 return co;
 })();
+
+// add_task(generatorFunction):
+// Call `add_task(generatorFunction)` for each separate
+// asynchronous task in a mochitest. Tasks are run consecutively.
+// Before the first task, `SimpleTest.waitForExplicitFinish()`
+// will be called automatically, and after the last task,
+// `SimpleTest.finish()` will be called.
+var add_task = (function () {
+  // The list of tasks to run.
+  var task_list = [];
+  // The "add_task" function
+  return function (generatorFunction) {
+    if (task_list.length === 0) {
+      // This is the first time add_task has been called.
+      // First, confirm that SimpleTest is available.
+      if (!SimpleTest) {
+        throw new Error("SimpleTest not available.");
+      }
+      // Don't stop tests until asynchronous tasks are finished.
+      SimpleTest.waitForExplicitFinish();
+      // Because the client is using add_task for this set of tests,
+      // we need to spawn a "master task" that calls each task in succesion.
+      // Use setTimeout to ensure the master task runs after the client
+      // script finishes.
+      setTimeout(function () {
+        spawn_task(function* () {
+          for (var task of task_list) {
+            yield task();
+          }
+          // All tasks are finished.
+          SimpleTest.finish();
+        });
+      });
+    }
+    // Add the task to the list of tasks to run after
+    // the main thread is finished.
+    task_list.push(generatorFunction);
+  };
+})();