diff --git a/test/built-ins/Promise/prototype/then/rxn-handler-fulfilled-next-abrupt.js b/test/built-ins/Promise/prototype/then/rxn-handler-fulfilled-next-abrupt.js new file mode 100644 index 0000000000..00d6aeff04 --- /dev/null +++ b/test/built-ins/Promise/prototype/then/rxn-handler-fulfilled-next-abrupt.js @@ -0,0 +1,44 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Abrupt completions should not preclude additional jobs +es6id: 25.4.2.1 +info: > + [...] + 7. If handlerResult is an abrupt completion, then + a. Let status be Call(promiseCapability.[[Reject]], undefined, + «handlerResult.[[value]]»). + b. NextJob Completion(status). + 8. Let status be Call(promiseCapability.[[Resolve]], undefined, + «handlerResult.[[value]]»). + 9. NextJob Completion(status). +---*/ + +var promise = new Promise(function(resolve) { + resolve(); +}); +var fulfilledCallCount = 0; +var rejectedCallCount = 0; + +promise.then(function() { + fulfilledCallCount += 1; + throw new Error(); + }, function() { + rejectedCallCount += 1; + }); + +promise.then(function() { + if (fulfilledCallCount !== 1) { + $DONE('Expected "onFulfilled" handler to be invoked exactly once.'); + return; + } + + if (rejectedCallCount !== 0) { + $DONE('Expected "onRejected" handler to not be invoked.'); + return; + } + + $DONE(); + }, function() { + $DONE('This promise should not be rejected.'); + }); diff --git a/test/built-ins/Promise/prototype/then/rxn-handler-fulfilled-next.js b/test/built-ins/Promise/prototype/then/rxn-handler-fulfilled-next.js new file mode 100644 index 0000000000..1443459a16 --- /dev/null +++ b/test/built-ins/Promise/prototype/then/rxn-handler-fulfilled-next.js @@ -0,0 +1,52 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: All queued jobs should be executed in series +es6id: 25.4.2.1 +info: > + [...] + 7. If handlerResult is an abrupt completion, then + a. Let status be Call(promiseCapability.[[Reject]], undefined, + «handlerResult.[[value]]»). + b. NextJob Completion(status). + 8. Let status be Call(promiseCapability.[[Resolve]], undefined, + «handlerResult.[[value]]»). + 9. NextJob Completion(status). +---*/ + +var promise = new Promise(function(resolve) { + resolve(); +}); +var log = ''; + +promise.then(function() { + log += 'a'; + }, function() { + log += 'A'; + }); + +promise.then(function() { + log += 'b'; + }, function() { + log += 'B'; + }); + +promise.then(function() { + log += 'c'; + }, function() { + log += 'C'; + }); + +promise.then(function() { + if (log !== 'abc') { + $DONE( + 'Expected each "onFulfilled" handler to be invoked exactly once in series. ' + + 'Expected: abc. Actual: ' + log + ); + return; + } + + $DONE(); + }, function() { + $DONE('This promise should not be rejected.'); + }); diff --git a/test/built-ins/Promise/prototype/then/rxn-handler-rejected-next-abrupt.js b/test/built-ins/Promise/prototype/then/rxn-handler-rejected-next-abrupt.js new file mode 100644 index 0000000000..6c3d18b40d --- /dev/null +++ b/test/built-ins/Promise/prototype/then/rxn-handler-rejected-next-abrupt.js @@ -0,0 +1,44 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Abrupt completions should not preclude additional jobs +es6id: 25.4.2.1 +info: > + [...] + 7. If handlerResult is an abrupt completion, then + a. Let status be Call(promiseCapability.[[Reject]], undefined, + «handlerResult.[[value]]»). + b. NextJob Completion(status). + 8. Let status be Call(promiseCapability.[[Resolve]], undefined, + «handlerResult.[[value]]»). + 9. NextJob Completion(status). +---*/ + +var promise = new Promise(function(_, reject) { + reject(); +}); +var fulfilledCallCount = 0; +var rejectedCallCount = 0; + +promise.then(function() { + fulfilledCallCount += 1; + }, function() { + rejectedCallCount += 1; + throw new Error(); + }); + +promise.then(function() { + $DONE('This promise should not be fulfilled.'); + }, function() { + if (fulfilledCallCount !== 0) { + $DONE('Expected "onFulfilled" handler to not be invoked.'); + return; + } + + if (rejectedCallCount !== 1) { + $DONE('Expected "onRejected" handler to be invoked exactly once.'); + return; + } + + $DONE(); + }); diff --git a/test/built-ins/Promise/prototype/then/rxn-handler-rejected-next.js b/test/built-ins/Promise/prototype/then/rxn-handler-rejected-next.js new file mode 100644 index 0000000000..59a3916b3a --- /dev/null +++ b/test/built-ins/Promise/prototype/then/rxn-handler-rejected-next.js @@ -0,0 +1,52 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: All queued jobs should be executed in series +es6id: 25.4.2.1 +info: > + [...] + 7. If handlerResult is an abrupt completion, then + a. Let status be Call(promiseCapability.[[Reject]], undefined, + «handlerResult.[[value]]»). + b. NextJob Completion(status). + 8. Let status be Call(promiseCapability.[[Resolve]], undefined, + «handlerResult.[[value]]»). + 9. NextJob Completion(status). +---*/ + +var promise = new Promise(function(_, reject) { + reject(); +}); +var log = ''; + +promise.then(function() { + log += 'A'; + }, function() { + log += 'a'; + }); + +promise.then(function() { + log += 'B'; + }, function() { + log += 'b'; + }); + +promise.then(function() { + log += 'C'; + }, function() { + log += 'c'; + }); + +promise.then(function() { + $DONE('This promise should not be fulfilled.'); + }, function() { + if (log !== 'abc') { + $DONE( + 'Expected each "onFulfilled" handler to be invoked exactly once in series. ' + + 'Expected: abc. Actual: ' + log + ); + return; + } + + $DONE(); + }); diff --git a/test/built-ins/Promise/prototype/then/rxn-handler-rejected-return-normal.js b/test/built-ins/Promise/prototype/then/rxn-handler-rejected-return-normal.js new file mode 100644 index 0000000000..1277801c50 --- /dev/null +++ b/test/built-ins/Promise/prototype/then/rxn-handler-rejected-return-normal.js @@ -0,0 +1,49 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: A normal completion should trigger promise fulfillment +es6id: 25.4.5.3 +info: > + [...] + 7. Return PerformPromiseThen(promise, onFulfilled, onRejected, + resultCapability). + + 25.4.5.3.1 PerformPromiseThen + [...] + 9. Else if the value of promise's [[PromiseState]] internal slot is + "rejected", + a. Let reason be the value of promise's [[PromiseResult]] internal slot. + b. Perform EnqueueJob("PromiseJobs", PromiseReactionJob, + «rejectReaction, reason»). + + 25.4.2.1 PromiseReactionJob + [...] + 7. If handlerResult is an abrupt completion, then + a. Let status be Call(promiseCapability.[[Reject]], undefined, + «handlerResult.[[value]]»). + b. NextJob Completion(status). + 8. Let status be Call(promiseCapability.[[Resolve]], undefined, + «handlerResult.[[value]]»). + 9. NextJob Completion(status). +---*/ + +var value = {}; +var p1 = new Promise(function(_, reject) { + reject(); +}); +var p2; + +p2 = p1.then(function() {}, function() { + return value; + }); + +p2.then(function(x) { + if (x !== value) { + $DONE('The `onFulfilled` handler should be invoked with the promise result.'); + return; + } + + $DONE(); + }, function() { + $DONE('The `onRejected` handler should not be invoked.'); + });