promise_worker.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857
  1. function ok(a, msg) {
  2. dump("OK: " + !!a + " => " + a + " " + msg + "\n");
  3. postMessage({type: 'status', status: !!a, msg: a + ": " + msg });
  4. }
  5. function todo(a, msg) {
  6. dump("TODO: " + !a + " => " + a + " " + msg + "\n");
  7. postMessage({type: 'status', status: !a, msg: a + ": " + msg });
  8. }
  9. function is(a, b, msg) {
  10. dump("IS: " + (a===b) + " => " + a + " | " + b + " " + msg + "\n");
  11. postMessage({type: 'status', status: a === b, msg: a + " === " + b + ": " + msg });
  12. }
  13. function isnot(a, b, msg) {
  14. dump("ISNOT: " + (a!==b) + " => " + a + " | " + b + " " + msg + "\n");
  15. postMessage({type: 'status', status: a !== b, msg: a + " !== " + b + ": " + msg });
  16. }
  17. function promiseResolve() {
  18. 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");
  22. resolve(42);
  23. }).then(function(what) {
  24. ok(true, "Then - resolveCb has been called");
  25. is(what, 42, "ResolveCb received 42");
  26. runTest();
  27. }, function() {
  28. ok(false, "Then - rejectCb has been called");
  29. runTest();
  30. });
  31. }
  32. function promiseResolveNoArg() {
  33. var promise = new Promise(function(resolve, reject) {
  34. ok(resolve, "Promise.resolve exists");
  35. ok(reject, "Promise.reject exists");
  36. resolve();
  37. }).then(function(what) {
  38. ok(true, "Then - resolveCb has been called");
  39. is(what, undefined, "ResolveCb received undefined");
  40. runTest();
  41. }, function() {
  42. ok(false, "Then - rejectCb has been called");
  43. runTest();
  44. });
  45. }
  46. function promiseRejectNoHandler() {
  47. // This test only checks that the code that reports unhandled errors in the
  48. // Promises implementation does not crash or leak.
  49. var promise = new Promise(function(res, rej) {
  50. noSuchMethod();
  51. });
  52. runTest();
  53. }
  54. function promiseReject() {
  55. var promise = new Promise(function(resolve, reject) {
  56. reject(42);
  57. }).then(function(what) {
  58. ok(false, "Then - resolveCb has been called");
  59. runTest();
  60. }, function(what) {
  61. ok(true, "Then - rejectCb has been called");
  62. is(what, 42, "RejectCb received 42");
  63. runTest();
  64. });
  65. }
  66. function promiseRejectNoArg() {
  67. var promise = new Promise(function(resolve, reject) {
  68. reject();
  69. }).then(function(what) {
  70. ok(false, "Then - resolveCb has been called");
  71. runTest();
  72. }, function(what) {
  73. ok(true, "Then - rejectCb has been called");
  74. is(what, undefined, "RejectCb received undefined");
  75. runTest();
  76. });
  77. }
  78. function promiseException() {
  79. var promise = new Promise(function(resolve, reject) {
  80. throw 42;
  81. }).then(function(what) {
  82. ok(false, "Then - resolveCb has been called");
  83. runTest();
  84. }, function(what) {
  85. ok(true, "Then - rejectCb has been called");
  86. is(what, 42, "RejectCb received 42");
  87. runTest();
  88. });
  89. }
  90. function promiseAsync_TimeoutResolveThen() {
  91. var handlerExecuted = false;
  92. setTimeout(function() {
  93. ok(handlerExecuted, "Handler should have been called before the timeout.");
  94. // Allow other assertions to run so the test could fail before the next one.
  95. setTimeout(runTest, 0);
  96. }, 0);
  97. Promise.resolve().then(function() {
  98. handlerExecuted = true;
  99. });
  100. ok(!handlerExecuted, "Handlers are not called before 'then' returns.");
  101. }
  102. function promiseAsync_ResolveTimeoutThen() {
  103. var handlerExecuted = false;
  104. var promise = Promise.resolve();
  105. setTimeout(function() {
  106. ok(handlerExecuted, "Handler should have been called before the timeout.");
  107. // Allow other assertions to run so the test could fail before the next one.
  108. setTimeout(runTest, 0);
  109. }, 0);
  110. promise.then(function() {
  111. handlerExecuted = true;
  112. });
  113. ok(!handlerExecuted, "Handlers are not called before 'then' returns.");
  114. }
  115. function promiseAsync_ResolveThenTimeout() {
  116. var handlerExecuted = false;
  117. Promise.resolve().then(function() {
  118. handlerExecuted = true;
  119. });
  120. setTimeout(function() {
  121. ok(handlerExecuted, "Handler should have been called before the timeout.");
  122. // Allow other assertions to run so the test could fail before the next one.
  123. setTimeout(runTest, 0);
  124. }, 0);
  125. ok(!handlerExecuted, "Handlers are not called before 'then' returns.");
  126. }
  127. function promiseAsync_SyncXHRAndImportScripts()
  128. {
  129. var handlerExecuted = false;
  130. Promise.resolve().then(function() {
  131. handlerExecuted = true;
  132. // Allow other assertions to run so the test could fail before the next one.
  133. setTimeout(runTest, 0);
  134. });
  135. ok(!handlerExecuted, "Handlers are not called until the next microtask.");
  136. var xhr = new XMLHttpRequest();
  137. xhr.open("GET", "testXHR.txt", false);
  138. xhr.send(null);
  139. ok(!handlerExecuted, "Sync XHR should not trigger microtask execution.");
  140. importScripts("../../../dom/xhr/tests/relativeLoad_import.js");
  141. ok(!handlerExecuted, "importScripts should not trigger microtask execution.");
  142. }
  143. function promiseDoubleThen() {
  144. var steps = 0;
  145. var promise = new Promise(function(r1, r2) {
  146. r1(42);
  147. });
  148. promise.then(function(what) {
  149. ok(true, "Then.resolve has been called");
  150. is(what, 42, "Value == 42");
  151. steps++;
  152. }, function(what) {
  153. ok(false, "Then.reject has been called");
  154. });
  155. promise.then(function(what) {
  156. ok(true, "Then.resolve has been called");
  157. is(steps, 1, "Then.resolve - step == 1");
  158. is(what, 42, "Value == 42");
  159. runTest();
  160. }, function(what) {
  161. ok(false, "Then.reject has been called");
  162. });
  163. }
  164. function promiseThenException() {
  165. var promise = new Promise(function(resolve, reject) {
  166. resolve(42);
  167. });
  168. promise.then(function(what) {
  169. ok(true, "Then.resolve has been called");
  170. throw "booh";
  171. }).catch(function(e) {
  172. ok(true, "Catch has been called!");
  173. runTest();
  174. });
  175. }
  176. function promiseThenCatchThen() {
  177. var promise = new Promise(function(resolve, reject) {
  178. resolve(42);
  179. });
  180. var promise2 = promise.then(function(what) {
  181. ok(true, "Then.resolve has been called");
  182. is(what, 42, "Value == 42");
  183. return what + 1;
  184. }, function(what) {
  185. ok(false, "Then.reject has been called");
  186. });
  187. isnot(promise, promise2, "These 2 promise objs are different");
  188. promise2.then(function(what) {
  189. ok(true, "Then.resolve has been called");
  190. is(what, 43, "Value == 43");
  191. return what + 1;
  192. }, function(what) {
  193. ok(false, "Then.reject has been called");
  194. }).catch(function() {
  195. ok(false, "Catch has been called");
  196. }).then(function(what) {
  197. ok(true, "Then.resolve has been called");
  198. is(what, 44, "Value == 44");
  199. runTest();
  200. }, function(what) {
  201. ok(false, "Then.reject has been called");
  202. });
  203. }
  204. function promiseRejectThenCatchThen() {
  205. var promise = new Promise(function(resolve, reject) {
  206. reject(42);
  207. });
  208. var promise2 = promise.then(function(what) {
  209. ok(false, "Then.resolve has been called");
  210. }, function(what) {
  211. ok(true, "Then.reject has been called");
  212. is(what, 42, "Value == 42");
  213. return what + 1;
  214. });
  215. isnot(promise, promise2, "These 2 promise objs are different");
  216. promise2.then(function(what) {
  217. ok(true, "Then.resolve has been called");
  218. is(what, 43, "Value == 43");
  219. return what+1;
  220. }).catch(function(what) {
  221. ok(false, "Catch has been called");
  222. }).then(function(what) {
  223. ok(true, "Then.resolve has been called");
  224. is(what, 44, "Value == 44");
  225. runTest();
  226. });
  227. }
  228. function promiseRejectThenCatchThen2() {
  229. var promise = new Promise(function(resolve, reject) {
  230. reject(42);
  231. });
  232. promise.then(function(what) {
  233. ok(true, "Then.resolve has been called");
  234. is(what, 42, "Value == 42");
  235. return what+1;
  236. }).catch(function(what) {
  237. is(what, 42, "Value == 42");
  238. ok(true, "Catch has been called");
  239. return what+1;
  240. }).then(function(what) {
  241. ok(true, "Then.resolve has been called");
  242. is(what, 43, "Value == 43");
  243. runTest();
  244. });
  245. }
  246. function promiseRejectThenCatchExceptionThen() {
  247. var promise = new Promise(function(resolve, reject) {
  248. reject(42);
  249. });
  250. promise.then(function(what) {
  251. ok(false, "Then.resolve has been called");
  252. }, function(what) {
  253. ok(true, "Then.reject has been called");
  254. is(what, 42, "Value == 42");
  255. throw(what + 1);
  256. }).catch(function(what) {
  257. ok(true, "Catch has been called");
  258. is(what, 43, "Value == 43");
  259. return what + 1;
  260. }).then(function(what) {
  261. ok(true, "Then.resolve has been called");
  262. is(what, 44, "Value == 44");
  263. runTest();
  264. });
  265. }
  266. function promiseThenCatchOrderingResolve() {
  267. var global = 0;
  268. var f = new Promise(function(r1, r2) {
  269. r1(42);
  270. });
  271. f.then(function() {
  272. f.then(function() {
  273. global++;
  274. });
  275. f.catch(function() {
  276. global++;
  277. });
  278. f.then(function() {
  279. global++;
  280. });
  281. setTimeout(function() {
  282. is(global, 2, "Many steps... should return 2");
  283. runTest();
  284. }, 0);
  285. });
  286. }
  287. function promiseThenCatchOrderingReject() {
  288. var global = 0;
  289. var f = new Promise(function(r1, r2) {
  290. r2(42);
  291. })
  292. f.then(function() {}, function() {
  293. f.then(function() {
  294. global++;
  295. });
  296. f.catch(function() {
  297. global++;
  298. });
  299. f.then(function() {}, function() {
  300. global++;
  301. });
  302. setTimeout(function() {
  303. is(global, 2, "Many steps... should return 2");
  304. runTest();
  305. }, 0);
  306. });
  307. }
  308. function promiseThenNoArg() {
  309. var promise = new Promise(function(resolve, reject) {
  310. resolve(42);
  311. });
  312. var clone = promise.then();
  313. isnot(promise, clone, "These 2 promise objs are different");
  314. promise.then(function(v) {
  315. clone.then(function(cv) {
  316. is(v, cv, "Both resolve to the same value");
  317. runTest();
  318. });
  319. });
  320. }
  321. function promiseThenUndefinedResolveFunction() {
  322. var promise = new Promise(function(resolve, reject) {
  323. reject(42);
  324. });
  325. try {
  326. promise.then(undefined, function(v) {
  327. is(v, 42, "Promise rejected with 42");
  328. runTest();
  329. });
  330. } catch (e) {
  331. ok(false, "then should not throw on undefined resolve function");
  332. }
  333. }
  334. function promiseThenNullResolveFunction() {
  335. var promise = new Promise(function(resolve, reject) {
  336. reject(42);
  337. });
  338. try {
  339. promise.then(null, function(v) {
  340. is(v, 42, "Promise rejected with 42");
  341. runTest();
  342. });
  343. } catch (e) {
  344. ok(false, "then should not throw on null resolve function");
  345. }
  346. }
  347. function promiseCatchNoArg() {
  348. var promise = new Promise(function(resolve, reject) {
  349. reject(42);
  350. });
  351. var clone = promise.catch();
  352. isnot(promise, clone, "These 2 promise objs are different");
  353. promise.catch(function(v) {
  354. clone.catch(function(cv) {
  355. is(v, cv, "Both reject to the same value");
  356. runTest();
  357. });
  358. });
  359. }
  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. }
  371. function promiseNestedNestedPromise() {
  372. new Promise(function(resolve, reject) {
  373. resolve(new Promise(function(resolve, reject) {
  374. ok(true, "Nested promise is executed");
  375. resolve(42);
  376. }).then(function(what) { return what+1; }));
  377. }).then(function(value) {
  378. is(value, 43, "Nested promise is executed and then == 43");
  379. runTest();
  380. });
  381. }
  382. function promiseWrongNestedPromise() {
  383. new Promise(function(resolve, reject) {
  384. resolve(new Promise(function(r, r2) {
  385. ok(true, "Nested promise is executed");
  386. r(42);
  387. }));
  388. reject(42);
  389. }).then(function(value) {
  390. is(value, 42, "Nested promise is executed and then == 42");
  391. runTest();
  392. }, function(value) {
  393. ok(false, "This is wrong");
  394. });
  395. }
  396. function promiseLoop() {
  397. new Promise(function(resolve, reject) {
  398. resolve(new Promise(function(r1, r2) {
  399. ok(true, "Nested promise is executed");
  400. r1(new Promise(function(r1, r2) {
  401. ok(true, "Nested nested promise is executed");
  402. r1(42);
  403. }));
  404. }));
  405. }).then(function(value) {
  406. is(value, 42, "Nested nested promise is executed and then == 42");
  407. runTest();
  408. }, function(value) {
  409. ok(false, "This is wrong");
  410. });
  411. }
  412. function promiseStaticReject() {
  413. var promise = Promise.reject(42).then(function(what) {
  414. ok(false, "This should not be called");
  415. }, function(what) {
  416. is(what, 42, "Value == 42");
  417. runTest();
  418. });
  419. }
  420. function promiseStaticResolve() {
  421. var promise = Promise.resolve(42).then(function(what) {
  422. is(what, 42, "Value == 42");
  423. runTest();
  424. }, function() {
  425. ok(false, "This should not be called");
  426. });
  427. }
  428. function promiseResolveNestedPromise() {
  429. var promise = Promise.resolve(new Promise(function(r, r2) {
  430. ok(true, "Nested promise is executed");
  431. r(42);
  432. }, function() {
  433. ok(false, "This should not be called");
  434. })).then(function(what) {
  435. is(what, 42, "Value == 42");
  436. runTest();
  437. }, function() {
  438. ok(false, "This should not be called");
  439. });
  440. }
  441. function promiseRejectNoHandler() {
  442. // This test only checks that the code that reports unhandled errors in the
  443. // Promises implementation does not crash or leak.
  444. var promise = new Promise(function(res, rej) {
  445. noSuchMethod();
  446. });
  447. runTest();
  448. }
  449. function promiseUtilitiesDefined() {
  450. ok(Promise.all, "Promise.all must be defined when Promise is enabled.");
  451. ok(Promise.race, "Promise.race must be defined when Promise is enabled.");
  452. runTest();
  453. }
  454. function promiseAllArray() {
  455. var p = Promise.all([1, new Date(), Promise.resolve("firefox")]);
  456. ok(p instanceof Promise, "Return value of Promise.all should be a Promise.");
  457. p.then(function(values) {
  458. ok(Array.isArray(values), "Resolved value should be an array.");
  459. is(values.length, 3, "Resolved array length should match iterable's length.");
  460. is(values[0], 1, "Array values should match.");
  461. ok(values[1] instanceof Date, "Array values should match.");
  462. is(values[2], "firefox", "Array values should match.");
  463. runTest();
  464. }, function() {
  465. ok(false, "Promise.all shouldn't fail when iterable has no rejected Promises.");
  466. runTest();
  467. });
  468. }
  469. function promiseAllWaitsForAllPromises() {
  470. var arr = [
  471. new Promise(function(resolve) {
  472. setTimeout(resolve.bind(undefined, 1), 50);
  473. }),
  474. new Promise(function(resolve) {
  475. setTimeout(resolve.bind(undefined, 2), 10);
  476. }),
  477. new Promise(function(resolve) {
  478. setTimeout(resolve.bind(undefined, new Promise(function(resolve2) {
  479. resolve2(3);
  480. })), 10);
  481. }),
  482. new Promise(function(resolve) {
  483. setTimeout(resolve.bind(undefined, 4), 20);
  484. })
  485. ];
  486. var p = Promise.all(arr);
  487. p.then(function(values) {
  488. ok(Array.isArray(values), "Resolved value should be an array.");
  489. is(values.length, 4, "Resolved array length should match iterable's length.");
  490. is(values[0], 1, "Array values should match.");
  491. is(values[1], 2, "Array values should match.");
  492. is(values[2], 3, "Array values should match.");
  493. is(values[3], 4, "Array values should match.");
  494. runTest();
  495. }, function() {
  496. ok(false, "Promise.all shouldn't fail when iterable has no rejected Promises.");
  497. runTest();
  498. });
  499. }
  500. function promiseAllRejectFails() {
  501. var arr = [
  502. new Promise(function(resolve) {
  503. setTimeout(resolve.bind(undefined, 1), 50);
  504. }),
  505. new Promise(function(resolve, reject) {
  506. setTimeout(reject.bind(undefined, 2), 10);
  507. }),
  508. new Promise(function(resolve) {
  509. setTimeout(resolve.bind(undefined, 3), 10);
  510. }),
  511. new Promise(function(resolve) {
  512. setTimeout(resolve.bind(undefined, 4), 20);
  513. })
  514. ];
  515. var p = Promise.all(arr);
  516. p.then(function(values) {
  517. ok(false, "Promise.all shouldn't resolve when iterable has rejected Promises.");
  518. runTest();
  519. }, function(e) {
  520. ok(true, "Promise.all should reject when iterable has rejected Promises.");
  521. is(e, 2, "Rejection value should match.");
  522. runTest();
  523. });
  524. }
  525. function promiseRaceEmpty() {
  526. var p = Promise.race([]);
  527. ok(p instanceof Promise, "Should return a Promise.");
  528. // An empty race never resolves!
  529. runTest();
  530. }
  531. function promiseRaceValuesArray() {
  532. var p = Promise.race([true, new Date(), 3]);
  533. ok(p instanceof Promise, "Should return a Promise.");
  534. p.then(function(winner) {
  535. is(winner, true, "First value should win.");
  536. runTest();
  537. }, function(err) {
  538. ok(false, "Should not fail " + err + ".");
  539. runTest();
  540. });
  541. }
  542. function promiseRacePromiseArray() {
  543. var arr = [
  544. new Promise(function(resolve) {
  545. resolve("first");
  546. }),
  547. Promise.resolve("second"),
  548. new Promise(function() {}),
  549. new Promise(function(resolve) {
  550. setTimeout(function() {
  551. setTimeout(function() {
  552. resolve("fourth");
  553. }, 0);
  554. }, 0);
  555. }),
  556. ];
  557. var p = Promise.race(arr);
  558. p.then(function(winner) {
  559. is(winner, "first", "First queued resolution should win the race.");
  560. runTest();
  561. });
  562. }
  563. function promiseRaceReject() {
  564. var p = Promise.race([
  565. Promise.reject(new Error("Fail bad!")),
  566. new Promise(function(resolve) {
  567. setTimeout(resolve, 0);
  568. })
  569. ]);
  570. p.then(function() {
  571. ok(false, "Should not resolve when winning Promise rejected.");
  572. runTest();
  573. }, function(e) {
  574. ok(true, "Should be rejected");
  575. ok(e instanceof Error, "Should reject with Error.");
  576. ok(e.message == "Fail bad!", "Message should match.");
  577. runTest();
  578. });
  579. }
  580. function promiseRaceThrow() {
  581. var p = Promise.race([
  582. new Promise(function(resolve) {
  583. nonExistent();
  584. }),
  585. new Promise(function(resolve) {
  586. setTimeout(resolve, 0);
  587. })
  588. ]);
  589. p.then(function() {
  590. ok(false, "Should not resolve when winning Promise had an error.");
  591. runTest();
  592. }, function(e) {
  593. ok(true, "Should be rejected");
  594. ok(e instanceof ReferenceError, "Should reject with ReferenceError for function nonExistent().");
  595. runTest();
  596. });
  597. }
  598. function promiseResolveArray() {
  599. var p = Promise.resolve([1,2,3]);
  600. ok(p instanceof Promise, "Should return a Promise.");
  601. p.then(function(v) {
  602. ok(Array.isArray(v), "Resolved value should be an Array");
  603. is(v.length, 3, "Length should match");
  604. is(v[0], 1, "Resolved value should match original");
  605. is(v[1], 2, "Resolved value should match original");
  606. is(v[2], 3, "Resolved value should match original");
  607. runTest();
  608. });
  609. }
  610. function promiseResolveThenable() {
  611. var p = Promise.resolve({ then: function(onFulfill, onReject) { onFulfill(2); } });
  612. ok(p instanceof Promise, "Should cast to a Promise.");
  613. p.then(function(v) {
  614. is(v, 2, "Should resolve to 2.");
  615. runTest();
  616. }, function(e) {
  617. ok(false, "promiseResolveThenable should've resolved");
  618. runTest();
  619. });
  620. }
  621. function promiseResolvePromise() {
  622. var original = Promise.resolve(true);
  623. var cast = Promise.resolve(original);
  624. ok(cast instanceof Promise, "Should cast to a Promise.");
  625. is(cast, original, "Should return original Promise.");
  626. cast.then(function(v) {
  627. is(v, true, "Should resolve to true.");
  628. runTest();
  629. });
  630. }
  631. // Bug 1009569.
  632. // Ensure that thenables are run on a clean stack asynchronously.
  633. // Test case adopted from
  634. // https://gist.github.com/getify/d64bb01751b50ed6b281#file-bug1-js.
  635. function promiseResolveThenableCleanStack() {
  636. function immed(s) { x++; s(); }
  637. function incX(){ x++; }
  638. var x = 0;
  639. var thenable = { then: immed };
  640. var results = [];
  641. var p = Promise.resolve(thenable).then(incX);
  642. results.push(x);
  643. // check what happens after all "next cycle" steps
  644. // have had a chance to complete
  645. setTimeout(function(){
  646. // Result should be [0, 2] since `thenable` will be called async.
  647. is(results[0], 0, "Expected thenable to be called asynchronously");
  648. // See Bug 1023547 comment 13 for why this check has to be gated on p.
  649. p.then(function() {
  650. results.push(x);
  651. is(results[1], 2, "Expected thenable to be called asynchronously");
  652. runTest();
  653. });
  654. },1000);
  655. }
  656. // Bug 1062323
  657. function promiseWrapperAsyncResolution()
  658. {
  659. var p = new Promise(function(resolve, reject){
  660. resolve();
  661. });
  662. var results = [];
  663. var q = p.then(function () {
  664. results.push("1-1");
  665. }).then(function () {
  666. results.push("1-2");
  667. }).then(function () {
  668. results.push("1-3");
  669. });
  670. var r = p.then(function () {
  671. results.push("2-1");
  672. }).then(function () {
  673. results.push("2-2");
  674. }).then(function () {
  675. results.push("2-3");
  676. });
  677. Promise.all([q, r]).then(function() {
  678. var match = results[0] == "1-1" &&
  679. results[1] == "2-1" &&
  680. results[2] == "1-2" &&
  681. results[3] == "2-2" &&
  682. results[4] == "1-3" &&
  683. results[5] == "2-3";
  684. ok(match, "Chained promises should resolve asynchronously.");
  685. runTest();
  686. }, function() {
  687. ok(false, "promiseWrapperAsyncResolution: One of the promises failed.");
  688. runTest();
  689. });
  690. }
  691. var tests = [
  692. promiseResolve,
  693. promiseReject,
  694. promiseException,
  695. promiseAsync_TimeoutResolveThen,
  696. promiseAsync_ResolveTimeoutThen,
  697. promiseAsync_ResolveThenTimeout,
  698. promiseAsync_SyncXHRAndImportScripts,
  699. promiseDoubleThen,
  700. promiseThenException,
  701. promiseThenCatchThen,
  702. promiseRejectThenCatchThen,
  703. promiseRejectThenCatchThen2,
  704. promiseRejectThenCatchExceptionThen,
  705. promiseThenCatchOrderingResolve,
  706. promiseThenCatchOrderingReject,
  707. promiseNestedPromise,
  708. promiseNestedNestedPromise,
  709. promiseWrongNestedPromise,
  710. promiseLoop,
  711. promiseStaticReject,
  712. promiseStaticResolve,
  713. promiseResolveNestedPromise,
  714. promiseResolveNoArg,
  715. promiseRejectNoArg,
  716. promiseThenNoArg,
  717. promiseThenUndefinedResolveFunction,
  718. promiseThenNullResolveFunction,
  719. promiseCatchNoArg,
  720. promiseRejectNoHandler,
  721. promiseUtilitiesDefined,
  722. promiseAllArray,
  723. promiseAllWaitsForAllPromises,
  724. promiseAllRejectFails,
  725. promiseRaceEmpty,
  726. promiseRaceValuesArray,
  727. promiseRacePromiseArray,
  728. promiseRaceReject,
  729. promiseRaceThrow,
  730. promiseResolveArray,
  731. promiseResolveThenable,
  732. promiseResolvePromise,
  733. promiseResolveThenableCleanStack,
  734. promiseWrapperAsyncResolution,
  735. ];
  736. function runTest() {
  737. if (!tests.length) {
  738. postMessage({ type: 'finish' });
  739. return;
  740. }
  741. var test = tests.shift();
  742. test();
  743. }
  744. onmessage = function() {
  745. runTest();
  746. }