tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

promise_worker.js (23509B)


      1 "use strict";
      2 
      3 /* eslint-disable mozilla/no-comparison-or-assignment-inside-ok */
      4 
      5 function ok(a, msg) {
      6  dump("OK: " + !!a + "  =>  " + a + " " + msg + "\n");
      7  postMessage({ type: "status", status: !!a, msg: a + ": " + msg });
      8 }
      9 
     10 function is(a, b, msg) {
     11  dump("IS: " + (a === b) + "  =>  " + a + " | " + b + " " + msg + "\n");
     12  postMessage({
     13    type: "status",
     14    status: a === b,
     15    msg: a + " === " + b + ": " + msg,
     16  });
     17 }
     18 
     19 function isnot(a, b, msg) {
     20  dump("ISNOT: " + (a !== b) + "  =>  " + a + " | " + b + " " + msg + "\n");
     21  postMessage({
     22    type: "status",
     23    status: a !== b,
     24    msg: a + " !== " + b + ": " + msg,
     25  });
     26 }
     27 
     28 function promiseResolve() {
     29  ok(Promise, "Promise object should exist");
     30 
     31  var promise = new Promise(function (resolve, reject) {
     32    ok(resolve, "Promise.resolve exists");
     33    ok(reject, "Promise.reject exists");
     34 
     35    resolve(42);
     36  }).then(
     37    function (what) {
     38      ok(true, "Then - resolveCb has been called");
     39      is(what, 42, "ResolveCb received 42");
     40      runTest();
     41    },
     42    function () {
     43      ok(false, "Then - rejectCb has been called");
     44      runTest();
     45    }
     46  );
     47 }
     48 
     49 function promiseResolveNoArg() {
     50  var promise = new Promise(function (resolve, reject) {
     51    ok(resolve, "Promise.resolve exists");
     52    ok(reject, "Promise.reject exists");
     53 
     54    resolve();
     55  }).then(
     56    function (what) {
     57      ok(true, "Then - resolveCb has been called");
     58      is(what, undefined, "ResolveCb received undefined");
     59      runTest();
     60    },
     61    function () {
     62      ok(false, "Then - rejectCb has been called");
     63      runTest();
     64    }
     65  );
     66 }
     67 
     68 function promiseRejectNoHandler() {
     69  // This test only checks that the code that reports unhandled errors in the
     70  // Promises implementation does not crash or leak.
     71  var promise = new Promise(function (res, rej) {
     72    noSuchMethod();
     73  });
     74  runTest();
     75 }
     76 
     77 function promiseReject() {
     78  var promise = new Promise(function (resolve, reject) {
     79    reject(42);
     80  }).then(
     81    function (what) {
     82      ok(false, "Then - resolveCb has been called");
     83      runTest();
     84    },
     85    function (what) {
     86      ok(true, "Then - rejectCb has been called");
     87      is(what, 42, "RejectCb received 42");
     88      runTest();
     89    }
     90  );
     91 }
     92 
     93 function promiseRejectNoArg() {
     94  var promise = new Promise(function (resolve, reject) {
     95    reject();
     96  }).then(
     97    function (what) {
     98      ok(false, "Then - resolveCb has been called");
     99      runTest();
    100    },
    101    function (what) {
    102      ok(true, "Then - rejectCb has been called");
    103      is(what, undefined, "RejectCb received undefined");
    104      runTest();
    105    }
    106  );
    107 }
    108 
    109 function promiseException() {
    110  var promise = new Promise(function (resolve, reject) {
    111    throw 42;
    112  }).then(
    113    function (what) {
    114      ok(false, "Then - resolveCb has been called");
    115      runTest();
    116    },
    117    function (what) {
    118      ok(true, "Then - rejectCb has been called");
    119      is(what, 42, "RejectCb received 42");
    120      runTest();
    121    }
    122  );
    123 }
    124 
    125 function promiseAsync_TimeoutResolveThen() {
    126  var handlerExecuted = false;
    127 
    128  setTimeout(function () {
    129    ok(handlerExecuted, "Handler should have been called before the timeout.");
    130 
    131    // Allow other assertions to run so the test could fail before the next one.
    132    setTimeout(runTest, 0);
    133  }, 0);
    134 
    135  Promise.resolve().then(function () {
    136    handlerExecuted = true;
    137  });
    138 
    139  ok(!handlerExecuted, "Handlers are not called before 'then' returns.");
    140 }
    141 
    142 function promiseAsync_ResolveTimeoutThen() {
    143  var handlerExecuted = false;
    144 
    145  var promise = Promise.resolve();
    146 
    147  setTimeout(function () {
    148    ok(handlerExecuted, "Handler should have been called before the timeout.");
    149 
    150    // Allow other assertions to run so the test could fail before the next one.
    151    setTimeout(runTest, 0);
    152  }, 0);
    153 
    154  promise.then(function () {
    155    handlerExecuted = true;
    156  });
    157 
    158  ok(!handlerExecuted, "Handlers are not called before 'then' returns.");
    159 }
    160 
    161 function promiseAsync_ResolveThenTimeout() {
    162  var handlerExecuted = false;
    163 
    164  Promise.resolve().then(function () {
    165    handlerExecuted = true;
    166  });
    167 
    168  setTimeout(function () {
    169    ok(handlerExecuted, "Handler should have been called before the timeout.");
    170 
    171    // Allow other assertions to run so the test could fail before the next one.
    172    setTimeout(runTest, 0);
    173  }, 0);
    174 
    175  ok(!handlerExecuted, "Handlers are not called before 'then' returns.");
    176 }
    177 
    178 function promiseAsync_SyncXHRAndImportScripts() {
    179  var handlerExecuted = false;
    180 
    181  Promise.resolve().then(function () {
    182    handlerExecuted = true;
    183 
    184    // Allow other assertions to run so the test could fail before the next one.
    185    setTimeout(runTest, 0);
    186  });
    187 
    188  ok(!handlerExecuted, "Handlers are not called until the next microtask.");
    189 
    190  var xhr = new XMLHttpRequest();
    191  xhr.open("GET", "testXHR.txt", false);
    192  xhr.send(null);
    193 
    194  ok(!handlerExecuted, "Sync XHR should not trigger microtask execution.");
    195 
    196  importScripts("../../../dom/xhr/tests/relativeLoad_import.js");
    197 
    198  ok(!handlerExecuted, "importScripts should not trigger microtask execution.");
    199 }
    200 
    201 function promiseDoubleThen() {
    202  var steps = 0;
    203  var promise = new Promise(function (r1, r2) {
    204    r1(42);
    205  });
    206 
    207  promise.then(
    208    function (what) {
    209      ok(true, "Then.resolve has been called");
    210      is(what, 42, "Value == 42");
    211      steps++;
    212    },
    213    function (what) {
    214      ok(false, "Then.reject has been called");
    215    }
    216  );
    217 
    218  promise.then(
    219    function (what) {
    220      ok(true, "Then.resolve has been called");
    221      is(steps, 1, "Then.resolve - step == 1");
    222      is(what, 42, "Value == 42");
    223      runTest();
    224    },
    225    function (what) {
    226      ok(false, "Then.reject has been called");
    227    }
    228  );
    229 }
    230 
    231 function promiseThenException() {
    232  var promise = new Promise(function (resolve, reject) {
    233    resolve(42);
    234  });
    235 
    236  promise
    237    .then(function (what) {
    238      ok(true, "Then.resolve has been called");
    239      throw "booh";
    240    })
    241    .catch(function (e) {
    242      ok(true, "Catch has been called!");
    243      runTest();
    244    });
    245 }
    246 
    247 function promiseThenCatchThen() {
    248  var promise = new Promise(function (resolve, reject) {
    249    resolve(42);
    250  });
    251 
    252  var promise2 = promise.then(
    253    function (what) {
    254      ok(true, "Then.resolve has been called");
    255      is(what, 42, "Value == 42");
    256      return what + 1;
    257    },
    258    function (what) {
    259      ok(false, "Then.reject has been called");
    260    }
    261  );
    262 
    263  isnot(promise, promise2, "These 2 promise objs are different");
    264 
    265  promise2
    266    .then(
    267      function (what) {
    268        ok(true, "Then.resolve has been called");
    269        is(what, 43, "Value == 43");
    270        return what + 1;
    271      },
    272      function (what) {
    273        ok(false, "Then.reject has been called");
    274      }
    275    )
    276    .catch(function () {
    277      ok(false, "Catch has been called");
    278    })
    279    .then(
    280      function (what) {
    281        ok(true, "Then.resolve has been called");
    282        is(what, 44, "Value == 44");
    283        runTest();
    284      },
    285      function (what) {
    286        ok(false, "Then.reject has been called");
    287      }
    288    );
    289 }
    290 
    291 function promiseRejectThenCatchThen() {
    292  var promise = new Promise(function (resolve, reject) {
    293    reject(42);
    294  });
    295 
    296  var promise2 = promise.then(
    297    function (what) {
    298      ok(false, "Then.resolve has been called");
    299    },
    300    function (what) {
    301      ok(true, "Then.reject has been called");
    302      is(what, 42, "Value == 42");
    303      return what + 1;
    304    }
    305  );
    306 
    307  isnot(promise, promise2, "These 2 promise objs are different");
    308 
    309  promise2
    310    .then(function (what) {
    311      ok(true, "Then.resolve has been called");
    312      is(what, 43, "Value == 43");
    313      return what + 1;
    314    })
    315    .catch(function (what) {
    316      ok(false, "Catch has been called");
    317    })
    318    .then(function (what) {
    319      ok(true, "Then.resolve has been called");
    320      is(what, 44, "Value == 44");
    321      runTest();
    322    });
    323 }
    324 
    325 function promiseRejectThenCatchThen2() {
    326  var promise = new Promise(function (resolve, reject) {
    327    reject(42);
    328  });
    329 
    330  promise
    331    .then(function (what) {
    332      ok(true, "Then.resolve has been called");
    333      is(what, 42, "Value == 42");
    334      return what + 1;
    335    })
    336    .catch(function (what) {
    337      is(what, 42, "Value == 42");
    338      ok(true, "Catch has been called");
    339      return what + 1;
    340    })
    341    .then(function (what) {
    342      ok(true, "Then.resolve has been called");
    343      is(what, 43, "Value == 43");
    344      runTest();
    345    });
    346 }
    347 
    348 function promiseRejectThenCatchExceptionThen() {
    349  var promise = new Promise(function (resolve, reject) {
    350    reject(42);
    351  });
    352 
    353  promise
    354    .then(
    355      function (what) {
    356        ok(false, "Then.resolve has been called");
    357      },
    358      function (what) {
    359        ok(true, "Then.reject has been called");
    360        is(what, 42, "Value == 42");
    361        throw what + 1;
    362      }
    363    )
    364    .catch(function (what) {
    365      ok(true, "Catch has been called");
    366      is(what, 43, "Value == 43");
    367      return what + 1;
    368    })
    369    .then(function (what) {
    370      ok(true, "Then.resolve has been called");
    371      is(what, 44, "Value == 44");
    372      runTest();
    373    });
    374 }
    375 
    376 function promiseThenCatchOrderingResolve() {
    377  var global = 0;
    378  var f = new Promise(function (r1, r2) {
    379    r1(42);
    380  });
    381 
    382  f.then(function () {
    383    f.then(function () {
    384      global++;
    385    });
    386    f.catch(function () {
    387      global++;
    388    });
    389    f.then(function () {
    390      global++;
    391    });
    392    setTimeout(function () {
    393      is(global, 2, "Many steps... should return 2");
    394      runTest();
    395    }, 0);
    396  });
    397 }
    398 
    399 function promiseThenCatchOrderingReject() {
    400  var global = 0;
    401  var f = new Promise(function (r1, r2) {
    402    r2(42);
    403  });
    404 
    405  f.then(
    406    function () {},
    407    function () {
    408      f.then(function () {
    409        global++;
    410      });
    411      f.catch(function () {
    412        global++;
    413      });
    414      f.then(
    415        function () {},
    416        function () {
    417          global++;
    418        }
    419      );
    420      setTimeout(function () {
    421        is(global, 2, "Many steps... should return 2");
    422        runTest();
    423      }, 0);
    424    }
    425  );
    426 }
    427 
    428 function promiseThenNoArg() {
    429  var promise = new Promise(function (resolve, reject) {
    430    resolve(42);
    431  });
    432 
    433  // eslint-disable-next-line promise/valid-params
    434  var clone = promise.then();
    435  isnot(promise, clone, "These 2 promise objs are different");
    436  promise.then(function (v) {
    437    clone.then(function (cv) {
    438      is(v, cv, "Both resolve to the same value");
    439      runTest();
    440    });
    441  });
    442 }
    443 
    444 function promiseThenUndefinedResolveFunction() {
    445  var promise = new Promise(function (resolve, reject) {
    446    reject(42);
    447  });
    448 
    449  try {
    450    promise.then(undefined, function (v) {
    451      is(v, 42, "Promise rejected with 42");
    452      runTest();
    453    });
    454  } catch (e) {
    455    ok(false, "then should not throw on undefined resolve function");
    456  }
    457 }
    458 
    459 function promiseThenNullResolveFunction() {
    460  var promise = new Promise(function (resolve, reject) {
    461    reject(42);
    462  });
    463 
    464  try {
    465    promise.then(null, function (v) {
    466      is(v, 42, "Promise rejected with 42");
    467      runTest();
    468    });
    469  } catch (e) {
    470    ok(false, "then should not throw on null resolve function");
    471  }
    472 }
    473 
    474 function promiseCatchNoArg() {
    475  var promise = new Promise(function (resolve, reject) {
    476    reject(42);
    477  });
    478 
    479  // eslint-disable-next-line promise/valid-params
    480  var clone = promise.catch();
    481  isnot(promise, clone, "These 2 promise objs are different");
    482  promise.catch(function (v) {
    483    clone.catch(function (cv) {
    484      is(v, cv, "Both reject to the same value");
    485      runTest();
    486    });
    487  });
    488 }
    489 
    490 function promiseNestedPromise() {
    491  new Promise(function (resolve, reject) {
    492    resolve(
    493      new Promise(function (r) {
    494        ok(true, "Nested promise is executed");
    495        r(42);
    496      })
    497    );
    498  }).then(function (value) {
    499    is(value, 42, "Nested promise is executed and then == 42");
    500    runTest();
    501  });
    502 }
    503 
    504 function promiseNestedNestedPromise() {
    505  new Promise(function (resolve, reject) {
    506    resolve(
    507      new Promise(function (r) {
    508        ok(true, "Nested promise is executed");
    509        r(42);
    510      }).then(function (what) {
    511        return what + 1;
    512      })
    513    );
    514  }).then(function (value) {
    515    is(value, 43, "Nested promise is executed and then == 43");
    516    runTest();
    517  });
    518 }
    519 
    520 function promiseWrongNestedPromise() {
    521  new Promise(function (resolve, reject) {
    522    resolve(
    523      new Promise(function (r, r2) {
    524        ok(true, "Nested promise is executed");
    525        r(42);
    526      })
    527    );
    528    reject(42);
    529  }).then(
    530    function (value) {
    531      is(value, 42, "Nested promise is executed and then == 42");
    532      runTest();
    533    },
    534    function (value) {
    535      ok(false, "This is wrong");
    536    }
    537  );
    538 }
    539 
    540 function promiseLoop() {
    541  new Promise(function (resolve, reject) {
    542    resolve(
    543      new Promise(function (r1, r2) {
    544        ok(true, "Nested promise is executed");
    545        r1(
    546          new Promise(function (r3, r4) {
    547            ok(true, "Nested nested promise is executed");
    548            r3(42);
    549          })
    550        );
    551      })
    552    );
    553  }).then(
    554    function (value) {
    555      is(value, 42, "Nested nested promise is executed and then == 42");
    556      runTest();
    557    },
    558    function (value) {
    559      ok(false, "This is wrong");
    560    }
    561  );
    562 }
    563 
    564 function promiseStaticReject() {
    565  var promise = Promise.reject(42).then(
    566    function (what) {
    567      ok(false, "This should not be called");
    568    },
    569    function (what) {
    570      is(what, 42, "Value == 42");
    571      runTest();
    572    }
    573  );
    574 }
    575 
    576 function promiseStaticResolve() {
    577  var promise = Promise.resolve(42).then(
    578    function (what) {
    579      is(what, 42, "Value == 42");
    580      runTest();
    581    },
    582    function () {
    583      ok(false, "This should not be called");
    584    }
    585  );
    586 }
    587 
    588 function promiseResolveNestedPromise() {
    589  var promise = Promise.resolve(
    590    new Promise(
    591      function (r, r2) {
    592        ok(true, "Nested promise is executed");
    593        r(42);
    594      },
    595      function () {
    596        ok(false, "This should not be called");
    597      }
    598    )
    599  ).then(
    600    function (what) {
    601      is(what, 42, "Value == 42");
    602      runTest();
    603    },
    604    function () {
    605      ok(false, "This should not be called");
    606    }
    607  );
    608 }
    609 
    610 function promiseUtilitiesDefined() {
    611  ok(Promise.all, "Promise.all must be defined when Promise is enabled.");
    612  ok(Promise.race, "Promise.race must be defined when Promise is enabled.");
    613  runTest();
    614 }
    615 
    616 function promiseAllArray() {
    617  var p = Promise.all([1, new Date(), Promise.resolve("firefox")]);
    618  ok(p instanceof Promise, "Return value of Promise.all should be a Promise.");
    619  p.then(
    620    function (values) {
    621      ok(Array.isArray(values), "Resolved value should be an array.");
    622      is(
    623        values.length,
    624        3,
    625        "Resolved array length should match iterable's length."
    626      );
    627      is(values[0], 1, "Array values should match.");
    628      ok(values[1] instanceof Date, "Array values should match.");
    629      is(values[2], "firefox", "Array values should match.");
    630      runTest();
    631    },
    632    function () {
    633      ok(
    634        false,
    635        "Promise.all shouldn't fail when iterable has no rejected Promises."
    636      );
    637      runTest();
    638    }
    639  );
    640 }
    641 
    642 function promiseAllWaitsForAllPromises() {
    643  var arr = [
    644    new Promise(function (resolve) {
    645      setTimeout(resolve.bind(undefined, 1), 50);
    646    }),
    647    new Promise(function (resolve) {
    648      setTimeout(resolve.bind(undefined, 2), 10);
    649    }),
    650    new Promise(function (resolve) {
    651      setTimeout(
    652        resolve.bind(
    653          undefined,
    654          new Promise(function (resolve2) {
    655            resolve2(3);
    656          })
    657        ),
    658        10
    659      );
    660    }),
    661    new Promise(function (resolve) {
    662      setTimeout(resolve.bind(undefined, 4), 20);
    663    }),
    664  ];
    665 
    666  var p = Promise.all(arr);
    667  p.then(
    668    function (values) {
    669      ok(Array.isArray(values), "Resolved value should be an array.");
    670      is(
    671        values.length,
    672        4,
    673        "Resolved array length should match iterable's length."
    674      );
    675      is(values[0], 1, "Array values should match.");
    676      is(values[1], 2, "Array values should match.");
    677      is(values[2], 3, "Array values should match.");
    678      is(values[3], 4, "Array values should match.");
    679      runTest();
    680    },
    681    function () {
    682      ok(
    683        false,
    684        "Promise.all shouldn't fail when iterable has no rejected Promises."
    685      );
    686      runTest();
    687    }
    688  );
    689 }
    690 
    691 function promiseAllRejectFails() {
    692  var arr = [
    693    new Promise(function (resolve) {
    694      setTimeout(resolve.bind(undefined, 1), 50);
    695    }),
    696    new Promise(function (resolve, reject) {
    697      setTimeout(reject.bind(undefined, 2), 10);
    698    }),
    699    new Promise(function (resolve) {
    700      setTimeout(resolve.bind(undefined, 3), 10);
    701    }),
    702    new Promise(function (resolve) {
    703      setTimeout(resolve.bind(undefined, 4), 20);
    704    }),
    705  ];
    706 
    707  var p = Promise.all(arr);
    708  p.then(
    709    function (values) {
    710      ok(
    711        false,
    712        "Promise.all shouldn't resolve when iterable has rejected Promises."
    713      );
    714      runTest();
    715    },
    716    function (e) {
    717      ok(
    718        true,
    719        "Promise.all should reject when iterable has rejected Promises."
    720      );
    721      is(e, 2, "Rejection value should match.");
    722      runTest();
    723    }
    724  );
    725 }
    726 
    727 function promiseRaceEmpty() {
    728  var p = Promise.race([]);
    729  ok(p instanceof Promise, "Should return a Promise.");
    730  // An empty race never resolves!
    731  runTest();
    732 }
    733 
    734 function promiseRaceValuesArray() {
    735  var p = Promise.race([true, new Date(), 3]);
    736  ok(p instanceof Promise, "Should return a Promise.");
    737  p.then(
    738    function (winner) {
    739      is(winner, true, "First value should win.");
    740      runTest();
    741    },
    742    function (err) {
    743      ok(false, "Should not fail " + err + ".");
    744      runTest();
    745    }
    746  );
    747 }
    748 
    749 function promiseRacePromiseArray() {
    750  var arr = [
    751    new Promise(function (resolve) {
    752      resolve("first");
    753    }),
    754    Promise.resolve("second"),
    755    new Promise(function () {}),
    756    new Promise(function (resolve) {
    757      setTimeout(function () {
    758        setTimeout(function () {
    759          resolve("fourth");
    760        }, 0);
    761      }, 0);
    762    }),
    763  ];
    764 
    765  var p = Promise.race(arr);
    766  p.then(function (winner) {
    767    is(winner, "first", "First queued resolution should win the race.");
    768    runTest();
    769  });
    770 }
    771 
    772 function promiseRaceReject() {
    773  var p = Promise.race([
    774    Promise.reject(new Error("Fail bad!")),
    775    new Promise(function (resolve) {
    776      setTimeout(resolve, 0);
    777    }),
    778  ]);
    779 
    780  p.then(
    781    function () {
    782      ok(false, "Should not resolve when winning Promise rejected.");
    783      runTest();
    784    },
    785    function (e) {
    786      ok(true, "Should be rejected");
    787      ok(e instanceof Error, "Should reject with Error.");
    788      ok(e.message == "Fail bad!", "Message should match.");
    789      runTest();
    790    }
    791  );
    792 }
    793 
    794 function promiseRaceThrow() {
    795  var p = Promise.race([
    796    new Promise(function (resolve) {
    797      nonExistent();
    798    }),
    799    new Promise(function (resolve) {
    800      setTimeout(resolve, 0);
    801    }),
    802  ]);
    803 
    804  p.then(
    805    function () {
    806      ok(false, "Should not resolve when winning Promise had an error.");
    807      runTest();
    808    },
    809    function (e) {
    810      ok(true, "Should be rejected");
    811      ok(
    812        e instanceof ReferenceError,
    813        "Should reject with ReferenceError for function nonExistent()."
    814      );
    815      runTest();
    816    }
    817  );
    818 }
    819 
    820 function promiseResolveArray() {
    821  var p = Promise.resolve([1, 2, 3]);
    822  ok(p instanceof Promise, "Should return a Promise.");
    823  p.then(function (v) {
    824    ok(Array.isArray(v), "Resolved value should be an Array");
    825    is(v.length, 3, "Length should match");
    826    is(v[0], 1, "Resolved value should match original");
    827    is(v[1], 2, "Resolved value should match original");
    828    is(v[2], 3, "Resolved value should match original");
    829    runTest();
    830  });
    831 }
    832 
    833 function promiseResolveThenable() {
    834  var p = Promise.resolve({
    835    then(onFulfill, onReject) {
    836      onFulfill(2);
    837    },
    838  });
    839  ok(p instanceof Promise, "Should cast to a Promise.");
    840  p.then(
    841    function (v) {
    842      is(v, 2, "Should resolve to 2.");
    843      runTest();
    844    },
    845    function (e) {
    846      ok(false, "promiseResolveThenable should've resolved");
    847      runTest();
    848    }
    849  );
    850 }
    851 
    852 function promiseResolvePromise() {
    853  var original = Promise.resolve(true);
    854  var cast = Promise.resolve(original);
    855 
    856  ok(cast instanceof Promise, "Should cast to a Promise.");
    857  is(cast, original, "Should return original Promise.");
    858  cast.then(function (v) {
    859    is(v, true, "Should resolve to true.");
    860    runTest();
    861  });
    862 }
    863 
    864 // Bug 1009569.
    865 // Ensure that thenables are run on a clean stack asynchronously.
    866 // Test case adopted from
    867 // https://gist.github.com/getify/d64bb01751b50ed6b281#file-bug1-js.
    868 function promiseResolveThenableCleanStack() {
    869  function immed(s) {
    870    x++;
    871    s();
    872  }
    873  function incX() {
    874    x++;
    875  }
    876 
    877  var x = 0;
    878  var thenable = { then: immed };
    879  var results = [];
    880 
    881  var p = Promise.resolve(thenable).then(incX);
    882  results.push(x);
    883 
    884  // check what happens after all "next cycle" steps
    885  // have had a chance to complete
    886  setTimeout(function () {
    887    // Result should be [0, 2] since `thenable` will be called async.
    888    is(results[0], 0, "Expected thenable to be called asynchronously");
    889    // See Bug 1023547 comment 13 for why this check has to be gated on p.
    890    p.then(function () {
    891      results.push(x);
    892      is(results[1], 2, "Expected thenable to be called asynchronously");
    893      runTest();
    894    });
    895  }, 1000);
    896 }
    897 
    898 // Bug 1062323
    899 function promiseWrapperAsyncResolution() {
    900  var p = new Promise(function (resolve, reject) {
    901    resolve();
    902  });
    903 
    904  var results = [];
    905  var q = p
    906    .then(function () {
    907      results.push("1-1");
    908    })
    909    .then(function () {
    910      results.push("1-2");
    911    })
    912    .then(function () {
    913      results.push("1-3");
    914    });
    915 
    916  var r = p
    917    .then(function () {
    918      results.push("2-1");
    919    })
    920    .then(function () {
    921      results.push("2-2");
    922    })
    923    .then(function () {
    924      results.push("2-3");
    925    });
    926 
    927  Promise.all([q, r]).then(
    928    function () {
    929      var match =
    930        results[0] == "1-1" &&
    931        results[1] == "2-1" &&
    932        results[2] == "1-2" &&
    933        results[3] == "2-2" &&
    934        results[4] == "1-3" &&
    935        results[5] == "2-3";
    936      ok(match, "Chained promises should resolve asynchronously.");
    937      runTest();
    938    },
    939    function () {
    940      ok(false, "promiseWrapperAsyncResolution: One of the promises failed.");
    941      runTest();
    942    }
    943  );
    944 }
    945 
    946 var tests = [
    947  promiseResolve,
    948  promiseReject,
    949  promiseException,
    950  promiseAsync_TimeoutResolveThen,
    951  promiseAsync_ResolveTimeoutThen,
    952  promiseAsync_ResolveThenTimeout,
    953  promiseAsync_SyncXHRAndImportScripts,
    954  promiseDoubleThen,
    955  promiseThenException,
    956  promiseThenCatchThen,
    957  promiseRejectThenCatchThen,
    958  promiseRejectThenCatchThen2,
    959  promiseRejectThenCatchExceptionThen,
    960  promiseThenCatchOrderingResolve,
    961  promiseThenCatchOrderingReject,
    962  promiseNestedPromise,
    963  promiseNestedNestedPromise,
    964  promiseWrongNestedPromise,
    965  promiseLoop,
    966  promiseStaticReject,
    967  promiseStaticResolve,
    968  promiseResolveNestedPromise,
    969  promiseResolveNoArg,
    970  promiseRejectNoArg,
    971 
    972  promiseThenNoArg,
    973  promiseThenUndefinedResolveFunction,
    974  promiseThenNullResolveFunction,
    975  promiseCatchNoArg,
    976  promiseRejectNoHandler,
    977 
    978  promiseUtilitiesDefined,
    979 
    980  promiseAllArray,
    981  promiseAllWaitsForAllPromises,
    982  promiseAllRejectFails,
    983 
    984  promiseRaceEmpty,
    985  promiseRaceValuesArray,
    986  promiseRacePromiseArray,
    987  promiseRaceReject,
    988  promiseRaceThrow,
    989 
    990  promiseResolveArray,
    991  promiseResolveThenable,
    992  promiseResolvePromise,
    993 
    994  promiseResolveThenableCleanStack,
    995 
    996  promiseWrapperAsyncResolution,
    997 ];
    998 
    999 function runTest() {
   1000  if (!tests.length) {
   1001    postMessage({ type: "finish" });
   1002    return;
   1003  }
   1004 
   1005  var test = tests.shift();
   1006  test();
   1007 }
   1008 
   1009 onmessage = function () {
   1010  runTest();
   1011 };