dom/workers/test/promise_worker.js

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 function ok(a, msg) {
     2   dump("OK: " + !!a + "  =>  " + a + " " + msg + "\n");
     3   postMessage({type: 'status', status: !!a, msg: a + ": " + msg });
     4 }
     6 function is(a, b, msg) {
     7   dump("IS: " + (a===b) + "  =>  " + a + " | " + b + " " + msg + "\n");
     8   postMessage({type: 'status', status: a === b, msg: a + " === " + b + ": " + msg });
     9 }
    11 function isnot(a, b, msg) {
    12   dump("ISNOT: " + (a!==b) + "  =>  " + a + " | " + b + " " + msg + "\n");
    13   postMessage({type: 'status', status: a !== b, msg: a + " !== " + b + ": " + msg });
    14 }
    16 function promiseResolve() {
    17   ok(Promise, "Promise object should exist");
    19   var promise = new Promise(function(resolve, reject) {
    20     ok(resolve, "Promise.resolve exists");
    21     ok(reject, "Promise.reject exists");
    23     resolve(42);
    24   }).then(function(what) {
    25     ok(true, "Then - resolveCb has been called");
    26     is(what, 42, "ResolveCb received 42");
    27     runTest();
    28   }, function() {
    29     ok(false, "Then - rejectCb has been called");
    30     runTest();
    31   });
    32 }
    34 function promiseResolveNoArg() {
    35   var promise = new Promise(function(resolve, reject) {
    36     ok(resolve, "Promise.resolve exists");
    37     ok(reject, "Promise.reject exists");
    39     resolve();
    40   }).then(function(what) {
    41     ok(true, "Then - resolveCb has been called");
    42     is(what, undefined, "ResolveCb received undefined");
    43     runTest();
    44   }, function() {
    45     ok(false, "Then - rejectCb has been called");
    46     runTest();
    47   });
    48 }
    50 function promiseRejectNoHandler() {
    51   // This test only checks that the code that reports unhandled errors in the
    52   // Promises implementation does not crash or leak.
    53   var promise = new Promise(function(res, rej) {
    54     noSuchMethod();
    55   });
    56   runTest();
    57 }
    59 function promiseReject() {
    60   var promise = new Promise(function(resolve, reject) {
    61     reject(42);
    62   }).then(function(what) {
    63     ok(false, "Then - resolveCb has been called");
    64     runTest();
    65   }, function(what) {
    66     ok(true, "Then - rejectCb has been called");
    67     is(what, 42, "RejectCb received 42");
    68     runTest();
    69   });
    70 }
    72 function promiseRejectNoArg() {
    73   var promise = new Promise(function(resolve, reject) {
    74     reject();
    75   }).then(function(what) {
    76     ok(false, "Then - resolveCb has been called");
    77     runTest();
    78   }, function(what) {
    79     ok(true, "Then - rejectCb has been called");
    80     is(what, undefined, "RejectCb received undefined");
    81     runTest();
    82   });
    83 }
    85 function promiseException() {
    86   var promise = new Promise(function(resolve, reject) {
    87     throw 42;
    88   }).then(function(what) {
    89     ok(false, "Then - resolveCb has been called");
    90     runTest();
    91   }, function(what) {
    92     ok(true, "Then - rejectCb has been called");
    93     is(what, 42, "RejectCb received 42");
    94     runTest();
    95   });
    96 }
    98 function promiseAsync() {
    99   var global = "foo";
   100   var f = new Promise(function(r1, r2) {
   101     is(global, "foo", "Global should be foo");
   102     r1(42);
   103     is(global, "foo", "Global should still be foo");
   104     setTimeout(function() {
   105       is(global, "bar", "Global should still be bar!");
   106       runTest();
   107     }, 0);
   108   }).then(function() {
   109     global = "bar";
   110   });
   111   is(global, "foo", "Global should still be foo (2)");
   112 }
   114 function promiseDoubleThen() {
   115   var steps = 0;
   116   var promise = new Promise(function(r1, r2) {
   117     r1(42);
   118   });
   120   promise.then(function(what) {
   121     ok(true, "Then.resolve has been called");
   122     is(what, 42, "Value == 42");
   123     steps++;
   124   }, function(what) {
   125     ok(false, "Then.reject has been called");
   126   });
   128   promise.then(function(what) {
   129     ok(true, "Then.resolve has been called");
   130     is(steps, 1, "Then.resolve - step == 1");
   131     is(what, 42, "Value == 42");
   132     runTest();
   133   }, function(what) {
   134     ok(false, "Then.reject has been called");
   135   });
   136 }
   138 function promiseThenException() {
   139   var promise = new Promise(function(resolve, reject) {
   140     resolve(42);
   141   });
   143   promise.then(function(what) {
   144     ok(true, "Then.resolve has been called");
   145     throw "booh";
   146   }).catch(function(e) {
   147     ok(true, "Catch has been called!");
   148     runTest();
   149   });
   150 }
   152 function promiseThenCatchThen() {
   153   var promise = new Promise(function(resolve, reject) {
   154     resolve(42);
   155   });
   157   var promise2 = promise.then(function(what) {
   158     ok(true, "Then.resolve has been called");
   159     is(what, 42, "Value == 42");
   160     return what + 1;
   161   }, function(what) {
   162     ok(false, "Then.reject has been called");
   163   });
   165   isnot(promise, promise2, "These 2 promise objs are different");
   167   promise2.then(function(what) {
   168     ok(true, "Then.resolve has been called");
   169     is(what, 43, "Value == 43");
   170     return what + 1;
   171   }, function(what) {
   172     ok(false, "Then.reject has been called");
   173   }).catch(function() {
   174     ok(false, "Catch has been called");
   175   }).then(function(what) {
   176     ok(true, "Then.resolve has been called");
   177     is(what, 44, "Value == 44");
   178     runTest();
   179   }, function(what) {
   180     ok(false, "Then.reject has been called");
   181   });
   182 }
   184 function promiseRejectThenCatchThen() {
   185   var promise = new Promise(function(resolve, reject) {
   186     reject(42);
   187   });
   189   var promise2 = promise.then(function(what) {
   190     ok(false, "Then.resolve has been called");
   191   }, function(what) {
   192     ok(true, "Then.reject has been called");
   193     is(what, 42, "Value == 42");
   194     return what + 1;
   195   });
   197   isnot(promise, promise2, "These 2 promise objs are different");
   199   promise2.then(function(what) {
   200     ok(true, "Then.resolve has been called");
   201     is(what, 43, "Value == 43");
   202     return what+1;
   203   }).catch(function(what) {
   204     ok(false, "Catch has been called");
   205   }).then(function(what) {
   206     ok(true, "Then.resolve has been called");
   207     is(what, 44, "Value == 44");
   208     runTest();
   209   });
   210 }
   212 function promiseRejectThenCatchThen2() {
   213   var promise = new Promise(function(resolve, reject) {
   214     reject(42);
   215   });
   217   promise.then(function(what) {
   218     ok(true, "Then.resolve has been called");
   219     is(what, 42, "Value == 42");
   220     return what+1;
   221   }).catch(function(what) {
   222     is(what, 42, "Value == 42");
   223     ok(true, "Catch has been called");
   224     return what+1;
   225   }).then(function(what) {
   226     ok(true, "Then.resolve has been called");
   227     is(what, 43, "Value == 43");
   228     runTest();
   229   });
   230 }
   232 function promiseRejectThenCatchExceptionThen() {
   233   var promise = new Promise(function(resolve, reject) {
   234     reject(42);
   235   });
   237   promise.then(function(what) {
   238     ok(false, "Then.resolve has been called");
   239   }, function(what) {
   240     ok(true, "Then.reject has been called");
   241     is(what, 42, "Value == 42");
   242     throw(what + 1);
   243   }).catch(function(what) {
   244     ok(true, "Catch has been called");
   245     is(what, 43, "Value == 43");
   246     return what + 1;
   247   }).then(function(what) {
   248     ok(true, "Then.resolve has been called");
   249     is(what, 44, "Value == 44");
   250     runTest();
   251   });
   252 }
   254 function promiseThenCatchOrderingResolve() {
   255   var global = 0;
   256   var f = new Promise(function(r1, r2) {
   257     r1(42);
   258   });
   260   f.then(function() {
   261     f.then(function() {
   262       global++;
   263     });
   264     f.catch(function() {
   265       global++;
   266     });
   267     f.then(function() {
   268       global++;
   269     });
   270     setTimeout(function() {
   271       is(global, 2, "Many steps... should return 2");
   272       runTest();
   273     }, 0);
   274   });
   275 }
   277 function promiseThenCatchOrderingReject() {
   278   var global = 0;
   279   var f = new Promise(function(r1, r2) {
   280     r2(42);
   281   })
   283   f.then(function() {}, function() {
   284     f.then(function() {
   285       global++;
   286     });
   287     f.catch(function() {
   288       global++;
   289     });
   290     f.then(function() {}, function() {
   291       global++;
   292     });
   293     setTimeout(function() {
   294       is(global, 2, "Many steps... should return 2");
   295       runTest();
   296     }, 0);
   297   });
   298 }
   300 function promiseThenNoArg() {
   301   var promise = new Promise(function(resolve, reject) {
   302     resolve(42);
   303   });
   305   var clone = promise.then();
   306   isnot(promise, clone, "These 2 promise objs are different");
   307   promise.then(function(v) {
   308     clone.then(function(cv) {
   309       is(v, cv, "Both resolve to the same value");
   310       runTest();
   311     });
   312   });
   313 }
   315 function promiseThenUndefinedResolveFunction() {
   316   var promise = new Promise(function(resolve, reject) {
   317     reject(42);
   318   });
   320   try {
   321     promise.then(undefined, function(v) {
   322       is(v, 42, "Promise rejected with 42");
   323       runTest();
   324     });
   325   } catch (e) {
   326     ok(false, "then should not throw on undefined resolve function");
   327   }
   328 }
   330 function promiseThenNullResolveFunction() {
   331   var promise = new Promise(function(resolve, reject) {
   332     reject(42);
   333   });
   335   try {
   336     promise.then(null, function(v) {
   337       is(v, 42, "Promise rejected with 42");
   338       runTest();
   339     });
   340   } catch (e) {
   341     ok(false, "then should not throw on null resolve function");
   342   }
   343 }
   345 function promiseCatchNoArg() {
   346   var promise = new Promise(function(resolve, reject) {
   347     reject(42);
   348   });
   350   var clone = promise.catch();
   351   isnot(promise, clone, "These 2 promise objs are different");
   352   promise.catch(function(v) {
   353     clone.catch(function(cv) {
   354       is(v, cv, "Both reject to the same value");
   355       runTest();
   356     });
   357   });
   358 }
   360 function promiseNestedPromise() {
   361   new Promise(function(resolve, reject) {
   362     resolve(new Promise(function(resolve, reject) {
   363       ok(true, "Nested promise is executed");
   364       resolve(42);
   365     }));
   366   }).then(function(value) {
   367     is(value, 42, "Nested promise is executed and then == 42");
   368     runTest();
   369   });
   370 }
   372 function promiseNestedNestedPromise() {
   373   new Promise(function(resolve, reject) {
   374     resolve(new Promise(function(resolve, reject) {
   375       ok(true, "Nested promise is executed");
   376       resolve(42);
   377     }).then(function(what) { return what+1; }));
   378   }).then(function(value) {
   379     is(value, 43, "Nested promise is executed and then == 43");
   380     runTest();
   381   });
   382 }
   384 function promiseWrongNestedPromise() {
   385   new Promise(function(resolve, reject) {
   386     resolve(new Promise(function(r, r2) {
   387       ok(true, "Nested promise is executed");
   388       r(42);
   389     }));
   390     reject(42);
   391   }).then(function(value) {
   392     is(value, 42, "Nested promise is executed and then == 42");
   393     runTest();
   394   }, function(value) {
   395      ok(false, "This is wrong");
   396   });
   397 }
   399 function promiseLoop() {
   400   new Promise(function(resolve, reject) {
   401     resolve(new Promise(function(r1, r2) {
   402       ok(true, "Nested promise is executed");
   403       r1(new Promise(function(r1, r2) {
   404         ok(true, "Nested nested promise is executed");
   405         r1(42);
   406       }));
   407     }));
   408   }).then(function(value) {
   409     is(value, 42, "Nested nested promise is executed and then == 42");
   410     runTest();
   411   }, function(value) {
   412      ok(false, "This is wrong");
   413   });
   414 }
   416 function promiseStaticReject() {
   417   var promise = Promise.reject(42).then(function(what) {
   418     ok(false, "This should not be called");
   419   }, function(what) {
   420     is(what, 42, "Value == 42");
   421     runTest();
   422   });
   423 }
   425 function promiseStaticResolve() {
   426   var promise = Promise.resolve(42).then(function(what) {
   427     is(what, 42, "Value == 42");
   428     runTest();
   429   }, function() {
   430     ok(false, "This should not be called");
   431   });
   432 }
   434 function promiseResolveNestedPromise() {
   435   var promise = Promise.resolve(new Promise(function(r, r2) {
   436     ok(true, "Nested promise is executed");
   437     r(42);
   438   }, function() {
   439     ok(false, "This should not be called");
   440   })).then(function(what) {
   441     is(what, 42, "Value == 42");
   442     runTest();
   443   }, function() {
   444     ok(false, "This should not be called");
   445   });
   446 }
   448 function promiseRejectNoHandler() {
   449   // This test only checks that the code that reports unhandled errors in the
   450   // Promises implementation does not crash or leak.
   451   var promise = new Promise(function(res, rej) {
   452     noSuchMethod();
   453   });
   454   runTest();
   455 }
   457 function promiseUtilitiesDefined() {
   458   ok(Promise.all, "Promise.all must be defined when Promise is enabled.");
   459   ok(Promise.race, "Promise.race must be defined when Promise is enabled.");
   460   runTest();
   461 }
   463 function promiseAllArray() {
   464   var p = Promise.all([1, new Date(), Promise.resolve("firefox")]);
   465   ok(p instanceof Promise, "Return value of Promise.all should be a Promise.");
   466   p.then(function(values) {
   467     ok(Array.isArray(values), "Resolved value should be an array.");
   468     is(values.length, 3, "Resolved array length should match iterable's length.");
   469     is(values[0], 1, "Array values should match.");
   470     ok(values[1] instanceof Date, "Array values should match.");
   471     is(values[2], "firefox", "Array values should match.");
   472     runTest();
   473   }, function() {
   474     ok(false, "Promise.all shouldn't fail when iterable has no rejected Promises.");
   475     runTest();
   476   });
   477 }
   479 function promiseAllWaitsForAllPromises() {
   480   var arr = [
   481     new Promise(function(resolve) {
   482       setTimeout(resolve.bind(undefined, 1), 50);
   483     }),
   484     new Promise(function(resolve) {
   485       setTimeout(resolve.bind(undefined, 2), 10);
   486     }),
   487     new Promise(function(resolve) {
   488       setTimeout(resolve.bind(undefined, new Promise(function(resolve2) {
   489         resolve2(3);
   490       })), 10);
   491     }),
   492     new Promise(function(resolve) {
   493       setTimeout(resolve.bind(undefined, 4), 20);
   494     })
   495   ];
   497   var p = Promise.all(arr);
   498   p.then(function(values) {
   499     ok(Array.isArray(values), "Resolved value should be an array.");
   500     is(values.length, 4, "Resolved array length should match iterable's length.");
   501     is(values[0], 1, "Array values should match.");
   502     is(values[1], 2, "Array values should match.");
   503     is(values[2], 3, "Array values should match.");
   504     is(values[3], 4, "Array values should match.");
   505     runTest();
   506   }, function() {
   507     ok(false, "Promise.all shouldn't fail when iterable has no rejected Promises.");
   508     runTest();
   509   });
   510 }
   512 function promiseAllRejectFails() {
   513   var arr = [
   514     new Promise(function(resolve) {
   515       setTimeout(resolve.bind(undefined, 1), 50);
   516     }),
   517     new Promise(function(resolve, reject) {
   518       setTimeout(reject.bind(undefined, 2), 10);
   519     }),
   520     new Promise(function(resolve) {
   521       setTimeout(resolve.bind(undefined, 3), 10);
   522     }),
   523     new Promise(function(resolve) {
   524       setTimeout(resolve.bind(undefined, 4), 20);
   525     })
   526   ];
   528   var p = Promise.all(arr);
   529   p.then(function(values) {
   530     ok(false, "Promise.all shouldn't resolve when iterable has rejected Promises.");
   531     runTest();
   532   }, function(e) {
   533     ok(true, "Promise.all should reject when iterable has rejected Promises.");
   534     is(e, 2, "Rejection value should match.");
   535     runTest();
   536   });
   537 }
   539 function promiseRaceEmpty() {
   540   var p = Promise.race([]);
   541   ok(p instanceof Promise, "Should return a Promise.");
   542   // An empty race never resolves!
   543   runTest();
   544 }
   546 function promiseRaceValuesArray() {
   547   var p = Promise.race([true, new Date(), 3]);
   548   ok(p instanceof Promise, "Should return a Promise.");
   549   p.then(function(winner) {
   550     is(winner, true, "First value should win.");
   551     runTest();
   552   }, function(err) {
   553     ok(false, "Should not fail " + err + ".");
   554     runTest();
   555   });
   556 }
   558 function promiseRacePromiseArray() {
   559   var arr = [
   560     new Promise(function(resolve) {
   561       resolve("first");
   562     }),
   563     Promise.resolve("second"),
   564     new Promise(function() {}),
   565     new Promise(function(resolve) {
   566       setTimeout(function() {
   567         setTimeout(function() {
   568           resolve("fourth");
   569         }, 0);
   570       }, 0);
   571     }),
   572   ];
   574   var p = Promise.race(arr);
   575   p.then(function(winner) {
   576     is(winner, "first", "First queued resolution should win the race.");
   577     runTest();
   578   });
   579 }
   581 function promiseRaceReject() {
   582   var p = Promise.race([
   583     Promise.reject(new Error("Fail bad!")),
   584     new Promise(function(resolve) {
   585       setTimeout(resolve, 0);
   586     })
   587   ]);
   589   p.then(function() {
   590     ok(false, "Should not resolve when winning Promise rejected.");
   591     runTest();
   592   }, function(e) {
   593     ok(true, "Should be rejected");
   594     ok(e instanceof Error, "Should reject with Error.");
   595     ok(e.message == "Fail bad!", "Message should match.");
   596     runTest();
   597   });
   598 }
   600 function promiseRaceThrow() {
   601   var p = Promise.race([
   602     new Promise(function(resolve) {
   603       nonExistent();
   604     }),
   605     new Promise(function(resolve) {
   606       setTimeout(resolve, 0);
   607     })
   608   ]);
   610   p.then(function() {
   611     ok(false, "Should not resolve when winning Promise had an error.");
   612     runTest();
   613   }, function(e) {
   614     ok(true, "Should be rejected");
   615     ok(e instanceof ReferenceError, "Should reject with ReferenceError for function nonExistent().");
   616     runTest();
   617   });
   618 }
   620 function promiseResolveArray() {
   621   var p = Promise.resolve([1,2,3]);
   622   ok(p instanceof Promise, "Should return a Promise.");
   623   p.then(function(v) {
   624     ok(Array.isArray(v), "Resolved value should be an Array");
   625     is(v.length, 3, "Length should match");
   626     is(v[0], 1, "Resolved value should match original");
   627     is(v[1], 2, "Resolved value should match original");
   628     is(v[2], 3, "Resolved value should match original");
   629     runTest();
   630   });
   631 }
   633 function promiseResolveThenable() {
   634   var p = Promise.resolve({ then: function(onFulfill, onReject) { onFulfill(2); } });
   635   ok(p instanceof Promise, "Should cast to a Promise.");
   636   p.then(function(v) {
   637     is(v, 2, "Should resolve to 2.");
   638     runTest();
   639   }, function(e) {
   640     ok(false, "promiseResolveThenable should've resolved");
   641     runTest();
   642   });
   643 }
   645 function promiseResolvePromise() {
   646   var original = Promise.resolve(true);
   647   var cast = Promise.resolve(original);
   649   ok(cast instanceof Promise, "Should cast to a Promise.");
   650   is(cast, original, "Should return original Promise.");
   651   cast.then(function(v) {
   652     is(v, true, "Should resolve to true.");
   653     runTest();
   654   });
   655 }
   657 var tests = [
   658     promiseResolve,
   659     promiseReject,
   660     promiseException,
   661     promiseAsync,
   662     promiseDoubleThen,
   663     promiseThenException,
   664     promiseThenCatchThen,
   665     promiseRejectThenCatchThen,
   666     promiseRejectThenCatchThen2,
   667     promiseRejectThenCatchExceptionThen,
   668     promiseThenCatchOrderingResolve,
   669     promiseThenCatchOrderingReject,
   670     promiseNestedPromise,
   671     promiseNestedNestedPromise,
   672     promiseWrongNestedPromise,
   673     promiseLoop,
   674     promiseStaticReject,
   675     promiseStaticResolve,
   676     promiseResolveNestedPromise,
   677     promiseResolveNoArg,
   678     promiseRejectNoArg,
   680     promiseThenNoArg,
   681     promiseThenUndefinedResolveFunction,
   682     promiseThenNullResolveFunction,
   683     promiseCatchNoArg,
   684     promiseRejectNoHandler,
   686     promiseUtilitiesDefined,
   688     promiseAllArray,
   689     promiseAllWaitsForAllPromises,
   690     promiseAllRejectFails,
   692     promiseRaceEmpty,
   693     promiseRaceValuesArray,
   694     promiseRacePromiseArray,
   695     promiseRaceReject,
   696     promiseRaceThrow,
   698     promiseResolveArray,
   699     promiseResolveThenable,
   700     promiseResolvePromise,
   701 ];
   703 function runTest() {
   704   if (!tests.length) {
   705     postMessage({ type: 'finish' });
   706     return;
   707   }
   709   var test = tests.shift();
   710   test();
   711 }
   713 onmessage = function() {
   714   runTest();
   715 }

mercurial