From c62700c8efbb9fac68b14b05083f195b19955236 Mon Sep 17 00:00:00 2001 From: Mike Pennisi Date: Fri, 24 Jun 2016 18:43:22 -0400 Subject: [PATCH] Assert iterator protocol for Promise methods --- ...close.js => invoke-resolve-error-close.js} | 3 +- .../all/invoke-resolve-error-reject.js | 39 +++++++++++++ .../all/invoke-resolve-get-error-close.js | 49 ++++++++++++++++ ....js => invoke-resolve-get-error-reject.js} | 7 ++- .../Promise/all/invoke-then-error-close.js | 49 ++++++++++++++++ ...n-error.js => invoke-then-error-reject.js} | 5 +- .../all/invoke-then-get-error-close.js | 51 ++++++++++++++++ .../all/invoke-then-get-error-reject.js | 41 +++++++++++++ .../Promise/all/iter-next-val-err-no-close.js | 56 ++++++++++++++++++ ...val-err.js => iter-next-val-err-reject.js} | 8 ++- .../Promise/all/iter-step-err-no-close.js | 58 +++++++++++++++++++ ...er-step-err.js => iter-step-err-reject.js} | 7 ++- .../race/invoke-resolve-error-close.js | 47 +++++++++++++++ ...lose.js => invoke-resolve-error-reject.js} | 24 ++------ .../race/invoke-resolve-get-error-close.js | 48 +++++++++++++++ ....js => invoke-resolve-get-error-reject.js} | 7 ++- .../Promise/race/invoke-then-error-close.js | 48 +++++++++++++++ ...n-error.js => invoke-then-error-reject.js} | 5 +- .../race/invoke-then-get-error-close.js | 49 ++++++++++++++++ .../race/invoke-then-get-error-reject.js | 40 +++++++++++++ .../race/iter-next-val-err-no-close.js | 54 +++++++++++++++++ ...val-err.js => iter-next-val-err-reject.js} | 6 +- .../Promise/race/iter-step-err-no-close.js | 52 +++++++++++++++++ ...er-step-err.js => iter-step-err-reject.js} | 5 +- 24 files changed, 718 insertions(+), 40 deletions(-) rename test/built-ins/Promise/all/{iter-close.js => invoke-resolve-error-close.js} (97%) create mode 100644 test/built-ins/Promise/all/invoke-resolve-error-reject.js create mode 100644 test/built-ins/Promise/all/invoke-resolve-get-error-close.js rename test/built-ins/Promise/all/{invoke-resolve-get-error.js => invoke-resolve-get-error-reject.js} (88%) create mode 100644 test/built-ins/Promise/all/invoke-then-error-close.js rename test/built-ins/Promise/all/{invoke-then-error.js => invoke-then-error-reject.js} (90%) create mode 100644 test/built-ins/Promise/all/invoke-then-get-error-close.js create mode 100644 test/built-ins/Promise/all/invoke-then-get-error-reject.js create mode 100644 test/built-ins/Promise/all/iter-next-val-err-no-close.js rename test/built-ins/Promise/all/{iter-next-val-err.js => iter-next-val-err-reject.js} (91%) create mode 100644 test/built-ins/Promise/all/iter-step-err-no-close.js rename test/built-ins/Promise/all/{iter-step-err.js => iter-step-err-reject.js} (93%) create mode 100644 test/built-ins/Promise/race/invoke-resolve-error-close.js rename test/built-ins/Promise/race/{iter-close.js => invoke-resolve-error-reject.js} (70%) create mode 100644 test/built-ins/Promise/race/invoke-resolve-get-error-close.js rename test/built-ins/Promise/race/{invoke-resolve-get-error.js => invoke-resolve-get-error-reject.js} (88%) create mode 100644 test/built-ins/Promise/race/invoke-then-error-close.js rename test/built-ins/Promise/race/{invoke-then-error.js => invoke-then-error-reject.js} (90%) create mode 100644 test/built-ins/Promise/race/invoke-then-get-error-close.js create mode 100644 test/built-ins/Promise/race/invoke-then-get-error-reject.js create mode 100644 test/built-ins/Promise/race/iter-next-val-err-no-close.js rename test/built-ins/Promise/race/{iter-next-val-err.js => iter-next-val-err-reject.js} (91%) create mode 100644 test/built-ins/Promise/race/iter-step-err-no-close.js rename test/built-ins/Promise/race/{iter-step-err.js => iter-step-err-reject.js} (93%) diff --git a/test/built-ins/Promise/all/iter-close.js b/test/built-ins/Promise/all/invoke-resolve-error-close.js similarity index 97% rename from test/built-ins/Promise/all/iter-close.js rename to test/built-ins/Promise/all/invoke-resolve-error-close.js index 9496ca7de9..ac2ca28249 100644 --- a/test/built-ins/Promise/all/iter-close.js +++ b/test/built-ins/Promise/all/invoke-resolve-error-close.js @@ -4,8 +4,9 @@ /*--- description: > Explicit iterator closing in response to error +esid: sec-promise.all es6id: 25.4.4.1 -info: > +info: | 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). 12. If result is an abrupt completion, a. If iteratorRecord.[[done]] is false, let result be diff --git a/test/built-ins/Promise/all/invoke-resolve-error-reject.js b/test/built-ins/Promise/all/invoke-resolve-error-reject.js new file mode 100644 index 0000000000..c21f205152 --- /dev/null +++ b/test/built-ins/Promise/all/invoke-resolve-error-reject.js @@ -0,0 +1,39 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Promise rejection in response to error +esid: sec-promise.all +es6id: 25.4.4.1 +info: | + 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + 12. If result is an abrupt completion, + a. If iteratorRecord.[[done]] is false, let result be + IteratorClose(iterator, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + [...] + + 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + + [...] + 6. Repeat + [...] + i. Let nextPromise be Invoke(constructor, "resolve", «nextValue»). + j. ReturnIfAbrupt(nextPromise ). +flags: [async] +---*/ + +var thrown = new Test262Error(); +Promise.resolve = function() { + throw thrown; +}; + +Promise.all([1]) + .then(function() { + $ERROR('The promise should not be fulfilled.'); + }, function(reason) { + if (reason !== thrown) { + $ERROR('The promise should be rejected with the thrown error object'); + } + }).then($DONE, $DONE); diff --git a/test/built-ins/Promise/all/invoke-resolve-get-error-close.js b/test/built-ins/Promise/all/invoke-resolve-get-error-close.js new file mode 100644 index 0000000000..ce43d8ab15 --- /dev/null +++ b/test/built-ins/Promise/all/invoke-resolve-get-error-close.js @@ -0,0 +1,49 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Error retrieving the constructor's `resolve` method (closing iterator) +esid: sec-performpromiseall +es6id: 25.4.4.1 +info: | + 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + 12. If result is an abrupt completion, + a. If iteratorRecord.[[done]] is false, let result be + IteratorClose(iterator, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + [...] + + 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + + [...] + 6. Repeat + [...] + i. Let nextPromise be Invoke(constructor, "resolve", «nextValue»). + j. ReturnIfAbrupt(nextPromise ). +features: [Symbol.iterator] +---*/ + +var iter = {}; +var returnCount = 0; +iter[Symbol.iterator] = function() { + return { + next: function() { + return { done: false }; + }, + return: function() { + returnCount += 1; + return {}; + } + }; +}; +Object.defineProperty(Promise, 'resolve', { + get: function() { + throw new Test262Error(); + } +}); + +Promise.all(iter); + +assert.sameValue(returnCount, 1); diff --git a/test/built-ins/Promise/all/invoke-resolve-get-error.js b/test/built-ins/Promise/all/invoke-resolve-get-error-reject.js similarity index 88% rename from test/built-ins/Promise/all/invoke-resolve-get-error.js rename to test/built-ins/Promise/all/invoke-resolve-get-error-reject.js index 70c220f0b9..d03378253d 100644 --- a/test/built-ins/Promise/all/invoke-resolve-get-error.js +++ b/test/built-ins/Promise/all/invoke-resolve-get-error-reject.js @@ -3,9 +3,10 @@ /*--- description: > - Error retrieving the constructor's `resolve` method + Error retrieving the constructor's `resolve` method (rejecting promise) +esid: sec-performpromiseall es6id: 25.4.4.1 -info: > +info: | 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). 12. If result is an abrupt completion, a. If iteratorRecord.[[done]] is false, let result be @@ -26,7 +27,7 @@ flags: [async] var error = new Test262Error(); Object.defineProperty(Promise, 'resolve', { - get: function() { + get: function() { throw error; } }); diff --git a/test/built-ins/Promise/all/invoke-then-error-close.js b/test/built-ins/Promise/all/invoke-then-error-close.js new file mode 100644 index 0000000000..6786b31883 --- /dev/null +++ b/test/built-ins/Promise/all/invoke-then-error-close.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: > + Error thrown when invoking the instance's `then` method (closing iterator) +esid: sec-performpromiseall +es6id: 25.4.4.1 +info: | + 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + 12. If result is an abrupt completion, + a. If iteratorRecord.[[done]] is false, let result be + IteratorClose(iterator, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + [...] + + 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + + [...] + 6. Repeat + [...] + r. Let result be Invoke(nextPromise, "then", «resolveElement, + resultCapability.[[Reject]]»). + s. ReturnIfAbrupt(result). +features: [Symbol.iterator] +---*/ + +var promise = new Promise(function() {}); +var returnCount = 0; +var iter = {}; +iter[Symbol.iterator] = function() { + return { + next: function() { + return { done: false, value: promise }; + }, + return: function() { + returnCount += 1; + return {}; + } + }; +}; + +promise.then = function() { + throw new Test262Error(); +}; + +Promise.all(iter); + +assert.sameValue(returnCount, 1); diff --git a/test/built-ins/Promise/all/invoke-then-error.js b/test/built-ins/Promise/all/invoke-then-error-reject.js similarity index 90% rename from test/built-ins/Promise/all/invoke-then-error.js rename to test/built-ins/Promise/all/invoke-then-error-reject.js index a3fef19b00..c50096946a 100644 --- a/test/built-ins/Promise/all/invoke-then-error.js +++ b/test/built-ins/Promise/all/invoke-then-error-reject.js @@ -3,9 +3,10 @@ /*--- description: > - Error thrown when invoking the instance's `then` method + Error thrown when invoking the instance's `then` method (rejecting Promise) +esid: sec-performpromiseall es6id: 25.4.4.1 -info: > +info: | 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). 12. If result is an abrupt completion, a. If iteratorRecord.[[done]] is false, let result be diff --git a/test/built-ins/Promise/all/invoke-then-get-error-close.js b/test/built-ins/Promise/all/invoke-then-get-error-close.js new file mode 100644 index 0000000000..a200b752a5 --- /dev/null +++ b/test/built-ins/Promise/all/invoke-then-get-error-close.js @@ -0,0 +1,51 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: > + Error thrown when accesing the instance's `then` method (closing iterator) +esid: sec-performpromiseall +es6id: 25.4.4.1 +info: | + 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + 12. If result is an abrupt completion, + a. If iteratorRecord.[[done]] is false, let result be + IteratorClose(iterator, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + [...] + + 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + + [...] + 6. Repeat + [...] + r. Let result be Invoke(nextPromise, "then", «resolveElement, + resultCapability.[[Reject]]»). + s. ReturnIfAbrupt(result). +features: [Symbol.iterator] +---*/ + +var promise = new Promise(function() {}); +var returnCount = 0; +var iter = {}; +iter[Symbol.iterator] = function() { + return { + next: function() { + return { done: false, value: promise }; + }, + return: function() { + returnCount += 1; + return {}; + } + }; +}; + +Object.defineProperty(promise, 'then', { + get: function() { + throw new Test262Error(); + } +}); + +Promise.all(iter); + +assert.sameValue(returnCount, 1); diff --git a/test/built-ins/Promise/all/invoke-then-get-error-reject.js b/test/built-ins/Promise/all/invoke-then-get-error-reject.js new file mode 100644 index 0000000000..62cdba244d --- /dev/null +++ b/test/built-ins/Promise/all/invoke-then-get-error-reject.js @@ -0,0 +1,41 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: > + Error thrown when accessing the instance's `then` method (rejecting Promise) +esid: sec-performpromiseall +es6id: 25.4.4.1 +info: | + 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + 12. If result is an abrupt completion, + a. If iteratorRecord.[[done]] is false, let result be + IteratorClose(iterator, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + [...] + + 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + + [...] + 6. Repeat + [...] + r. Let result be Invoke(nextPromise, "then", «resolveElement, + resultCapability.[[Reject]]»). + s. ReturnIfAbrupt(result). +flags: [async] +---*/ + +var promise = new Promise(function() {}); +var error = new Test262Error(); + +Object.defineProperty(promise, 'then', { + get: function() { + throw error; + } +}); + +Promise.all([promise]).then(function() { + $ERROR('The promise should be rejected'); +}, function(reason) { + assert.sameValue(reason, error); +}).then($DONE, $DONE); diff --git a/test/built-ins/Promise/all/iter-next-val-err-no-close.js b/test/built-ins/Promise/all/iter-next-val-err-no-close.js new file mode 100644 index 0000000000..bd2aed5224 --- /dev/null +++ b/test/built-ins/Promise/all/iter-next-val-err-no-close.js @@ -0,0 +1,56 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +es6id: 25.4.4.1 +description: > + Error when accessing an iterator result's `value` property (not closing + iterator) +info: | + 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + 12. If result is an abrupt completion, + a. If iteratorRecord.[[done]] is false, let result be + IteratorClose(iterator, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + [...] + + 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + + [...] + 6. Repeat + [...] + e. Let nextValue be IteratorValue(next). + f. If nextValue is an abrupt completion, set iteratorRecord.[[done]] to + true. + g. ReturnIfAbrupt(nextValue). +features: [Symbol.iterator] +---*/ + +var iterNextValThrows = {}; +var returnCount = 0; +var poisonedVal = { + done: false +}; +var error = new Test262Error(); +Object.defineProperty(poisonedVal, 'value', { + get: function() { + throw error; + } +}); +iterNextValThrows[Symbol.iterator] = function() { + return { + next: function() { + return poisonedVal; + }, + return: function() { + returnCount += 1; + return {}; + } + }; +}; + +Promise.all(iterNextValThrows); + +assert.sameValue(returnCount, 0); diff --git a/test/built-ins/Promise/all/iter-next-val-err.js b/test/built-ins/Promise/all/iter-next-val-err-reject.js similarity index 91% rename from test/built-ins/Promise/all/iter-next-val-err.js rename to test/built-ins/Promise/all/iter-next-val-err-reject.js index 20a4d8f8e2..811b19923b 100644 --- a/test/built-ins/Promise/all/iter-next-val-err.js +++ b/test/built-ins/Promise/all/iter-next-val-err-reject.js @@ -2,10 +2,12 @@ // This code is governed by the BSD license found in the LICENSE file. /*--- -description: > - Error when accessing an iterator result's `value` property +esid: sec-promise.all es6id: 25.4.4.1 -info: > +description: > + Error when accessing an iterator result's `value` property (rejecting + promise) +info: | 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). 12. If result is an abrupt completion, a. If iteratorRecord.[[done]] is false, let result be diff --git a/test/built-ins/Promise/all/iter-step-err-no-close.js b/test/built-ins/Promise/all/iter-step-err-no-close.js new file mode 100644 index 0000000000..e288093ac1 --- /dev/null +++ b/test/built-ins/Promise/all/iter-step-err-no-close.js @@ -0,0 +1,58 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +es6id: 25.4.4.1 +description: > + Error when advancing the provided iterable (not closing iterator) +info: | + 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + 12. If result is an abrupt completion, + a. If iteratorRecord.[[done]] is false, let result be + IteratorClose(iterator, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + [...] + + 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + + [...] + 6. Repeat + a. Let next be IteratorStep(iteratorRecord.[[iterator]]). + b. If next is an abrupt completion, set iteratorRecord.[[done]] to + true. + c. ReturnIfAbrupt(next). +features: [Symbol.iterator] +---*/ + +var iterStepThrows = {}; +var poisonedDone = {}; +var returnCount = 0; +var error = new Test262Error(); +Object.defineProperty(poisonedDone, 'done', { + get: function() { + throw error; + } +}); +Object.defineProperty(poisonedDone, 'value', { + get: function() { + $ERROR('The `value` property should not be accessed.'); + } +}); + +iterStepThrows[Symbol.iterator] = function() { + return { + next: function() { + return poisonedDone; + }, + return: function() { + returnCount += 1; + return {}; + } + }; +}; + +Promise.all(iterStepThrows); + +assert.sameValue(returnCount, 0); diff --git a/test/built-ins/Promise/all/iter-step-err.js b/test/built-ins/Promise/all/iter-step-err-reject.js similarity index 93% rename from test/built-ins/Promise/all/iter-step-err.js rename to test/built-ins/Promise/all/iter-step-err-reject.js index 9ef1430b88..a100ef0bbb 100644 --- a/test/built-ins/Promise/all/iter-step-err.js +++ b/test/built-ins/Promise/all/iter-step-err-reject.js @@ -2,10 +2,11 @@ // This code is governed by the BSD license found in the LICENSE file. /*--- -description: > - Error when advancing the provided iterable +esid: sec-promise.all es6id: 25.4.4.1 -info: > +description: > + Error when advancing the provided iterable (rejecting promise) +info: | 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). 12. If result is an abrupt completion, a. If iteratorRecord.[[done]] is false, let result be diff --git a/test/built-ins/Promise/race/invoke-resolve-error-close.js b/test/built-ins/Promise/race/invoke-resolve-error-close.js new file mode 100644 index 0000000000..36651be4e6 --- /dev/null +++ b/test/built-ins/Promise/race/invoke-resolve-error-close.js @@ -0,0 +1,47 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Explicit iterator closing in response to error from `Promise.resolve` +esid: sec-promise.race +es6id: 25.4.4.3 +info: | + [...] + 11. Let result be PerformPromiseRace(iteratorRecord, promiseCapability, C). + 12. If result is an abrupt completion, then + a. If iteratorRecord.[[done]] is false, let result be + IteratorClose(iterator,result). + b. IfAbruptRejectPromise(result, promiseCapability). + + + 25.4.4.3.1 Runtime Semantics: PerformPromiseRace + + 1. Repeat + [...] + h. Let nextPromise be Invoke(C, "resolve", «nextValue»). + i. ReturnIfAbrupt(nextPromise). +features: [Symbol.iterator] +---*/ + +var iterDoneSpy = {}; +var returnCount = 0; +iterDoneSpy[Symbol.iterator] = function() { + return { + next: function() { + return { value: null, done: false }; + }, + return: function() { + returnCount += 1; + return {}; + } + }; +}; + +Promise.resolve = function() { + throw err; +}; + +Promise.race(iterDoneSpy); + +assert.sameValue(returnCount, 1); diff --git a/test/built-ins/Promise/race/iter-close.js b/test/built-ins/Promise/race/invoke-resolve-error-reject.js similarity index 70% rename from test/built-ins/Promise/race/iter-close.js rename to test/built-ins/Promise/race/invoke-resolve-error-reject.js index f66dc68c3c..71fd31f9e0 100644 --- a/test/built-ins/Promise/race/iter-close.js +++ b/test/built-ins/Promise/race/invoke-resolve-error-reject.js @@ -2,10 +2,11 @@ // This code is governed by the BSD license found in the LICENSE file. /*--- -description: > - Explicit iterator closing in response to error +description: Promise rejection in response to error from `Promise.resolve` +esid: sec-promise.race es6id: 25.4.4.3 -info: > +info: | + [...] 11. Let result be PerformPromiseRace(iteratorRecord, promiseCapability, C). 12. If result is an abrupt completion, then a. If iteratorRecord.[[done]] is false, let result be @@ -19,37 +20,22 @@ info: > [...] h. Let nextPromise be Invoke(C, "resolve", «nextValue»). i. ReturnIfAbrupt(nextPromise). -features: [Symbol.iterator] flags: [async] ---*/ var err = new Test262Error(); -var iterDoneSpy = {}; -var callCount = 0; var CustomPromise = function(executor) { return new Promise(executor); }; -iterDoneSpy[Symbol.iterator] = function() { - return { - next: function() { - return { value: null, done: false }; - }, - return: function() { - callCount += 1; - } - }; -}; CustomPromise.resolve = function() { throw err; }; -Promise.race.call(CustomPromise, iterDoneSpy) +Promise.race.call(CustomPromise, [1]) .then(function() { $ERROR('The promise should be rejected.'); }, function(reason) { assert.sameValue(reason, err); $DONE(); }); - -assert.sameValue(callCount, 1); diff --git a/test/built-ins/Promise/race/invoke-resolve-get-error-close.js b/test/built-ins/Promise/race/invoke-resolve-get-error-close.js new file mode 100644 index 0000000000..d2958b5b37 --- /dev/null +++ b/test/built-ins/Promise/race/invoke-resolve-get-error-close.js @@ -0,0 +1,48 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Error retrieving the constructor's `resolve` method (iterator closing) +esid: sec-promise.race +es6id: 25.4.4.3 +info: | + 11. Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability). + 12. If result is an abrupt completion, + a. If iteratorRecord.[[done]] is false, let result be + IteratorClose(iterator, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + [...] + + 25.4.4.3.1 Runtime Semantics: PerformPromiseRace + + 1. Repeat + [...] + h. Let nextPromise be Invoke(C, "resolve", «nextValue»). + i. ReturnIfAbrupt(nextPromise). +features: [Symbol.iterator] +---*/ + +var iter = {}; +var returnCount = 0; +iter[Symbol.iterator] = function() { + return { + next: function() { + return { done: false }; + }, + return: function() { + returnCount += 1; + return {}; + } + }; +}; +Object.defineProperty(Promise, 'resolve', { + get: function() { + throw new Test262Error(); + } +}); + +Promise.race(iter); + +assert.sameValue(returnCount, 1); diff --git a/test/built-ins/Promise/race/invoke-resolve-get-error.js b/test/built-ins/Promise/race/invoke-resolve-get-error-reject.js similarity index 88% rename from test/built-ins/Promise/race/invoke-resolve-get-error.js rename to test/built-ins/Promise/race/invoke-resolve-get-error-reject.js index 9fa2dc6ad4..0aa6f45b5d 100644 --- a/test/built-ins/Promise/race/invoke-resolve-get-error.js +++ b/test/built-ins/Promise/race/invoke-resolve-get-error-reject.js @@ -3,9 +3,10 @@ /*--- description: > - Error retrieving the constructor's `resolve` method + Error retrieving the constructor's `resolve` method (promise rejection) +esid: sec-promise.race es6id: 25.4.4.3 -info: > +info: | 11. Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability). 12. If result is an abrupt completion, a. If iteratorRecord.[[done]] is false, let result be @@ -25,7 +26,7 @@ flags: [async] var error = new Test262Error(); Object.defineProperty(Promise, 'resolve', { - get: function() { + get: function() { throw error; } }); diff --git a/test/built-ins/Promise/race/invoke-then-error-close.js b/test/built-ins/Promise/race/invoke-then-error-close.js new file mode 100644 index 0000000000..a9df84f499 --- /dev/null +++ b/test/built-ins/Promise/race/invoke-then-error-close.js @@ -0,0 +1,48 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Error thrown when invoking the instance's `then` method (closing iterator) +esid: sec-promise.race +es6id: 25.4.4.3 +info: | + 11. Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability). + 12. If result is an abrupt completion, + a. If iteratorRecord.[[done]] is false, let result be + IteratorClose(iterator, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + [...] + + 25.4.4.3.1 Runtime Semantics: PerformPromiseRace + + 1. Repeat + [...] + j. Let result be Invoke(nextPromise, "then", + «promiseCapability.[[Resolve]], promiseCapability.[[Reject]]»). + k. ReturnIfAbrupt(result). +features: [Symbol.iterator] +---*/ + +var promise = new Promise(function() {}); +var iter = {}; +var returnCount = 0; +iter[Symbol.iterator] = function() { + return { + next: function() { + return { done: false, value: promise }; + }, + return: function() { + returnCount += 1; + return {}; + } + }; +}; +promise.then = function() { + throw new Test262Error(); +}; + +Promise.race(iter); + +assert.sameValue(returnCount, 1); diff --git a/test/built-ins/Promise/race/invoke-then-error.js b/test/built-ins/Promise/race/invoke-then-error-reject.js similarity index 90% rename from test/built-ins/Promise/race/invoke-then-error.js rename to test/built-ins/Promise/race/invoke-then-error-reject.js index 184e3ea5b1..65209d4194 100644 --- a/test/built-ins/Promise/race/invoke-then-error.js +++ b/test/built-ins/Promise/race/invoke-then-error-reject.js @@ -3,9 +3,10 @@ /*--- description: > - Error thrown when invoking the instance's `then` method + Error thrown when invoking the instance's `then` method (rejecting promise) +esid: sec-promise.race es6id: 25.4.4.3 -info: > +info: | 11. Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability). 12. If result is an abrupt completion, a. If iteratorRecord.[[done]] is false, let result be diff --git a/test/built-ins/Promise/race/invoke-then-get-error-close.js b/test/built-ins/Promise/race/invoke-then-get-error-close.js new file mode 100644 index 0000000000..93f095ee20 --- /dev/null +++ b/test/built-ins/Promise/race/invoke-then-get-error-close.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: > + Error thrown when accessing the instance's `then` method (closing iterator) +esid: sec-promise.race +es6id: 25.4.4.3 +info: | + 11. Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability). + 12. If result is an abrupt completion, + a. If iteratorRecord.[[done]] is false, let result be + IteratorClose(iterator, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + [...] + + 25.4.4.3.1 Runtime Semantics: PerformPromiseRace + + 1. Repeat + [...] + j. Let result be Invoke(nextPromise, "then", + «promiseCapability.[[Resolve]], promiseCapability.[[Reject]]»). + k. ReturnIfAbrupt(result). +features: [Symbol.iterator] +---*/ + +var promise = new Promise(function() {}); +var iter = {}; +var returnCount = 0; +iter[Symbol.iterator] = function() { + return { + next: function() { + return { done: false, value: promise }; + }, + return: function() { + returnCount += 1; + return {}; + } + }; +}; +Object.defineProperty(promise, 'then', { + get: function() { + throw new Test262Error(); + } +}); + +Promise.race(iter); + +assert.sameValue(returnCount, 1); diff --git a/test/built-ins/Promise/race/invoke-then-get-error-reject.js b/test/built-ins/Promise/race/invoke-then-get-error-reject.js new file mode 100644 index 0000000000..90be42920d --- /dev/null +++ b/test/built-ins/Promise/race/invoke-then-get-error-reject.js @@ -0,0 +1,40 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: > + Error thrown when accessing the instance's `then` method (rejecting promise) +esid: sec-promise.race +es6id: 25.4.4.3 +info: | + 11. Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability). + 12. If result is an abrupt completion, + a. If iteratorRecord.[[done]] is false, let result be + IteratorClose(iterator, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + [...] + + 25.4.4.3.1 Runtime Semantics: PerformPromiseRace + + 1. Repeat + [...] + j. Let result be Invoke(nextPromise, "then", + «promiseCapability.[[Resolve]], promiseCapability.[[Reject]]»). + k. ReturnIfAbrupt(result). +flags: [async] +---*/ + +var promise = new Promise(function() {}); +var error = new Test262Error(); + +Object.defineProperty(promise, 'then', { + get: function() { + throw error; + } +}); + +Promise.race([promise]).then(function() { + $ERROR('The promise should be rejected'); +}, function(reason) { + assert.sameValue(reason, error); +}).then($DONE, $DONE); diff --git a/test/built-ins/Promise/race/iter-next-val-err-no-close.js b/test/built-ins/Promise/race/iter-next-val-err-no-close.js new file mode 100644 index 0000000000..ddd2e6cec9 --- /dev/null +++ b/test/built-ins/Promise/race/iter-next-val-err-no-close.js @@ -0,0 +1,54 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Error when accessing an iterator result's `value` property (not closing + iterator) +esid: sec-promise.race +es6id: 25.4.4.3 +info: | + 11. Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability). + 12. If result is an abrupt completion, + a. If iteratorRecord.[[done]] is false, let result be + IteratorClose(iterator, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + [...] + + 25.4.4.3.1 Runtime Semantics: PerformPromiseRace + + 1. Repeat + [...] + e. Let nextValue be IteratorValue(next). + f. If nextValue is an abrupt completion, set iteratorRecord.[[done]] to + true. + g. ReturnIfAbrupt(nextValue). +features: [Symbol.iterator] +---*/ + +var iterNextValThrows = {}; +var returnCount = 0; +var poisonedVal = { + done: false +}; +var error = new Test262Error(); +Object.defineProperty(poisonedVal, 'value', { + get: function() { + throw error; + } +}); +iterNextValThrows[Symbol.iterator] = function() { + return { + next: function() { + return poisonedVal; + }, + return: function() { + returnCount += 1; + } + }; +}; + +Promise.race(iterNextValThrows); + +assert.sameValue(returnCount, 0); diff --git a/test/built-ins/Promise/race/iter-next-val-err.js b/test/built-ins/Promise/race/iter-next-val-err-reject.js similarity index 91% rename from test/built-ins/Promise/race/iter-next-val-err.js rename to test/built-ins/Promise/race/iter-next-val-err-reject.js index dfa2177a97..e5cdcdf788 100644 --- a/test/built-ins/Promise/race/iter-next-val-err.js +++ b/test/built-ins/Promise/race/iter-next-val-err-reject.js @@ -3,9 +3,11 @@ /*--- description: > - Error when accessing an iterator result's `value` property + Error when accessing an iterator result's `value` property (rejecting + promise) +esid: sec-promise.race es6id: 25.4.4.3 -info: > +info: | 11. Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability). 12. If result is an abrupt completion, a. If iteratorRecord.[[done]] is false, let result be diff --git a/test/built-ins/Promise/race/iter-step-err-no-close.js b/test/built-ins/Promise/race/iter-step-err-no-close.js new file mode 100644 index 0000000000..625325f390 --- /dev/null +++ b/test/built-ins/Promise/race/iter-step-err-no-close.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: > + Error when advancing the provided iterable (not closing iterator) +esid: sec-promise.race +es6id: 25.4.4.3 +info: | + [...] + 11. Let result be PerformPromiseRace(iteratorRecord, promiseCapability, C). + 12. If result is an abrupt completion, then + a. If iteratorRecord.[[done]] is false, let result be + IteratorClose(iterator,result). + b. IfAbruptRejectPromise(result, promiseCapability). + + 25.4.4.3.1 Runtime Semantics: PerformPromiseRace + 1. Repeat + a. Let next be IteratorStep(iteratorRecord.[[iterator]]). + b. If next is an abrupt completion, set iteratorRecord.[[done]] to true. + c. ReturnIfAbrupt(next). +features: [Symbol.iterator] +---*/ + +var iterStepThrows = {}; +var poisonedDone = {}; +var returnCount = 0; +var error = new Test262Error(); +Object.defineProperty(poisonedDone, 'done', { + get: function() { + throw error; + } +}); +Object.defineProperty(poisonedDone, 'value', { + get: function() { + $ERROR('The `value` property should not be accessed.'); + } +}); + +iterStepThrows[Symbol.iterator] = function() { + return { + next: function() { + return poisonedDone; + }, + return: function() { + returnCount += 1; + } + }; +}; + +Promise.race(iterStepThrows); + +assert.sameValue(returnCount, 0); diff --git a/test/built-ins/Promise/race/iter-step-err.js b/test/built-ins/Promise/race/iter-step-err-reject.js similarity index 93% rename from test/built-ins/Promise/race/iter-step-err.js rename to test/built-ins/Promise/race/iter-step-err-reject.js index d7dfd34d31..6f848b0862 100644 --- a/test/built-ins/Promise/race/iter-step-err.js +++ b/test/built-ins/Promise/race/iter-step-err-reject.js @@ -3,9 +3,10 @@ /*--- description: > - Error when advancing the provided iterable + Error when advancing the provided iterable (rejecting promise) +esid: sec-promise.race es6id: 25.4.4.3 -info: > +info: | [...] 11. Let result be PerformPromiseRace(iteratorRecord, promiseCapability, C). 12. If result is an abrupt completion, then