summaryrefslogtreecommitdiffstats
path: root/devtools/shared/tests/unit/test_async-utils.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/shared/tests/unit/test_async-utils.js')
-rw-r--r--devtools/shared/tests/unit/test_async-utils.js157
1 files changed, 157 insertions, 0 deletions
diff --git a/devtools/shared/tests/unit/test_async-utils.js b/devtools/shared/tests/unit/test_async-utils.js
new file mode 100644
index 000000000..2b09b8260
--- /dev/null
+++ b/devtools/shared/tests/unit/test_async-utils.js
@@ -0,0 +1,157 @@
+/* -*- js-indent-level: 2; indent-tabs-mode: nil -*- */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Test async-utils.js
+
+const {Task} = require("devtools/shared/task");
+// |const| will not work because
+// it will make the Promise object immutable before assigning.
+// Using Object.defineProperty() instead.
+Object.defineProperty(this, "Promise", {
+ value: require("promise"),
+ writable: false, configurable: false
+});
+const {asyncOnce, promiseInvoke, promiseCall} = require("devtools/shared/async-utils");
+
+function run_test() {
+ do_test_pending();
+ Task.spawn(function* () {
+ yield test_async_args(asyncOnce);
+ yield test_async_return(asyncOnce);
+ yield test_async_throw(asyncOnce);
+
+ 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");
+ });
+ });
+}