toolkit/modules/tests/xpcshell/test_task.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* Any copyright is dedicated to the Public Domain.
michael@0 2 http://creativecommons.org/publicdomain/zero/1.0/ */
michael@0 3
michael@0 4 /**
michael@0 5 * This file tests the Task.jsm module.
michael@0 6 */
michael@0 7
michael@0 8 ////////////////////////////////////////////////////////////////////////////////
michael@0 9 /// Globals
michael@0 10
michael@0 11 const Cc = Components.classes;
michael@0 12 const Ci = Components.interfaces;
michael@0 13 const Cu = Components.utils;
michael@0 14 const Cr = Components.results;
michael@0 15
michael@0 16 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
michael@0 17
michael@0 18 XPCOMUtils.defineLazyModuleGetter(this, "Promise",
michael@0 19 "resource://gre/modules/Promise.jsm");
michael@0 20 XPCOMUtils.defineLazyModuleGetter(this, "Services",
michael@0 21 "resource://gre/modules/Services.jsm");
michael@0 22 XPCOMUtils.defineLazyModuleGetter(this, "Task",
michael@0 23 "resource://gre/modules/Task.jsm");
michael@0 24
michael@0 25 /**
michael@0 26 * Returns a promise that will be resolved with the given value, when an event
michael@0 27 * posted on the event loop of the main thread is processed.
michael@0 28 */
michael@0 29 function promiseResolvedLater(aValue) {
michael@0 30 let deferred = Promise.defer();
michael@0 31 Services.tm.mainThread.dispatch(function () deferred.resolve(aValue),
michael@0 32 Ci.nsIThread.DISPATCH_NORMAL);
michael@0 33 return deferred.promise;
michael@0 34 }
michael@0 35
michael@0 36 ////////////////////////////////////////////////////////////////////////////////
michael@0 37 /// Tests
michael@0 38
michael@0 39 function run_test()
michael@0 40 {
michael@0 41 run_next_test();
michael@0 42 }
michael@0 43
michael@0 44 add_test(function test_normal()
michael@0 45 {
michael@0 46 Task.spawn(function () {
michael@0 47 let result = yield Promise.resolve("Value");
michael@0 48 for (let i = 0; i < 3; i++) {
michael@0 49 result += yield promiseResolvedLater("!");
michael@0 50 }
michael@0 51 throw new Task.Result("Task result: " + result);
michael@0 52 }).then(function (result) {
michael@0 53 do_check_eq("Task result: Value!!!", result);
michael@0 54 run_next_test();
michael@0 55 }, function (ex) {
michael@0 56 do_throw("Unexpected error: " + ex);
michael@0 57 });
michael@0 58 });
michael@0 59
michael@0 60 add_test(function test_exceptions()
michael@0 61 {
michael@0 62 Task.spawn(function () {
michael@0 63 try {
michael@0 64 yield Promise.reject("Rejection result by promise.");
michael@0 65 do_throw("Exception expected because the promise was rejected.");
michael@0 66 } catch (ex) {
michael@0 67 // We catch this exception now, we will throw a different one later.
michael@0 68 do_check_eq("Rejection result by promise.", ex);
michael@0 69 }
michael@0 70 throw new Error("Exception uncaught by task.");
michael@0 71 }).then(function (result) {
michael@0 72 do_throw("Unexpected success!");
michael@0 73 }, function (ex) {
michael@0 74 do_check_eq("Exception uncaught by task.", ex.message);
michael@0 75 run_next_test();
michael@0 76 });
michael@0 77 });
michael@0 78
michael@0 79 add_test(function test_recursion()
michael@0 80 {
michael@0 81 function task_fibonacci(n) {
michael@0 82 throw new Task.Result(n < 2 ? n : (yield task_fibonacci(n - 1)) +
michael@0 83 (yield task_fibonacci(n - 2)));
michael@0 84 };
michael@0 85
michael@0 86 Task.spawn(task_fibonacci(6)).then(function (result) {
michael@0 87 do_check_eq(8, result);
michael@0 88 run_next_test();
michael@0 89 }, function (ex) {
michael@0 90 do_throw("Unexpected error: " + ex);
michael@0 91 });
michael@0 92 });
michael@0 93
michael@0 94 add_test(function test_spawn_primitive()
michael@0 95 {
michael@0 96 function fibonacci(n) {
michael@0 97 return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
michael@0 98 };
michael@0 99
michael@0 100 // Polymorphism between task and non-task functions (see "test_recursion").
michael@0 101 Task.spawn(fibonacci(6)).then(function (result) {
michael@0 102 do_check_eq(8, result);
michael@0 103 run_next_test();
michael@0 104 }, function (ex) {
michael@0 105 do_throw("Unexpected error: " + ex);
michael@0 106 });
michael@0 107 });
michael@0 108
michael@0 109 add_test(function test_spawn_function()
michael@0 110 {
michael@0 111 Task.spawn(function () {
michael@0 112 return "This is not a generator.";
michael@0 113 }).then(function (result) {
michael@0 114 do_check_eq("This is not a generator.", result);
michael@0 115 run_next_test();
michael@0 116 }, function (ex) {
michael@0 117 do_throw("Unexpected error: " + ex);
michael@0 118 });
michael@0 119 });
michael@0 120
michael@0 121 add_test(function test_spawn_function_this()
michael@0 122 {
michael@0 123 Task.spawn(function () {
michael@0 124 return this;
michael@0 125 }).then(function (result) {
michael@0 126 // Since the task function wasn't defined in strict mode, its "this" object
michael@0 127 // should be the same as the "this" object in this function, i.e. the global
michael@0 128 // object.
michael@0 129 do_check_eq(result, this);
michael@0 130 run_next_test();
michael@0 131 }, function (ex) {
michael@0 132 do_throw("Unexpected error: " + ex);
michael@0 133 });
michael@0 134 });
michael@0 135
michael@0 136 add_test(function test_spawn_function_this_strict()
michael@0 137 {
michael@0 138 "use strict";
michael@0 139 Task.spawn(function () {
michael@0 140 return this;
michael@0 141 }).then(function (result) {
michael@0 142 // Since the task function was defined in strict mode, its "this" object
michael@0 143 // should be undefined.
michael@0 144 do_check_eq(typeof(result), "undefined");
michael@0 145 run_next_test();
michael@0 146 }, function (ex) {
michael@0 147 do_throw("Unexpected error: " + ex);
michael@0 148 });
michael@0 149 });
michael@0 150
michael@0 151 add_test(function test_spawn_function_returning_promise()
michael@0 152 {
michael@0 153 Task.spawn(function () {
michael@0 154 return promiseResolvedLater("Resolution value.");
michael@0 155 }).then(function (result) {
michael@0 156 do_check_eq("Resolution value.", result);
michael@0 157 run_next_test();
michael@0 158 }, function (ex) {
michael@0 159 do_throw("Unexpected error: " + ex);
michael@0 160 });
michael@0 161 });
michael@0 162
michael@0 163 add_test(function test_spawn_function_exceptions()
michael@0 164 {
michael@0 165 Task.spawn(function () {
michael@0 166 throw new Error("Exception uncaught by task.");
michael@0 167 }).then(function (result) {
michael@0 168 do_throw("Unexpected success!");
michael@0 169 }, function (ex) {
michael@0 170 do_check_eq("Exception uncaught by task.", ex.message);
michael@0 171 run_next_test();
michael@0 172 });
michael@0 173 });
michael@0 174
michael@0 175 add_test(function test_spawn_function_taskresult()
michael@0 176 {
michael@0 177 Task.spawn(function () {
michael@0 178 throw new Task.Result("Task result");
michael@0 179 }).then(function (result) {
michael@0 180 do_check_eq("Task result", result);
michael@0 181 run_next_test();
michael@0 182 }, function (ex) {
michael@0 183 do_throw("Unexpected error: " + ex);
michael@0 184 });
michael@0 185 });
michael@0 186
michael@0 187 add_test(function test_yielded_undefined()
michael@0 188 {
michael@0 189 Task.spawn(function () {
michael@0 190 yield;
michael@0 191 throw new Task.Result("We continued correctly.");
michael@0 192 }).then(function (result) {
michael@0 193 do_check_eq("We continued correctly.", result);
michael@0 194 run_next_test();
michael@0 195 }, function (ex) {
michael@0 196 do_throw("Unexpected error: " + ex);
michael@0 197 });
michael@0 198 });
michael@0 199
michael@0 200 add_test(function test_yielded_primitive()
michael@0 201 {
michael@0 202 Task.spawn(function () {
michael@0 203 throw new Task.Result("Primitive " + (yield "value."));
michael@0 204 }).then(function (result) {
michael@0 205 do_check_eq("Primitive value.", result);
michael@0 206 run_next_test();
michael@0 207 }, function (ex) {
michael@0 208 do_throw("Unexpected error: " + ex);
michael@0 209 });
michael@0 210 });
michael@0 211
michael@0 212 add_test(function test_star_normal()
michael@0 213 {
michael@0 214 Task.spawn(function* () {
michael@0 215 let result = yield Promise.resolve("Value");
michael@0 216 for (let i = 0; i < 3; i++) {
michael@0 217 result += yield promiseResolvedLater("!");
michael@0 218 }
michael@0 219 return "Task result: " + result;
michael@0 220 }).then(function (result) {
michael@0 221 do_check_eq("Task result: Value!!!", result);
michael@0 222 run_next_test();
michael@0 223 }, function (ex) {
michael@0 224 do_throw("Unexpected error: " + ex);
michael@0 225 });
michael@0 226 });
michael@0 227
michael@0 228 add_test(function test_star_exceptions()
michael@0 229 {
michael@0 230 Task.spawn(function* () {
michael@0 231 try {
michael@0 232 yield Promise.reject("Rejection result by promise.");
michael@0 233 do_throw("Exception expected because the promise was rejected.");
michael@0 234 } catch (ex) {
michael@0 235 // We catch this exception now, we will throw a different one later.
michael@0 236 do_check_eq("Rejection result by promise.", ex);
michael@0 237 }
michael@0 238 throw new Error("Exception uncaught by task.");
michael@0 239 }).then(function (result) {
michael@0 240 do_throw("Unexpected success!");
michael@0 241 }, function (ex) {
michael@0 242 do_check_eq("Exception uncaught by task.", ex.message);
michael@0 243 run_next_test();
michael@0 244 });
michael@0 245 });
michael@0 246
michael@0 247 add_test(function test_star_recursion()
michael@0 248 {
michael@0 249 function* task_fibonacci(n) {
michael@0 250 return n < 2 ? n : (yield task_fibonacci(n - 1)) +
michael@0 251 (yield task_fibonacci(n - 2));
michael@0 252 };
michael@0 253
michael@0 254 Task.spawn(task_fibonacci(6)).then(function (result) {
michael@0 255 do_check_eq(8, result);
michael@0 256 run_next_test();
michael@0 257 }, function (ex) {
michael@0 258 do_throw("Unexpected error: " + ex);
michael@0 259 });
michael@0 260 });
michael@0 261
michael@0 262 add_test(function test_mixed_legacy_and_star()
michael@0 263 {
michael@0 264 Task.spawn(function* () {
michael@0 265 return yield (function() {
michael@0 266 throw new Task.Result(yield 5);
michael@0 267 })();
michael@0 268 }).then(function (result) {
michael@0 269 do_check_eq(5, result);
michael@0 270 run_next_test();
michael@0 271 }, function (ex) {
michael@0 272 do_throw("Unexpected error: " + ex);
michael@0 273 });
michael@0 274 });
michael@0 275
michael@0 276 add_test(function test_async_function_from_generator()
michael@0 277 {
michael@0 278 Task.spawn(function* () {
michael@0 279 let object = {
michael@0 280 asyncFunction: Task.async(function* (param) {
michael@0 281 do_check_eq(this, object);
michael@0 282 return param;
michael@0 283 })
michael@0 284 };
michael@0 285
michael@0 286 // Ensure the async function returns a promise that resolves as expected.
michael@0 287 do_check_eq((yield object.asyncFunction(1)), 1);
michael@0 288
michael@0 289 // Ensure a second call to the async function also returns such a promise.
michael@0 290 do_check_eq((yield object.asyncFunction(3)), 3);
michael@0 291 }).then(function () {
michael@0 292 run_next_test();
michael@0 293 }, function (ex) {
michael@0 294 do_throw("Unexpected error: " + ex);
michael@0 295 });
michael@0 296 });
michael@0 297
michael@0 298 add_test(function test_async_function_from_function()
michael@0 299 {
michael@0 300 Task.spawn(function* () {
michael@0 301 return Task.spawn(function* () {
michael@0 302 let object = {
michael@0 303 asyncFunction: Task.async(function (param) {
michael@0 304 do_check_eq(this, object);
michael@0 305 return param;
michael@0 306 })
michael@0 307 };
michael@0 308
michael@0 309 // Ensure the async function returns a promise that resolves as expected.
michael@0 310 do_check_eq((yield object.asyncFunction(5)), 5);
michael@0 311
michael@0 312 // Ensure a second call to the async function also returns such a promise.
michael@0 313 do_check_eq((yield object.asyncFunction(7)), 7);
michael@0 314 });
michael@0 315 }).then(function () {
michael@0 316 run_next_test();
michael@0 317 }, function (ex) {
michael@0 318 do_throw("Unexpected error: " + ex);
michael@0 319 });
michael@0 320 });
michael@0 321
michael@0 322 add_test(function test_async_function_that_throws_rejects_promise()
michael@0 323 {
michael@0 324 Task.spawn(function* () {
michael@0 325 let object = {
michael@0 326 asyncFunction: Task.async(function* () {
michael@0 327 throw "Rejected!";
michael@0 328 })
michael@0 329 };
michael@0 330
michael@0 331 yield object.asyncFunction();
michael@0 332 }).then(function () {
michael@0 333 do_throw("unexpected success calling async function that throws error");
michael@0 334 }, function (ex) {
michael@0 335 do_check_eq(ex, "Rejected!");
michael@0 336 run_next_test();
michael@0 337 });
michael@0 338 });
michael@0 339
michael@0 340 add_test(function test_async_return_function()
michael@0 341 {
michael@0 342 Task.spawn(function* () {
michael@0 343 // Ensure an async function that returns a function resolves to the function
michael@0 344 // itself instead of calling the function and resolving to its return value.
michael@0 345 return Task.spawn(function* () {
michael@0 346 let returnValue = function () {
michael@0 347 return "These aren't the droids you're looking for.";
michael@0 348 };
michael@0 349
michael@0 350 let asyncFunction = Task.async(function () {
michael@0 351 return returnValue;
michael@0 352 });
michael@0 353
michael@0 354 do_check_eq((yield asyncFunction()), returnValue);
michael@0 355 });
michael@0 356 }).then(function () {
michael@0 357 run_next_test();
michael@0 358 }, function (ex) {
michael@0 359 do_throw("Unexpected error: " + ex);
michael@0 360 });
michael@0 361 });
michael@0 362
michael@0 363 add_test(function test_async_throw_argument_not_function()
michael@0 364 {
michael@0 365 Task.spawn(function* () {
michael@0 366 // Ensure Task.async throws if its aTask argument is not a function.
michael@0 367 Assert.throws(() => Task.async("not a function"),
michael@0 368 /aTask argument must be a function/);
michael@0 369 }).then(function () {
michael@0 370 run_next_test();
michael@0 371 }, function (ex) {
michael@0 372 do_throw("Unexpected error: " + ex);
michael@0 373 });
michael@0 374 });
michael@0 375
michael@0 376 add_test(function test_async_throw_on_function_in_place_of_promise()
michael@0 377 {
michael@0 378 Task.spawn(function* () {
michael@0 379 // Ensure Task.spawn throws if passed an async function.
michael@0 380 Assert.throws(() => Task.spawn(Task.async(function* () {})),
michael@0 381 /Cannot use an async function in place of a promise/);
michael@0 382 }).then(function () {
michael@0 383 run_next_test();
michael@0 384 }, function (ex) {
michael@0 385 do_throw("Unexpected error: " + ex);
michael@0 386 });
michael@0 387 });

mercurial