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.

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

mercurial