tor-browser

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

test_promise.html (21963B)


      1 <!--
      2  Any copyright is dedicated to the Public Domain.
      3  http://creativecommons.org/publicdomain/zero/1.0/
      4 -->
      5 <html>
      6 <head>
      7  <title>Basic Promise Test</title>
      8  <script src="/tests/SimpleTest/SimpleTest.js"></script>
      9  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
     10 </head>
     11 <body>
     12 <p id="display"></p>
     13 <div id="content" style="display: none">
     14 
     15 </div>
     16 <pre id="test">
     17 <script type="application/javascript"><!--
     18 
     19 function promiseResolve() {
     20  ok(Promise, "Promise object should exist");
     21 
     22  var promise = new Promise(function(resolve, reject) {
     23    ok(resolve, "Promise.resolve exists");
     24    ok(reject, "Promise.reject exists");
     25 
     26    resolve(42);
     27  });
     28  promise.then(function(what) {
     29    ok(true, "Then - resolveCb has been called");
     30    is(what, 42, "ResolveCb received 42");
     31    runTest();
     32  }, function() {
     33    ok(false, "Then - rejectCb has been called");
     34    runTest();
     35  });
     36 }
     37 
     38 function promiseResolveNoArg() {
     39  var promise = new Promise(function(resolve, reject) {
     40    ok(resolve, "Promise.resolve exists");
     41    ok(reject, "Promise.reject exists");
     42 
     43    resolve();
     44  });
     45  promise.then(function(what) {
     46    ok(true, "Then - resolveCb has been called");
     47    is(what, undefined, "ResolveCb received undefined");
     48    runTest();
     49  }, function() {
     50    ok(false, "Then - rejectCb has been called");
     51    runTest();
     52  });
     53 }
     54 
     55 function promiseReject() {
     56  var promise = new Promise(function(resolve, reject) {
     57    reject(42);
     58  });
     59  promise.then(function() {
     60    ok(false, "Then - resolveCb has been called");
     61    runTest();
     62  }, function(what) {
     63    ok(true, "Then - rejectCb has been called");
     64    is(what, 42, "RejectCb received 42");
     65    runTest();
     66  });
     67 }
     68 
     69 function promiseRejectNoHandler() {
     70  // This test only checks that the code that reports unhandled errors in the
     71  // Promises implementation does not crash or leak.
     72 
     73  new Promise(function() {
     74    // eslint-disable-next-line no-undef
     75    noSuchMethod();
     76  });
     77  runTest();
     78 }
     79 
     80 function promiseRejectNoArg() {
     81  var promise = new Promise(function(resolve, reject) {
     82    reject();
     83  });
     84  promise.then(function() {
     85    ok(false, "Then - resolveCb has been called");
     86    runTest();
     87  }, function(what) {
     88    ok(true, "Then - rejectCb has been called");
     89    is(what, undefined, "RejectCb received undefined");
     90    runTest();
     91  });
     92 }
     93 
     94 function promiseException() {
     95  var promise = new Promise(function() {
     96    // eslint-disable-next-line no-throw-literal
     97    throw 42;
     98  });
     99  promise.then(function() {
    100    ok(false, "Then - resolveCb has been called");
    101    runTest();
    102  }, function(what) {
    103    ok(true, "Then - rejectCb has been called");
    104    is(what, 42, "RejectCb received 42");
    105    runTest();
    106  });
    107 }
    108 
    109 function promiseGC() {
    110  var resolve;
    111  var promise = new Promise(function(r1) {
    112    resolve = r1;
    113  });
    114  promise.then(function() {
    115    ok(true, "Then - promise is still alive");
    116    runTest();
    117  });
    118 
    119  promise = null;
    120 
    121  SpecialPowers.gc();
    122  SpecialPowers.forceGC();
    123  SpecialPowers.forceCC();
    124 
    125  resolve(42);
    126 }
    127 
    128 function promiseAsync_TimeoutResolveThen() {
    129  var handlerExecuted = false;
    130 
    131  setTimeout(function() {
    132    ok(handlerExecuted, "Handler should have been called before the timeout.");
    133 
    134    // Allow other assertions to run so the test could fail before the next one.
    135    setTimeout(runTest, 0);
    136  }, 0);
    137 
    138  Promise.resolve().then(function() {
    139    handlerExecuted = true;
    140  });
    141 
    142  ok(!handlerExecuted, "Handlers are not called before 'then' returns.");
    143 }
    144 
    145 function promiseAsync_ResolveTimeoutThen() {
    146  var handlerExecuted = false;
    147 
    148  var promise = Promise.resolve();
    149 
    150  setTimeout(function() {
    151    ok(handlerExecuted, "Handler should have been called before the timeout.");
    152 
    153    // Allow other assertions to run so the test could fail before the next one.
    154    setTimeout(runTest, 0);
    155  }, 0);
    156 
    157  promise.then(function() {
    158    handlerExecuted = true;
    159  });
    160 
    161  ok(!handlerExecuted, "Handlers are not called before 'then' returns.");
    162 }
    163 
    164 function promiseAsync_ResolveThenTimeout() {
    165  var handlerExecuted = false;
    166 
    167  Promise.resolve().then(function() {
    168    handlerExecuted = true;
    169  });
    170 
    171  setTimeout(function() {
    172    ok(handlerExecuted, "Handler should have been called before the timeout.");
    173 
    174    // Allow other assertions to run so the test could fail before the next one.
    175    setTimeout(runTest, 0);
    176  }, 0);
    177 
    178  ok(!handlerExecuted, "Handlers are not called before 'then' returns.");
    179 }
    180 
    181 function promiseAsync_SyncXHR() {
    182  var handlerExecuted = false;
    183 
    184  Promise.resolve().then(function() {
    185    handlerExecuted = true;
    186 
    187    // Allow other assertions to run so the test could fail before the next one.
    188    setTimeout(runTest, 0);
    189  });
    190 
    191  ok(!handlerExecuted, "Handlers are not called until the next microtask.");
    192 
    193  var xhr = new XMLHttpRequest();
    194  xhr.open("GET", "testXHR.txt", false);
    195  xhr.send(null);
    196 
    197  ok(!handlerExecuted, "Sync XHR should not trigger microtask execution.");
    198 }
    199 
    200 function promiseDoubleThen() {
    201  var steps = 0;
    202  var promise = new Promise(function(r1) {
    203    r1(42);
    204  });
    205 
    206  promise.then(function(what) {
    207    ok(true, "Then.resolve has been called");
    208    is(what, 42, "Value == 42");
    209    steps++;
    210  }, function() {
    211    ok(false, "Then.reject has been called");
    212  });
    213 
    214  promise.then(function(what) {
    215    ok(true, "Then.resolve has been called");
    216    is(steps, 1, "Then.resolve - step == 1");
    217    is(what, 42, "Value == 42");
    218    runTest();
    219  }, function() {
    220    ok(false, "Then.reject has been called");
    221  });
    222 }
    223 
    224 function promiseThenException() {
    225  var promise = new Promise(function(resolve) {
    226    resolve(42);
    227  });
    228 
    229  promise.then(function() {
    230    ok(true, "Then.resolve has been called");
    231    // eslint-disable-next-line no-throw-literal
    232    throw "booh";
    233  }).catch(function() {
    234    ok(true, "window.onerror has been called!");
    235    runTest();
    236  });
    237 }
    238 
    239 function promiseThenCatchThen() {
    240  var promise = new Promise(function(resolve) {
    241    resolve(42);
    242  });
    243 
    244  var promise2 = promise.then(function(what) {
    245    ok(true, "Then.resolve has been called");
    246    is(what, 42, "Value == 42");
    247    return what + 1;
    248  }, function() {
    249    ok(false, "Then.reject has been called");
    250  });
    251 
    252  isnot(promise, promise2, "These 2 promise objs are different");
    253 
    254  promise2.then(function(what) {
    255    ok(true, "Then.resolve has been called");
    256    is(what, 43, "Value == 43");
    257    return what + 1;
    258  }, function() {
    259    ok(false, "Then.reject has been called");
    260  }).catch(function() {
    261    ok(false, "Catch has been called");
    262  }).then(function(what) {
    263    ok(true, "Then.resolve has been called");
    264    is(what, 44, "Value == 44");
    265    runTest();
    266  }, function() {
    267    ok(false, "Then.reject has been called");
    268  });
    269 }
    270 
    271 function promiseThenNoArg() {
    272  var promise = new Promise(function(resolve) {
    273    resolve(42);
    274  });
    275 
    276  // eslint-disable-next-line promise/valid-params
    277  var clone = promise.then();
    278  isnot(promise, clone, "These 2 promise objs are different");
    279  promise.then(function(v) {
    280    clone.then(function(cv) {
    281      is(v, cv, "Both resolve to the same value");
    282      runTest();
    283    });
    284  });
    285 }
    286 
    287 function promiseThenUndefinedResolveFunction() {
    288  var promise = new Promise(function(resolve, reject) {
    289    reject(42);
    290  });
    291 
    292  try {
    293    promise.then(undefined, function(v) {
    294      is(v, 42, "Promise rejected with 42");
    295      runTest();
    296    });
    297  } catch (e) {
    298    ok(false, "then should not throw on undefined resolve function");
    299  }
    300 }
    301 
    302 function promiseThenNullResolveFunction() {
    303  var promise = new Promise(function(resolve, reject) {
    304    reject(42);
    305  });
    306 
    307  try {
    308    promise.then(null, function(v) {
    309      is(v, 42, "Promise rejected with 42");
    310      runTest();
    311    });
    312  } catch (e) {
    313    ok(false, "then should not throw on null resolve function");
    314  }
    315 }
    316 
    317 function promiseRejectThenCatchThen() {
    318  var promise = new Promise(function(resolve, reject) {
    319    reject(42);
    320  });
    321 
    322  var promise2 = promise.then(function() {
    323    ok(false, "Then.resolve has been called");
    324  }, function(what) {
    325    ok(true, "Then.reject has been called");
    326    is(what, 42, "Value == 42");
    327    return what + 1;
    328  });
    329 
    330  isnot(promise, promise2, "These 2 promise objs are different");
    331 
    332  promise2.then(function(what) {
    333    ok(true, "Then.resolve has been called");
    334    is(what, 43, "Value == 43");
    335    return what + 1;
    336  }).catch(function() {
    337    ok(false, "Catch has been called");
    338  }).then(function(what) {
    339    ok(true, "Then.resolve has been called");
    340    is(what, 44, "Value == 44");
    341    runTest();
    342  });
    343 }
    344 
    345 function promiseRejectThenCatchThen2() {
    346  var promise = new Promise(function(resolve, reject) {
    347    reject(42);
    348  });
    349 
    350  promise.then(function(what) {
    351    ok(true, "Then.resolve has been called");
    352    is(what, 42, "Value == 42");
    353    return what + 1;
    354  }).catch(function(what) {
    355    is(what, 42, "Value == 42");
    356    ok(true, "Catch has been called");
    357    return what + 1;
    358  }).then(function(what) {
    359    ok(true, "Then.resolve has been called");
    360    is(what, 43, "Value == 43");
    361    runTest();
    362  });
    363 }
    364 
    365 function promiseRejectThenCatchExceptionThen() {
    366  var promise = new Promise(function(resolve, reject) {
    367    reject(42);
    368  });
    369 
    370  promise.then(function() {
    371    ok(false, "Then.resolve has been called");
    372  }, function(what) {
    373    ok(true, "Then.reject has been called");
    374    is(what, 42, "Value == 42");
    375    // eslint-disable-next-line no-throw-literal
    376    throw (what + 1);
    377  }).catch(function(what) {
    378    ok(true, "Catch has been called");
    379    is(what, 43, "Value == 43");
    380    return what + 1;
    381  }).then(function(what) {
    382    ok(true, "Then.resolve has been called");
    383    is(what, 44, "Value == 44");
    384    runTest();
    385  });
    386 }
    387 
    388 function promiseThenCatchOrderingResolve() {
    389  var global = 0;
    390  var f = new Promise(function(r1) {
    391    r1(42);
    392  });
    393 
    394  f.then(function() {
    395    f.then(function() {
    396      global++;
    397    });
    398    f.catch(function() {
    399      global++;
    400    });
    401    f.then(function() {
    402      global++;
    403    });
    404    setTimeout(function() {
    405      is(global, 2, "Many steps... should return 2");
    406      runTest();
    407    }, 0);
    408  });
    409 }
    410 
    411 function promiseThenCatchOrderingReject() {
    412  var global = 0;
    413  var f = new Promise(function(r1, r2) {
    414    r2(42);
    415  });
    416 
    417  f.then(function() {}, function() {
    418    f.then(function() {
    419      global++;
    420    });
    421    f.catch(function() {
    422      global++;
    423    });
    424    f.then(function() {}, function() {
    425      global++;
    426    });
    427    setTimeout(function() {
    428      is(global, 2, "Many steps... should return 2");
    429      runTest();
    430    }, 0);
    431  });
    432 }
    433 
    434 function promiseCatchNoArg() {
    435  var promise = new Promise(function(resolve, reject) {
    436    reject(42);
    437  });
    438 
    439  // eslint-disable-next-line promise/valid-params
    440  var clone = promise.catch();
    441  isnot(promise, clone, "These 2 promise objs are different");
    442  promise.catch(function(v) {
    443    clone.catch(function(cv) {
    444      is(v, cv, "Both reject to the same value");
    445      runTest();
    446    });
    447  });
    448 }
    449 
    450 function promiseNestedPromise() {
    451  new Promise(function(resolve) {
    452    resolve(new Promise(function(res) {
    453      ok(true, "Nested promise is executed");
    454      res(42);
    455    }));
    456  }).then(function(value) {
    457    is(value, 42, "Nested promise is executed and then == 42");
    458    runTest();
    459  });
    460 }
    461 
    462 function promiseNestedNestedPromise() {
    463  new Promise(function(resolve) {
    464    resolve(new Promise(function(res) {
    465      ok(true, "Nested promise is executed");
    466      res(42);
    467    }).then(function(what) { return what + 1; }));
    468  }).then(function(value) {
    469    is(value, 43, "Nested promise is executed and then == 43");
    470    runTest();
    471  });
    472 }
    473 
    474 function promiseWrongNestedPromise() {
    475  new Promise(function(resolve, reject) {
    476    resolve(new Promise(function(r) {
    477      ok(true, "Nested promise is executed");
    478      r(42);
    479    }));
    480    reject(42);
    481  }).then(function(value) {
    482    is(value, 42, "Nested promise is executed and then == 42");
    483    runTest();
    484  }, function() {
    485     ok(false, "This is wrong");
    486  });
    487 }
    488 
    489 function promiseLoop() {
    490  new Promise(function(resolve) {
    491    resolve(new Promise(function(res) {
    492      ok(true, "Nested promise is executed");
    493      res(new Promise(function(resInner) {
    494        ok(true, "Nested nested promise is executed");
    495        resInner(42);
    496      }));
    497    }));
    498  }).then(function(value) {
    499    is(value, 42, "Nested nested promise is executed and then == 42");
    500    runTest();
    501  }, function() {
    502     ok(false, "This is wrong");
    503  });
    504 }
    505 
    506 function promiseStaticReject() {
    507  var promise = Promise.reject(42);
    508  promise.then(function() {
    509    ok(false, "This should not be called");
    510  }, function(what) {
    511    is(what, 42, "Value == 42");
    512    runTest();
    513  });
    514 }
    515 
    516 function promiseStaticResolve() {
    517  var promise = Promise.resolve(42);
    518  promise.then(function(what) {
    519    is(what, 42, "Value == 42");
    520    runTest();
    521  }, function() {
    522    ok(false, "This should not be called");
    523  });
    524 }
    525 
    526 function promiseResolveNestedPromise() {
    527  var promise = Promise.resolve(new Promise(function(r) {
    528    ok(true, "Nested promise is executed");
    529    r(42);
    530  }, function() {
    531    ok(false, "This should not be called");
    532  }));
    533  promise.then(function(what) {
    534    is(what, 42, "Value == 42");
    535    runTest();
    536  }, function() {
    537    ok(false, "This should not be called");
    538  });
    539 }
    540 
    541 function promiseSimpleThenableResolve() {
    542  var thenable = { then(resolve) { resolve(5); } };
    543  var promise = new Promise(function(resolve) {
    544    resolve(thenable);
    545  });
    546 
    547  promise.then(function(v) {
    548    ok(v === 5, "promiseSimpleThenableResolve");
    549    runTest();
    550  }, function() {
    551    ok(false, "promiseSimpleThenableResolve: Should not reject");
    552  });
    553 }
    554 
    555 function promiseSimpleThenableReject() {
    556  var thenable = { then(resolve, reject) { reject(5); } };
    557  var promise = new Promise(function(resolve) {
    558    resolve(thenable);
    559  });
    560 
    561  promise.then(function() {
    562    ok(false, "promiseSimpleThenableReject: Should not resolve");
    563    runTest();
    564  }, function(e) {
    565    ok(e === 5, "promiseSimpleThenableReject");
    566    runTest();
    567  });
    568 }
    569 
    570 function promiseThenableThrowsBeforeCallback() {
    571  var thenable = { then(resolve) {
    572    throw new TypeError("Hi there");
    573 
    574    // eslint-disable-next-line no-unreachable
    575    resolve(5);
    576  }};
    577 
    578  var promise = Promise.resolve(thenable);
    579  promise.then(function() {
    580    ok(false, "promiseThenableThrowsBeforeCallback: Should've rejected");
    581    runTest();
    582  }, function(e) {
    583    ok(e instanceof TypeError, "promiseThenableThrowsBeforeCallback");
    584    runTest();
    585  });
    586 }
    587 
    588 function promiseThenableThrowsAfterCallback() {
    589  var thenable = { then(resolve) {
    590    resolve(5);
    591    throw new TypeError("Hi there");
    592  }};
    593 
    594  var promise = Promise.resolve(thenable);
    595  promise.then(function(v) {
    596    ok(v === 5, "promiseThenableThrowsAfterCallback");
    597    runTest();
    598  }, function() {
    599    ok(false, "promiseThenableThrowsAfterCallback: Should've resolved");
    600    runTest();
    601  });
    602 }
    603 
    604 function promiseThenableRejectThenResolve() {
    605  var thenable = { then(resolve, reject) {
    606    reject(new TypeError("Hi there"));
    607    resolve(5);
    608  }};
    609 
    610  var promise = Promise.resolve(thenable);
    611  promise.then(function() {
    612    ok(false, "promiseThenableRejectThenResolve should have rejected");
    613    runTest();
    614  }, function(e) {
    615    ok(e instanceof TypeError, "promiseThenableRejectThenResolve");
    616    runTest();
    617  });
    618 }
    619 
    620 function promiseWithThenReplaced() {
    621  // Ensure that we call the 'then' on the promise and not the internal then.
    622  var promise = new Promise(function(resolve) {
    623    resolve(5);
    624  });
    625 
    626  // Rogue `then` always rejects.
    627  promise.then = function(onFulfill, onReject) {
    628    onReject(new TypeError("Foo"));
    629  };
    630 
    631  var promise2 = Promise.resolve(promise);
    632  promise2.then(function() {
    633    ok(false, "promiseWithThenReplaced: Should've rejected");
    634    runTest();
    635  }, function(e) {
    636    ok(e instanceof TypeError, "promiseWithThenReplaced");
    637    runTest();
    638  });
    639 }
    640 
    641 function promiseStrictHandlers() {
    642  var promise = Promise.resolve(5);
    643  promise.then(function() {
    644    "use strict";
    645    ok(this === undefined, "Strict mode callback should have this === undefined.");
    646    runTest();
    647  });
    648 }
    649 
    650 function promiseStrictExecutorThisArg() {
    651  new Promise(function() {
    652    "use strict";
    653    ok(this === undefined, "thisArg should be undefined.");
    654    runTest();
    655  });
    656 }
    657 
    658 function promiseResolveArray() {
    659  var p = Promise.resolve([1, 2, 3]);
    660  ok(p instanceof Promise, "Should return a Promise.");
    661  p.then(function(v) {
    662    ok(Array.isArray(v), "Resolved value should be an Array");
    663    is(v.length, 3, "Length should match");
    664    is(v[0], 1, "Resolved value should match original");
    665    is(v[1], 2, "Resolved value should match original");
    666    is(v[2], 3, "Resolved value should match original");
    667    runTest();
    668  });
    669 }
    670 
    671 function promiseResolveThenable() {
    672  var p = Promise.resolve({ then(onFulfill) { onFulfill(2); } });
    673  ok(p instanceof Promise, "Should cast to a Promise.");
    674  p.then(function(v) {
    675    is(v, 2, "Should resolve to 2.");
    676    runTest();
    677  }, function() {
    678    ok(false, "promiseResolveThenable should've resolved");
    679    runTest();
    680  });
    681 }
    682 
    683 function promiseResolvePromise() {
    684  var original = Promise.resolve(true);
    685  var cast = Promise.resolve(original);
    686 
    687  ok(cast instanceof Promise, "Should cast to a Promise.");
    688  is(cast, original, "Should return original Promise.");
    689  cast.then(function(v) {
    690    is(v, true, "Should resolve to true.");
    691    runTest();
    692  });
    693 }
    694 
    695 // Bug 1009569.
    696 // Ensure that thenables are run on a clean stack asynchronously.
    697 // Test case adopted from
    698 // https://gist.github.com/getify/d64bb01751b50ed6b281#file-bug1-js.
    699 function promiseResolveThenableCleanStack() {
    700  function immed(s) { x++; s(); }
    701  function incX() { x++; }
    702 
    703  var x = 0;
    704  var thenable = { then: immed };
    705  var results = [];
    706 
    707  var p = Promise.resolve(thenable).then(incX);
    708  results.push(x);
    709 
    710  // check what happens after all "next cycle" steps
    711  // have had a chance to complete
    712  setTimeout(function() {
    713    // Result should be [0, 2] since `thenable` will be called async.
    714    is(results[0], 0, "Expected thenable to be called asynchronously");
    715    // See Bug 1023547 comment 13 for why this check has to be gated on p.
    716    p.then(function() {
    717      results.push(x);
    718      is(results[1], 2, "Expected thenable to be called asynchronously");
    719      runTest();
    720    });
    721  }, 1000);
    722 }
    723 
    724 // Bug 1008467 - Promise fails with "too much recursion".
    725 // The bug was that the callbacks passed to a thenable would resolve the
    726 // promise synchronously when the fulfill handler returned a non-thenable.
    727 //
    728 // For example:
    729 // var p = new Promise(function(resolve) {
    730 //   resolve(5);
    731 // });
    732 // var m = Promise.resolve(p);
    733 //
    734 // At this point `m` is a Promise that is resolved with a thenable `p`, so it
    735 // calls `p.then()` with two callbacks, both of which would synchronously resolve
    736 // `m` when `p` invoked them (on account of itself being resolved, possibly
    737 // synchronously. A chain of these 'Promise resolved by a Promise' would lead to
    738 // stack overflow.
    739 function promiseTestAsyncThenableResolution() {
    740  var k = 3000;
    741  Promise.resolve().then(function next() {
    742    k--;
    743    if (k > 0) return Promise.resolve().then(next);
    744    return undefined;
    745  }).then(function() {
    746    ok(true, "Resolution of a chain of thenables should not be synchronous.");
    747    runTest();
    748  });
    749 }
    750 
    751 // Bug 1062323
    752 function promiseWrapperAsyncResolution() {
    753  var p = new Promise(function(resolve) {
    754    resolve();
    755  });
    756 
    757  var results = [];
    758  var q = p.then(function() {
    759    results.push("1-1");
    760  }).then(function() {
    761    results.push("1-2");
    762  }).then(function() {
    763    results.push("1-3");
    764  });
    765 
    766  var r = p.then(function() {
    767    results.push("2-1");
    768  }).then(function() {
    769    results.push("2-2");
    770  }).then(function() {
    771    results.push("2-3");
    772  });
    773 
    774  Promise.all([q, r]).then(function() {
    775    var match = results[0] == "1-1" &&
    776                results[1] == "2-1" &&
    777                results[2] == "1-2" &&
    778                results[3] == "2-2" &&
    779                results[4] == "1-3" &&
    780                results[5] == "2-3";
    781                info(results);
    782    ok(match, "Chained promises should resolve asynchronously.");
    783    runTest();
    784  }, function() {
    785    ok(false, "promiseWrapperAsyncResolution: One of the promises failed.");
    786    runTest();
    787  });
    788 }
    789 
    790 var tests = [ promiseResolve, promiseReject,
    791              promiseException, promiseGC,
    792              promiseAsync_TimeoutResolveThen,
    793              promiseAsync_ResolveTimeoutThen,
    794              promiseAsync_ResolveThenTimeout,
    795              promiseAsync_SyncXHR,
    796              promiseDoubleThen, promiseThenException,
    797              promiseThenCatchThen, promiseRejectThenCatchThen,
    798              promiseRejectThenCatchThen2,
    799              promiseRejectThenCatchExceptionThen,
    800              promiseThenCatchOrderingResolve,
    801              promiseThenCatchOrderingReject,
    802              promiseNestedPromise, promiseNestedNestedPromise,
    803              promiseWrongNestedPromise, promiseLoop,
    804              promiseStaticReject, promiseStaticResolve,
    805              promiseResolveNestedPromise,
    806              promiseResolveNoArg,
    807              promiseRejectNoArg,
    808              promiseThenNoArg,
    809              promiseThenUndefinedResolveFunction,
    810              promiseThenNullResolveFunction,
    811              promiseCatchNoArg,
    812              promiseRejectNoHandler,
    813              promiseSimpleThenableResolve,
    814              promiseSimpleThenableReject,
    815              promiseThenableThrowsBeforeCallback,
    816              promiseThenableThrowsAfterCallback,
    817              promiseThenableRejectThenResolve,
    818              promiseWithThenReplaced,
    819              promiseStrictHandlers,
    820              promiseStrictExecutorThisArg,
    821              promiseResolveArray,
    822              promiseResolveThenable,
    823              promiseResolvePromise,
    824              promiseResolveThenableCleanStack,
    825              promiseTestAsyncThenableResolution,
    826              promiseWrapperAsyncResolution,
    827            ];
    828 
    829 function runTest() {
    830  if (!tests.length) {
    831    SimpleTest.finish();
    832    return;
    833  }
    834 
    835  var test = tests.shift();
    836  test();
    837 }
    838 
    839 SimpleTest.waitForExplicitFinish();
    840 SimpleTest.requestFlakyTimeout("untriaged");
    841 runTest();
    842 // -->
    843 </script>
    844 </pre>
    845 </body>
    846 </html>