diff options
Diffstat (limited to 'devtools/shared/tests/unit/test_async-utils.js')
-rw-r--r-- | devtools/shared/tests/unit/test_async-utils.js | 157 |
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"); + }); + }); +} |