From 0832fc67bda10153af80e929de1dc2a325022b2c Mon Sep 17 00:00:00 2001 From: Brandon Benvie Date: Wed, 19 Feb 2014 14:15:06 -0800 Subject: [PATCH] Bug 974065 - Add test file missing from previous push. r=me --- .../devtools/tests/unit/test_async-utils.js | 153 ++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 toolkit/devtools/tests/unit/test_async-utils.js diff --git a/toolkit/devtools/tests/unit/test_async-utils.js b/toolkit/devtools/tests/unit/test_async-utils.js new file mode 100644 index 000000000000..2b5e77e8e20a --- /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"); + }); + }); +}