Bug 974065 - Add test file missing from previous push. r=me
authorBrandon Benvie <bbenvie@mozilla.com>
Wed, 19 Feb 2014 14:15:06 -0800
changeset 169652 671b3044b16682b89c7aae16f97cc813780c91b2
parent 169651 9a30d2ed15978b06f5cb78c5fa3551f1f3e70870
child 169653 ee1ea4920afbd213980ff238635ef080beac8c77
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersme
bugs974065
milestone30.0a1
Bug 974065 - Add test file missing from previous push. r=me
toolkit/devtools/tests/unit/test_async-utils.js
new file mode 100644
--- /dev/null
+++ b/toolkit/devtools/tests/unit/test_async-utils.js
@@ -0,0 +1,153 @@
+/* -*- Mode: js; js-indent-level: 2; -*- */
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Test async-utils.js
+
+const {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
+const {Promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
+const {require} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools;
+const {async, asyncOnce, promiseInvoke, promiseCall} = require("devtools/async-utils");
+
+function run_test() {
+  do_test_pending();
+  Task.spawn(function*() {
+    for (let helper of [async, asyncOnce]) {
+      yield test_async_args(helper);
+      yield test_async_return(helper);
+      yield test_async_throw(helper);
+    }
+    yield test_async_once();
+    yield test_async_invoke();
+    do_test_finished();
+  }).then(null, error => {
+    do_throw(error);
+  });
+}
+
+// Test that arguments are correctly passed through to the async function.
+function test_async_args(async) {
+  let obj = {
+    method: async(function*(a, b) {
+      do_check_eq(this, obj);
+      do_check_eq(a, "foo");
+      do_check_eq(b, "bar");
+    })
+  };
+
+  return obj.method("foo", "bar");
+}
+
+// Test that the return value from the async function is resolution value of
+// the promise.
+function test_async_return(async) {
+  let obj = {
+    method: async(function*(a, b) {
+      return a + b;
+    })
+  };
+
+  return obj.method("foo", "bar").then(ret => {
+    do_check_eq(ret, "foobar");
+  });
+}
+
+// Test that the throwing from an async function rejects the promise.
+function test_async_throw(async) {
+  let obj = {
+    method: async(function*() {
+      throw "boom";
+    })
+  };
+
+  return obj.method().then(null, error => {
+    do_check_eq(error, "boom");
+  });
+}
+
+// Test that asyncOnce only runs the async function once per instance and
+// returns the same promise for that instance.
+function test_async_once() {
+  let counter = 0;
+
+  function Foo() {}
+  Foo.prototype = {
+    ran: false,
+    method: asyncOnce(function*() {
+      yield Promise.resolve();
+      if (this.ran) {
+        do_throw("asyncOnce function unexpectedly ran twice on the same object");
+      }
+      this.ran = true;
+      return counter++;
+    })
+  };
+
+  let foo1 = new Foo();
+  let foo2 = new Foo();
+  let p1 = foo1.method();
+  let p2 = foo2.method();
+
+  do_check_neq(p1, p2);
+
+  let p3 = foo1.method();
+  do_check_eq(p1, p3);
+  do_check_false(foo1.ran);
+
+  let p4 = foo2.method();
+  do_check_eq(p2, p4);
+  do_check_false(foo2.ran);
+
+  return p1.then(ret => {
+    do_check_true(foo1.ran);
+    do_check_eq(ret, 0);
+    return p2;
+  }).then(ret => {
+    do_check_true(foo2.ran);
+    do_check_eq(ret, 1);
+  });
+}
+
+// Test invoke and call.
+function test_async_invoke() {
+  return Task.spawn(function*() {
+    function func(a, b, expectedThis, callback) {
+      "use strict";
+      do_check_eq(a, "foo");
+      do_check_eq(b, "bar");
+      do_check_eq(this, expectedThis);
+      callback(a + b);
+    }
+
+    // Test call.
+    let callResult = yield promiseCall(func, "foo", "bar", undefined);
+    do_check_eq(callResult, "foobar");
+
+
+    // Test invoke.
+    let obj = { method: func };
+    let invokeResult = yield promiseInvoke(obj, obj.method, "foo", "bar", obj);
+    do_check_eq(invokeResult, "foobar");
+
+
+    // Test passing multiple values to the callback.
+    function multipleResults(callback) {
+      callback("foo", "bar");
+    }
+
+    let results = yield promiseCall(multipleResults);
+    do_check_eq(results.length, 2);
+    do_check_eq(results[0], "foo");
+    do_check_eq(results[1], "bar");
+
+
+    // Test throwing from the function.
+    function thrower() {
+      throw "boom";
+    }
+
+    yield promiseCall(thrower).then(null, error => {
+      do_check_eq(error, "boom");
+    });
+  });
+}