| <!DOCTYPE html> |
| <html> |
| <head> |
| <meta charset="utf-8"> |
| <script src="../../resources/js-test-pre.js"></script> |
| </head> |
| <body> |
| <script> |
| |
| // Adapted from http://dxr.mozilla.org/mozilla-central/source/dom/promise/tests/test_promise.html which stated: |
| // Any copyright is dedicated to the Public Domain. |
| // http://creativecommons.org/publicdomain/zero/1.0/ |
| |
| description("Promises - Adapted from http://dxr.mozilla.org/mozilla-central/source/dom/promise/tests/test_promise.html."); |
| |
| window.jsTestIsAsync = true; |
| |
| function ok(_a, _msg) { |
| if (_a) |
| testPassed(_msg); |
| else |
| testFailed(_msg); |
| } |
| |
| function is(_a, _b, _msg) { |
| if (isResultCorrect(_a, _b)) |
| testPassed(stringify(_a) + " is " + stringify(_b)); |
| else |
| testFailed(stringify(_a) + " should be " + stringify(_b)); |
| } |
| |
| function isnot(_a, _b, _msg) { |
| if (!isResultCorrect(_a, _b)) |
| testPassed(stringify(_a) + " should not be " + stringify(_b)); |
| else |
| testFailed(stringify(_a) + " is " + stringify(_b)); |
| } |
| |
| function promiseResolve() { |
| ok(Promise, "Promise object should exist"); |
| |
| var promise = new Promise(function(resolve, reject) { |
| ok(resolve, "Promise.resolve exists"); |
| ok(reject, "Promise.reject exists"); |
| |
| resolve(42); |
| }).then(function(what) { |
| ok(true, "Then - resolveCb has been called"); |
| is(what, 42, "ResolveCb received 42"); |
| runTest(); |
| }, function() { |
| ok(false, "Then - rejectCb has been called"); |
| runTest(); |
| }); |
| } |
| |
| function promiseResolveNoArg() { |
| var promise = new Promise(function(resolve, reject) { |
| ok(resolve, "Promise.resolve exists"); |
| ok(reject, "Promise.reject exists"); |
| |
| resolve(); |
| }).then(function(what) { |
| ok(true, "Then - resolveCb has been called"); |
| is(what, undefined, "ResolveCb received undefined"); |
| runTest(); |
| }, function() { |
| ok(false, "Then - rejectCb has been called"); |
| runTest(); |
| }); |
| } |
| |
| function promiseReject() { |
| var promise = new Promise(function(resolve, reject) { |
| reject(42); |
| }).then(function(what) { |
| ok(false, "Then - resolveCb has been called"); |
| runTest(); |
| }, function(what) { |
| ok(true, "Then - rejectCb has been called"); |
| is(what, 42, "RejectCb received 42"); |
| runTest(); |
| }); |
| } |
| |
| function promiseRejectNoHandler() { |
| // This test only checks that the code that reports unhandled errors in the |
| // Promises implementation does not crash or leak. |
| var promise = new Promise(function(res, rej) { |
| noSuchMethod(); |
| }); |
| runTest(); |
| } |
| |
| function promiseRejectNoArg() { |
| var promise = new Promise(function(resolve, reject) { |
| reject(); |
| }).then(function(what) { |
| ok(false, "Then - resolveCb has been called"); |
| runTest(); |
| }, function(what) { |
| ok(true, "Then - rejectCb has been called"); |
| is(what, undefined, "RejectCb received undefined"); |
| runTest(); |
| }); |
| } |
| |
| function promiseException() { |
| var promise = new Promise(function(resolve, reject) { |
| throw 42; |
| }).then(function(what) { |
| ok(false, "Then - resolveCb has been called"); |
| runTest(); |
| }, function(what) { |
| ok(true, "Then - rejectCb has been called"); |
| is(what, 42, "RejectCb received 42"); |
| runTest(); |
| }); |
| } |
| |
| function promiseGC() { |
| var resolve; |
| var promise = new Promise(function(r1, r2) { |
| resolve = r1; |
| }).then(function(what) { |
| ok(true, "Then - promise is still alive"); |
| runTest(); |
| }); |
| |
| promise = null; |
| |
| gc(); |
| |
| resolve(42); |
| } |
| |
| function promiseAsync() { |
| var global = "foo"; |
| var f = new Promise(function(r1, r2) { |
| is(global, "foo", "Global should be foo"); |
| r1(42); |
| is(global, "foo", "Global should still be foo"); |
| setTimeout(function() { |
| is(global, "bar", "Global should still be bar!"); |
| runTest(); |
| }, 0); |
| }).then(function() { |
| global = "bar"; |
| }); |
| is(global, "foo", "Global should still be foo (2)"); |
| } |
| |
| function promiseDoubleThen() { |
| var steps = 0; |
| var promise = new Promise(function(r1, r2) { |
| r1(42); |
| }); |
| |
| promise.then(function(what) { |
| ok(true, "Then.resolve has been called"); |
| is(what, 42, "Value == 42"); |
| steps++; |
| }, function(what) { |
| ok(false, "Then.reject has been called"); |
| }); |
| |
| promise.then(function(what) { |
| ok(true, "Then.resolve has been called"); |
| is(steps, 1, "Then.resolve - step == 1"); |
| is(what, 42, "Value == 42"); |
| runTest(); |
| }, function(what) { |
| ok(false, "Then.reject has been called"); |
| }); |
| } |
| |
| function promiseThenException() { |
| var promise = new Promise(function(resolve, reject) { |
| resolve(42); |
| }); |
| |
| promise.then(function(what) { |
| ok(true, "Then.resolve has been called"); |
| throw "booh"; |
| }).catch(function(e) { |
| ok(true, "window.onerror has been called!"); |
| runTest(); |
| }); |
| } |
| |
| function promiseThenCatchThen() { |
| var promise = new Promise(function(resolve, reject) { |
| resolve(42); |
| }); |
| |
| var promise2 = promise.then(function(what) { |
| ok(true, "Then.resolve has been called"); |
| is(what, 42, "Value == 42"); |
| return what + 1; |
| }, function(what) { |
| ok(false, "Then.reject has been called"); |
| }); |
| |
| isnot(promise, promise2, "These 2 promise objs are different"); |
| |
| promise2.then(function(what) { |
| ok(true, "Then.resolve has been called"); |
| is(what, 43, "Value == 43"); |
| return what + 1; |
| }, function(what) { |
| ok(false, "Then.reject has been called"); |
| }).catch(function() { |
| ok(false, "Catch has been called"); |
| }).then(function(what) { |
| ok(true, "Then.resolve has been called"); |
| is(what, 44, "Value == 44"); |
| runTest(); |
| }, function(what) { |
| ok(false, "Then.reject has been called"); |
| }); |
| } |
| |
| function promiseThenNoArg() { |
| var promise = new Promise(function(resolve, reject) { |
| resolve(42); |
| }); |
| |
| var clone = promise.then(); |
| isnot(promise, clone, "These 2 promise objs are different"); |
| promise.then(function(v) { |
| clone.then(function(cv) { |
| is(v, cv, "Both resolve to the same value"); |
| runTest(); |
| }); |
| }); |
| } |
| |
| function promiseThenUndefinedResolveFunction() { |
| var promise = new Promise(function(resolve, reject) { |
| reject(42); |
| }); |
| |
| try { |
| promise.then(undefined, function(v) { |
| is(v, 42, "Promise rejected with 42"); |
| runTest(); |
| }); |
| } catch (e) { |
| ok(false, "then should not throw on undefined resolve function"); |
| } |
| } |
| |
| function promiseThenNullResolveFunction() { |
| var promise = new Promise(function(resolve, reject) { |
| reject(42); |
| }); |
| |
| try { |
| promise.then(null, function(v) { |
| is(v, 42, "Promise rejected with 42"); |
| runTest(); |
| }); |
| } catch (e) { |
| ok(false, "then should not throw on null resolve function"); |
| } |
| } |
| |
| function promiseRejectThenCatchThen() { |
| var promise = new Promise(function(resolve, reject) { |
| reject(42); |
| }); |
| |
| var promise2 = promise.then(function(what) { |
| ok(false, "Then.resolve has been called"); |
| }, function(what) { |
| ok(true, "Then.reject has been called"); |
| is(what, 42, "Value == 42"); |
| return what + 1; |
| }); |
| |
| isnot(promise, promise2, "These 2 promise objs are different"); |
| |
| promise2.then(function(what) { |
| ok(true, "Then.resolve has been called"); |
| is(what, 43, "Value == 43"); |
| return what+1; |
| }).catch(function(what) { |
| ok(false, "Catch has been called"); |
| }).then(function(what) { |
| ok(true, "Then.resolve has been called"); |
| is(what, 44, "Value == 44"); |
| runTest(); |
| }); |
| } |
| |
| function promiseRejectThenCatchThen2() { |
| var promise = new Promise(function(resolve, reject) { |
| reject(42); |
| }); |
| |
| promise.then(function(what) { |
| ok(true, "Then.resolve has been called"); |
| is(what, 42, "Value == 42"); |
| return what+1; |
| }).catch(function(what) { |
| is(what, 42, "Value == 42"); |
| ok(true, "Catch has been called"); |
| return what+1; |
| }).then(function(what) { |
| ok(true, "Then.resolve has been called"); |
| is(what, 43, "Value == 43"); |
| runTest(); |
| }); |
| } |
| |
| function promiseRejectThenCatchExceptionThen() { |
| var promise = new Promise(function(resolve, reject) { |
| reject(42); |
| }); |
| |
| promise.then(function(what) { |
| ok(false, "Then.resolve has been called"); |
| }, function(what) { |
| ok(true, "Then.reject has been called"); |
| is(what, 42, "Value == 42"); |
| throw(what + 1); |
| }).catch(function(what) { |
| ok(true, "Catch has been called"); |
| is(what, 43, "Value == 43"); |
| return what + 1; |
| }).then(function(what) { |
| ok(true, "Then.resolve has been called"); |
| is(what, 44, "Value == 44"); |
| runTest(); |
| }); |
| } |
| |
| function promiseThenCatchOrderingResolve() { |
| var global = 0; |
| var f = new Promise(function(r1, r2) { |
| r1(42); |
| }); |
| |
| f.then(function() { |
| f.then(function() { |
| global++; |
| }); |
| f.catch(function() { |
| global++; |
| }); |
| f.then(function() { |
| global++; |
| }); |
| setTimeout(function() { |
| is(global, 2, "Many steps... should return 2"); |
| runTest(); |
| }, 0); |
| }); |
| } |
| |
| function promiseThenCatchOrderingReject() { |
| var global = 0; |
| var f = new Promise(function(r1, r2) { |
| r2(42); |
| }) |
| |
| f.then(function() {}, function() { |
| f.then(function() { |
| global++; |
| }); |
| f.catch(function() { |
| global++; |
| }); |
| f.then(function() {}, function() { |
| global++; |
| }); |
| setTimeout(function() { |
| is(global, 2, "Many steps... should return 2"); |
| runTest(); |
| }, 0); |
| }); |
| } |
| |
| function promiseCatchNoArg() { |
| var promise = new Promise(function(resolve, reject) { |
| reject(42); |
| }); |
| |
| var clone = promise.catch(); |
| isnot(promise, clone, "These 2 promise objs are different"); |
| promise.catch(function(v) { |
| clone.catch(function(cv) { |
| is(v, cv, "Both reject to the same value"); |
| runTest(); |
| }); |
| }); |
| } |
| |
| function promiseNestedPromise() { |
| new Promise(function(resolve, reject) { |
| resolve(new Promise(function(resolve, reject) { |
| ok(true, "Nested promise is executed"); |
| resolve(42); |
| })); |
| }).then(function(value) { |
| is(value, 42, "Nested promise is executed and then == 42"); |
| runTest(); |
| }); |
| } |
| |
| function promiseNestedNestedPromise() { |
| new Promise(function(resolve, reject) { |
| resolve(new Promise(function(resolve, reject) { |
| ok(true, "Nested promise is executed"); |
| resolve(42); |
| }).then(function(what) { return what+1; })); |
| }).then(function(value) { |
| is(value, 43, "Nested promise is executed and then == 43"); |
| runTest(); |
| }); |
| } |
| |
| function promiseWrongNestedPromise() { |
| new Promise(function(resolve, reject) { |
| resolve(new Promise(function(r, r2) { |
| ok(true, "Nested promise is executed"); |
| r(42); |
| })); |
| reject(42); |
| }).then(function(value) { |
| is(value, 42, "Nested promise is executed and then == 42"); |
| runTest(); |
| }, function(value) { |
| ok(false, "This is wrong"); |
| }); |
| } |
| |
| function promiseLoop() { |
| new Promise(function(resolve, reject) { |
| resolve(new Promise(function(r1, r2) { |
| ok(true, "Nested promise is executed"); |
| r1(new Promise(function(r1, r2) { |
| ok(true, "Nested nested promise is executed"); |
| r1(42); |
| })); |
| })); |
| }).then(function(value) { |
| is(value, 42, "Nested nested promise is executed and then == 42"); |
| runTest(); |
| }, function(value) { |
| ok(false, "This is wrong"); |
| }); |
| } |
| |
| function promiseStaticReject() { |
| var promise = Promise.reject(42).then(function(what) { |
| ok(false, "This should not be called"); |
| }, function(what) { |
| is(what, 42, "Value == 42"); |
| runTest(); |
| }); |
| } |
| |
| function promiseStaticResolve() { |
| var promise = Promise.resolve(42).then(function(what) { |
| is(what, 42, "Value == 42"); |
| runTest(); |
| }, function() { |
| ok(false, "This should not be called"); |
| }); |
| } |
| |
| function promiseResolveNestedPromise() { |
| var promise = Promise.resolve(new Promise(function(r, r2) { |
| ok(true, "Nested promise is executed"); |
| r(42); |
| }, function() { |
| ok(false, "This should not be called"); |
| })).then(function(what) { |
| is(what, 42, "Value == 42"); |
| runTest(); |
| }, function() { |
| ok(false, "This should not be called"); |
| }); |
| } |
| |
| function promiseSetTimeoutOrdering() { |
| var orderNumber = 0; |
| orderNumber++; |
| |
| Promise.resolve(null) |
| .then(function(v) { is(orderNumber++, 1, "Called first."); setTimeout(function() { is(orderNumber++, 6, "Called last."); runTest(); }, 0); return v; }) |
| .then(function(v) { is(orderNumber++, 2, "Called second."); return v }) |
| .then(function(v) { is(orderNumber++, 3, "Called third."); return v }) |
| .then(function(v) { is(orderNumber++, 4, "Called fourth."); return v }) |
| .then(function(v) { is(orderNumber++, 5, "Called fifth."); return v; }) |
| } |
| |
| var tests = [ |
| promiseResolve, |
| promiseReject, |
| promiseException, |
| promiseGC, |
| promiseAsync, |
| promiseDoubleThen, |
| promiseThenException, |
| promiseThenCatchThen, |
| promiseRejectThenCatchThen, |
| promiseRejectThenCatchThen2, |
| promiseRejectThenCatchExceptionThen, |
| promiseThenCatchOrderingResolve, |
| promiseThenCatchOrderingReject, |
| promiseNestedPromise, |
| promiseNestedNestedPromise, |
| promiseWrongNestedPromise, |
| promiseLoop, |
| promiseStaticReject, |
| promiseStaticResolve, |
| promiseResolveNestedPromise, |
| promiseResolveNoArg, |
| promiseRejectNoArg, |
| promiseThenNoArg, |
| promiseThenUndefinedResolveFunction, |
| promiseThenNullResolveFunction, |
| promiseCatchNoArg, |
| promiseRejectNoHandler, |
| promiseSetTimeoutOrdering, |
| ]; |
| |
| function runTest() { |
| if (!tests.length) { |
| finishJSTest(); |
| return; |
| } |
| |
| var test = tests.shift(); |
| debug("\nAbout to run test - " + test.name); |
| test(); |
| } |
| |
| runTest(); |
| |
| </script> |
| <script src="../../resources/js-test-post.js"></script> |
| </body> |
| </html> |