3 /* eslint-disable mozilla/no-comparison-or-assignment-inside-ok */
6 dump("OK: " + !!a + " => " + a + " " + msg + "\n");
7 postMessage({ type: "status", status: !!a, msg: a + ": " + msg });
10 function is(a, b, msg) {
11 dump("IS: " + (a === b) + " => " + a + " | " + b + " " + msg + "\n");
15 msg: a + " === " + b + ": " + msg,
19 function isnot(a, b, msg) {
20 dump("ISNOT: " + (a !== b) + " => " + a + " | " + b + " " + msg + "\n");
24 msg: a + " !== " + b + ": " + msg,
28 function promiseResolve() {
29 ok(Promise, "Promise object should exist");
31 var promise = new Promise(function (resolve, reject) {
32 ok(resolve, "Promise.resolve exists");
33 ok(reject, "Promise.reject exists");
38 ok(true, "Then - resolveCb has been called");
39 is(what, 42, "ResolveCb received 42");
43 ok(false, "Then - rejectCb has been called");
49 function promiseResolveNoArg() {
50 var promise = new Promise(function (resolve, reject) {
51 ok(resolve, "Promise.resolve exists");
52 ok(reject, "Promise.reject exists");
57 ok(true, "Then - resolveCb has been called");
58 is(what, undefined, "ResolveCb received undefined");
62 ok(false, "Then - rejectCb has been called");
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) {
77 function promiseReject() {
78 var promise = new Promise(function (resolve, reject) {
82 ok(false, "Then - resolveCb has been called");
86 ok(true, "Then - rejectCb has been called");
87 is(what, 42, "RejectCb received 42");
93 function promiseRejectNoArg() {
94 var promise = new Promise(function (resolve, reject) {
98 ok(false, "Then - resolveCb has been called");
102 ok(true, "Then - rejectCb has been called");
103 is(what, undefined, "RejectCb received undefined");
109 function promiseException() {
110 var promise = new Promise(function (resolve, reject) {
114 ok(false, "Then - resolveCb has been called");
118 ok(true, "Then - rejectCb has been called");
119 is(what, 42, "RejectCb received 42");
125 function promiseAsync_TimeoutResolveThen() {
126 var handlerExecuted = false;
128 setTimeout(function () {
129 ok(handlerExecuted, "Handler should have been called before the timeout.");
131 // Allow other assertions to run so the test could fail before the next one.
132 setTimeout(runTest, 0);
135 Promise.resolve().then(function () {
136 handlerExecuted = true;
139 ok(!handlerExecuted, "Handlers are not called before 'then' returns.");
142 function promiseAsync_ResolveTimeoutThen() {
143 var handlerExecuted = false;
145 var promise = Promise.resolve();
147 setTimeout(function () {
148 ok(handlerExecuted, "Handler should have been called before the timeout.");
150 // Allow other assertions to run so the test could fail before the next one.
151 setTimeout(runTest, 0);
154 promise.then(function () {
155 handlerExecuted = true;
158 ok(!handlerExecuted, "Handlers are not called before 'then' returns.");
161 function promiseAsync_ResolveThenTimeout() {
162 var handlerExecuted = false;
164 Promise.resolve().then(function () {
165 handlerExecuted = true;
168 setTimeout(function () {
169 ok(handlerExecuted, "Handler should have been called before the timeout.");
171 // Allow other assertions to run so the test could fail before the next one.
172 setTimeout(runTest, 0);
175 ok(!handlerExecuted, "Handlers are not called before 'then' returns.");
178 function promiseAsync_SyncXHRAndImportScripts() {
179 var handlerExecuted = false;
181 Promise.resolve().then(function () {
182 handlerExecuted = true;
184 // Allow other assertions to run so the test could fail before the next one.
185 setTimeout(runTest, 0);
188 ok(!handlerExecuted, "Handlers are not called until the next microtask.");
190 var xhr = new XMLHttpRequest();
191 xhr.open("GET", "testXHR.txt", false);
194 ok(!handlerExecuted, "Sync XHR should not trigger microtask execution.");
196 importScripts("../../../dom/xhr/tests/relativeLoad_import.js");
198 ok(!handlerExecuted, "importScripts should not trigger microtask execution.");
201 function promiseDoubleThen() {
203 var promise = new Promise(function (r1, r2) {
209 ok(true, "Then.resolve has been called");
210 is(what, 42, "Value == 42");
214 ok(false, "Then.reject has been called");
220 ok(true, "Then.resolve has been called");
221 is(steps, 1, "Then.resolve - step == 1");
222 is(what, 42, "Value == 42");
226 ok(false, "Then.reject has been called");
231 function promiseThenException() {
232 var promise = new Promise(function (resolve, reject) {
237 .then(function (what) {
238 ok(true, "Then.resolve has been called");
241 .catch(function (e) {
242 ok(true, "Catch has been called!");
247 function promiseThenCatchThen() {
248 var promise = new Promise(function (resolve, reject) {
252 var promise2 = promise.then(
254 ok(true, "Then.resolve has been called");
255 is(what, 42, "Value == 42");
259 ok(false, "Then.reject has been called");
263 isnot(promise, promise2, "These 2 promise objs are different");
268 ok(true, "Then.resolve has been called");
269 is(what, 43, "Value == 43");
273 ok(false, "Then.reject has been called");
277 ok(false, "Catch has been called");
281 ok(true, "Then.resolve has been called");
282 is(what, 44, "Value == 44");
286 ok(false, "Then.reject has been called");
291 function promiseRejectThenCatchThen() {
292 var promise = new Promise(function (resolve, reject) {
296 var promise2 = promise.then(
298 ok(false, "Then.resolve has been called");
301 ok(true, "Then.reject has been called");
302 is(what, 42, "Value == 42");
307 isnot(promise, promise2, "These 2 promise objs are different");
310 .then(function (what) {
311 ok(true, "Then.resolve has been called");
312 is(what, 43, "Value == 43");
315 .catch(function (what) {
316 ok(false, "Catch has been called");
318 .then(function (what) {
319 ok(true, "Then.resolve has been called");
320 is(what, 44, "Value == 44");
325 function promiseRejectThenCatchThen2() {
326 var promise = new Promise(function (resolve, reject) {
331 .then(function (what) {
332 ok(true, "Then.resolve has been called");
333 is(what, 42, "Value == 42");
336 .catch(function (what) {
337 is(what, 42, "Value == 42");
338 ok(true, "Catch has been called");
341 .then(function (what) {
342 ok(true, "Then.resolve has been called");
343 is(what, 43, "Value == 43");
348 function promiseRejectThenCatchExceptionThen() {
349 var promise = new Promise(function (resolve, reject) {
356 ok(false, "Then.resolve has been called");
359 ok(true, "Then.reject has been called");
360 is(what, 42, "Value == 42");
364 .catch(function (what) {
365 ok(true, "Catch has been called");
366 is(what, 43, "Value == 43");
369 .then(function (what) {
370 ok(true, "Then.resolve has been called");
371 is(what, 44, "Value == 44");
376 function promiseThenCatchOrderingResolve() {
378 var f = new Promise(function (r1, r2) {
386 f.catch(function () {
392 setTimeout(function () {
393 is(global, 2, "Many steps... should return 2");
399 function promiseThenCatchOrderingReject() {
401 var f = new Promise(function (r1, r2) {
411 f.catch(function () {
420 setTimeout(function () {
421 is(global, 2, "Many steps... should return 2");
428 function promiseThenNoArg() {
429 var promise = new Promise(function (resolve, reject) {
433 var clone = promise.then();
434 isnot(promise, clone, "These 2 promise objs are different");
435 promise.then(function (v) {
436 clone.then(function (cv) {
437 is(v, cv, "Both resolve to the same value");
443 function promiseThenUndefinedResolveFunction() {
444 var promise = new Promise(function (resolve, reject) {
449 promise.then(undefined, function (v) {
450 is(v, 42, "Promise rejected with 42");
454 ok(false, "then should not throw on undefined resolve function");
458 function promiseThenNullResolveFunction() {
459 var promise = new Promise(function (resolve, reject) {
464 promise.then(null, function (v) {
465 is(v, 42, "Promise rejected with 42");
469 ok(false, "then should not throw on null resolve function");
473 function promiseCatchNoArg() {
474 var promise = new Promise(function (resolve, reject) {
478 var clone = promise.catch();
479 isnot(promise, clone, "These 2 promise objs are different");
480 promise.catch(function (v) {
481 clone.catch(function (cv) {
482 is(v, cv, "Both reject to the same value");
488 function promiseNestedPromise() {
489 new Promise(function (resolve, reject) {
491 new Promise(function (r) {
492 ok(true, "Nested promise is executed");
496 }).then(function (value) {
497 is(value, 42, "Nested promise is executed and then == 42");
502 function promiseNestedNestedPromise() {
503 new Promise(function (resolve, reject) {
505 new Promise(function (r) {
506 ok(true, "Nested promise is executed");
508 }).then(function (what) {
512 }).then(function (value) {
513 is(value, 43, "Nested promise is executed and then == 43");
518 function promiseWrongNestedPromise() {
519 new Promise(function (resolve, reject) {
521 new Promise(function (r, r2) {
522 ok(true, "Nested promise is executed");
529 is(value, 42, "Nested promise is executed and then == 42");
533 ok(false, "This is wrong");
538 function promiseLoop() {
539 new Promise(function (resolve, reject) {
541 new Promise(function (r1, r2) {
542 ok(true, "Nested promise is executed");
544 new Promise(function (r3, r4) {
545 ok(true, "Nested nested promise is executed");
553 is(value, 42, "Nested nested promise is executed and then == 42");
557 ok(false, "This is wrong");
562 function promiseStaticReject() {
563 var promise = Promise.reject(42).then(
565 ok(false, "This should not be called");
568 is(what, 42, "Value == 42");
574 function promiseStaticResolve() {
575 var promise = Promise.resolve(42).then(
577 is(what, 42, "Value == 42");
581 ok(false, "This should not be called");
586 function promiseResolveNestedPromise() {
587 var promise = Promise.resolve(
590 ok(true, "Nested promise is executed");
594 ok(false, "This should not be called");
599 is(what, 42, "Value == 42");
603 ok(false, "This should not be called");
608 function promiseUtilitiesDefined() {
609 ok(Promise.all, "Promise.all must be defined when Promise is enabled.");
610 ok(Promise.race, "Promise.race must be defined when Promise is enabled.");
614 function promiseAllArray() {
615 var p = Promise.all([1, new Date(), Promise.resolve("firefox")]);
616 ok(p instanceof Promise, "Return value of Promise.all should be a Promise.");
619 ok(Array.isArray(values), "Resolved value should be an array.");
623 "Resolved array length should match iterable's length."
625 is(values[0], 1, "Array values should match.");
626 ok(values[1] instanceof Date, "Array values should match.");
627 is(values[2], "firefox", "Array values should match.");
633 "Promise.all shouldn't fail when iterable has no rejected Promises."
640 function promiseAllWaitsForAllPromises() {
642 new Promise(function (resolve) {
643 setTimeout(resolve.bind(undefined, 1), 50);
645 new Promise(function (resolve) {
646 setTimeout(resolve.bind(undefined, 2), 10);
648 new Promise(function (resolve) {
652 new Promise(function (resolve2) {
659 new Promise(function (resolve) {
660 setTimeout(resolve.bind(undefined, 4), 20);
664 var p = Promise.all(arr);
667 ok(Array.isArray(values), "Resolved value should be an array.");
671 "Resolved array length should match iterable's length."
673 is(values[0], 1, "Array values should match.");
674 is(values[1], 2, "Array values should match.");
675 is(values[2], 3, "Array values should match.");
676 is(values[3], 4, "Array values should match.");
682 "Promise.all shouldn't fail when iterable has no rejected Promises."
689 function promiseAllRejectFails() {
691 new Promise(function (resolve) {
692 setTimeout(resolve.bind(undefined, 1), 50);
694 new Promise(function (resolve, reject) {
695 setTimeout(reject.bind(undefined, 2), 10);
697 new Promise(function (resolve) {
698 setTimeout(resolve.bind(undefined, 3), 10);
700 new Promise(function (resolve) {
701 setTimeout(resolve.bind(undefined, 4), 20);
705 var p = Promise.all(arr);
710 "Promise.all shouldn't resolve when iterable has rejected Promises."
717 "Promise.all should reject when iterable has rejected Promises."
719 is(e, 2, "Rejection value should match.");
725 function promiseRaceEmpty() {
726 var p = Promise.race([]);
727 ok(p instanceof Promise, "Should return a Promise.");
728 // An empty race never resolves!
732 function promiseRaceValuesArray() {
733 var p = Promise.race([true, new Date(), 3]);
734 ok(p instanceof Promise, "Should return a Promise.");
737 is(winner, true, "First value should win.");
741 ok(false, "Should not fail " + err + ".");
747 function promiseRacePromiseArray() {
749 new Promise(function (resolve) {
752 Promise.resolve("second"),
753 new Promise(function () {}),
754 new Promise(function (resolve) {
755 setTimeout(function () {
756 setTimeout(function () {
763 var p = Promise.race(arr);
764 p.then(function (winner) {
765 is(winner, "first", "First queued resolution should win the race.");
770 function promiseRaceReject() {
771 var p = Promise.race([
772 Promise.reject(new Error("Fail bad!")),
773 new Promise(function (resolve) {
774 setTimeout(resolve, 0);
780 ok(false, "Should not resolve when winning Promise rejected.");
784 ok(true, "Should be rejected");
785 ok(e instanceof Error, "Should reject with Error.");
786 ok(e.message == "Fail bad!", "Message should match.");
792 function promiseRaceThrow() {
793 var p = Promise.race([
794 new Promise(function (resolve) {
797 new Promise(function (resolve) {
798 setTimeout(resolve, 0);
804 ok(false, "Should not resolve when winning Promise had an error.");
808 ok(true, "Should be rejected");
810 e instanceof ReferenceError,
811 "Should reject with ReferenceError for function nonExistent()."
818 function promiseResolveArray() {
819 var p = Promise.resolve([1, 2, 3]);
820 ok(p instanceof Promise, "Should return a Promise.");
821 p.then(function (v) {
822 ok(Array.isArray(v), "Resolved value should be an Array");
823 is(v.length, 3, "Length should match");
824 is(v[0], 1, "Resolved value should match original");
825 is(v[1], 2, "Resolved value should match original");
826 is(v[2], 3, "Resolved value should match original");
831 function promiseResolveThenable() {
832 var p = Promise.resolve({
833 then(onFulfill, onReject) {
837 ok(p instanceof Promise, "Should cast to a Promise.");
840 is(v, 2, "Should resolve to 2.");
844 ok(false, "promiseResolveThenable should've resolved");
850 function promiseResolvePromise() {
851 var original = Promise.resolve(true);
852 var cast = Promise.resolve(original);
854 ok(cast instanceof Promise, "Should cast to a Promise.");
855 is(cast, original, "Should return original Promise.");
856 cast.then(function (v) {
857 is(v, true, "Should resolve to true.");
863 // Ensure that thenables are run on a clean stack asynchronously.
864 // Test case adopted from
865 // https://gist.github.com/getify/d64bb01751b50ed6b281#file-bug1-js.
866 function promiseResolveThenableCleanStack() {
876 var thenable = { then: immed };
879 var p = Promise.resolve(thenable).then(incX);
882 // check what happens after all "next cycle" steps
883 // have had a chance to complete
884 setTimeout(function () {
885 // Result should be [0, 2] since `thenable` will be called async.
886 is(results[0], 0, "Expected thenable to be called asynchronously");
887 // See Bug 1023547 comment 13 for why this check has to be gated on p.
890 is(results[1], 2, "Expected thenable to be called asynchronously");
897 function promiseWrapperAsyncResolution() {
898 var p = new Promise(function (resolve, reject) {
925 Promise.all([q, r]).then(
928 results[0] == "1-1" &&
929 results[1] == "2-1" &&
930 results[2] == "1-2" &&
931 results[3] == "2-2" &&
932 results[4] == "1-3" &&
934 ok(match, "Chained promises should resolve asynchronously.");
938 ok(false, "promiseWrapperAsyncResolution: One of the promises failed.");
948 promiseAsync_TimeoutResolveThen,
949 promiseAsync_ResolveTimeoutThen,
950 promiseAsync_ResolveThenTimeout,
951 promiseAsync_SyncXHRAndImportScripts,
953 promiseThenException,
954 promiseThenCatchThen,
955 promiseRejectThenCatchThen,
956 promiseRejectThenCatchThen2,
957 promiseRejectThenCatchExceptionThen,
958 promiseThenCatchOrderingResolve,
959 promiseThenCatchOrderingReject,
960 promiseNestedPromise,
961 promiseNestedNestedPromise,
962 promiseWrongNestedPromise,
965 promiseStaticResolve,
966 promiseResolveNestedPromise,
971 promiseThenUndefinedResolveFunction,
972 promiseThenNullResolveFunction,
974 promiseRejectNoHandler,
976 promiseUtilitiesDefined,
979 promiseAllWaitsForAllPromises,
980 promiseAllRejectFails,
983 promiseRaceValuesArray,
984 promiseRacePromiseArray,
989 promiseResolveThenable,
990 promiseResolvePromise,
992 promiseResolveThenableCleanStack,
994 promiseWrapperAsyncResolution,
999 postMessage({ type: "finish" });
1003 var test = tests.shift();
1007 onmessage = function () {