diff --git a/test/built-ins/Promise/all/capability-executor-called-twice.js b/test/built-ins/Promise/all/capability-executor-called-twice.js index 7f9427dbca..24a1b223bd 100644 --- a/test/built-ins/Promise/all/capability-executor-called-twice.js +++ b/test/built-ins/Promise/all/capability-executor-called-twice.js @@ -2,7 +2,7 @@ // This code is governed by the BSD license found in the LICENSE file. /*--- -es6id: 25.4.4.1 +esid: sec-promise.all description: > Throws a TypeError if capabilities executor already called with non-undefined values. info: | @@ -13,67 +13,90 @@ info: | 7. ReturnIfAbrupt(promiseCapability). ... - 25.4.1.5.1 GetCapabilitiesExecutor Functions + GetCapabilitiesExecutor Functions ... 3. If promiseCapability.[[Resolve]] is not undefined, throw a TypeError exception. 4. If promiseCapability.[[Reject]] is not undefined, throw a TypeError exception. 5. Set promiseCapability.[[Resolve]] to resolve. 6. Set promiseCapability.[[Reject]] to reject. ... + + PerformPromiseAll ( iteratorRecord, constructor, resultCapability ) + + ... + 1. Let promiseResolve be ? Get(constructor, `"resolve"`). + 1. If IsCallable(promiseResolve) is *false*, throw a *TypeError* exception. + ... ---*/ var checkPoint = ""; -Promise.all.call(function(executor) { +function fn1(executor) { checkPoint += "a"; executor(); checkPoint += "b"; executor(function() {}, function() {}); checkPoint += "c"; -}, []); +} +fn1.resolve = function() {}; +Promise.all.call(fn1, []); assert.sameValue(checkPoint, "abc", "executor initially called with no arguments"); -var checkPoint = ""; -Promise.all.call(function(executor) { +checkPoint = ""; +function fn2(executor) { checkPoint += "a"; executor(undefined, undefined); checkPoint += "b"; executor(function() {}, function() {}); checkPoint += "c"; -}, []); +} +fn2.resolve = function() {}; +Promise.all.call(fn2, []); assert.sameValue(checkPoint, "abc", "executor initially called with (undefined, undefined)"); -var checkPoint = ""; +checkPoint = ""; +function fn3(executor) { + checkPoint += "a"; + executor(undefined, function() {}); + checkPoint += "b"; + executor(function() {}, function() {}); + checkPoint += "c"; +} +Object.defineProperty(fn3, 'resolve', { + get() { throw new Test262Error; } +}); assert.throws(TypeError, function() { - Promise.all.call(function(executor) { - checkPoint += "a"; - executor(undefined, function() {}); - checkPoint += "b"; - executor(function() {}, function() {}); - checkPoint += "c"; - }, []); + Promise.all.call(fn3, []); }, "executor initially called with (undefined, function)"); assert.sameValue(checkPoint, "ab", "executor initially called with (undefined, function)"); -var checkPoint = ""; +checkPoint = ""; +function fn4(executor) { + checkPoint += "a"; + executor(function() {}, undefined); + checkPoint += "b"; + executor(function() {}, function() {}); + checkPoint += "c"; +} +Object.defineProperty(fn4, 'resolve', { + get() { throw new Test262Error; } +}); assert.throws(TypeError, function() { - Promise.all.call(function(executor) { - checkPoint += "a"; - executor(function() {}, undefined); - checkPoint += "b"; - executor(function() {}, function() {}); - checkPoint += "c"; - }, []); + Promise.all.call(fn4, []); }, "executor initially called with (function, undefined)"); assert.sameValue(checkPoint, "ab", "executor initially called with (function, undefined)"); -var checkPoint = ""; +checkPoint = ""; +function fn5(executor) { + checkPoint += "a"; + executor("invalid value", 123); + checkPoint += "b"; + executor(function() {}, function() {}); + checkPoint += "c"; +} +Object.defineProperty(fn5, 'resolve', { + get() { throw new Test262Error; } +}); assert.throws(TypeError, function() { - Promise.all.call(function(executor) { - checkPoint += "a"; - executor("invalid value", 123); - checkPoint += "b"; - executor(function() {}, function() {}); - checkPoint += "c"; - }, []); + Promise.all.call(fn5, []); }, "executor initially called with (String, Number)"); assert.sameValue(checkPoint, "ab", "executor initially called with (String, Number)"); diff --git a/test/built-ins/Promise/all/capability-executor-not-callable.js b/test/built-ins/Promise/all/capability-executor-not-callable.js index db4092e664..127eb8072b 100644 --- a/test/built-ins/Promise/all/capability-executor-not-callable.js +++ b/test/built-ins/Promise/all/capability-executor-not-callable.js @@ -25,59 +25,83 @@ info: | ---*/ var checkPoint = ""; +function fn1(executor) { + checkPoint += "a"; +} +Object.defineProperty(fn1, 'resolve', { + get() { throw new Test262Error; } +}); assert.throws(TypeError, function() { - Promise.all.call(function(executor) { - checkPoint += "a"; - }, []); + Promise.all.call(fn1, []); }, "executor not called at all"); assert.sameValue(checkPoint, "a", "executor not called at all"); -var checkPoint = ""; +checkPoint = ""; +function fn2(executor) { + checkPoint += "a"; + executor(); + checkPoint += "b"; +} +Object.defineProperty(fn2, 'resolve', { + get() { throw new Test262Error; } +}); assert.throws(TypeError, function() { - Promise.all.call(function(executor) { - checkPoint += "a"; - executor(); - checkPoint += "b"; - }, []); + Promise.all.call(fn2, []); }, "executor called with no arguments"); assert.sameValue(checkPoint, "ab", "executor called with no arguments"); -var checkPoint = ""; +checkPoint = ""; +function fn3(executor) { + checkPoint += "a"; + executor(undefined, undefined); + checkPoint += "b"; +} +Object.defineProperty(fn3, 'resolve', { + get() { throw new Test262Error; } +}); assert.throws(TypeError, function() { - Promise.all.call(function(executor) { - checkPoint += "a"; - executor(undefined, undefined); - checkPoint += "b"; - }, []); + Promise.all.call(fn3, []); }, "executor called with (undefined, undefined)"); assert.sameValue(checkPoint, "ab", "executor called with (undefined, undefined)"); -var checkPoint = ""; +checkPoint = ""; +function fn4(executor) { + checkPoint += "a"; + executor(undefined, function() {}); + checkPoint += "b"; +} +Object.defineProperty(fn4, 'resolve', { + get() { throw new Test262Error; } +}); assert.throws(TypeError, function() { - Promise.all.call(function(executor) { - checkPoint += "a"; - executor(undefined, function() {}); - checkPoint += "b"; - }, []); + Promise.all.call(fn4, []); }, "executor called with (undefined, function)"); assert.sameValue(checkPoint, "ab", "executor called with (undefined, function)"); -var checkPoint = ""; +checkPoint = ""; +function fn5(executor) { + checkPoint += "a"; + executor(function() {}, undefined); + checkPoint += "b"; +} +Object.defineProperty(fn5, 'resolve', { + get() { throw new Test262Error; } +}); assert.throws(TypeError, function() { - Promise.all.call(function(executor) { - checkPoint += "a"; - executor(function() {}, undefined); - checkPoint += "b"; - }, []); + Promise.all.call(fn5, []); }, "executor called with (function, undefined)"); assert.sameValue(checkPoint, "ab", "executor called with (function, undefined)"); -var checkPoint = ""; +checkPoint = ""; +function fn6(executor) { + checkPoint += "a"; + executor(123, "invalid value"); + checkPoint += "b"; +} +Object.defineProperty(fn6, 'resolve', { + get() { throw new Test262Error; } +}); assert.throws(TypeError, function() { - Promise.all.call(function(executor) { - checkPoint += "a"; - executor(123, "invalid value"); - checkPoint += "b"; - }, []); + Promise.all.call(fn6, []); }, "executor called with (Number, String)"); assert.sameValue(checkPoint, "ab", "executor called with (Number, String)"); diff --git a/test/built-ins/Promise/all/capability-resolve-throws-no-close.js b/test/built-ins/Promise/all/capability-resolve-throws-no-close.js index 390bf8d253..4429ae26cc 100644 --- a/test/built-ins/Promise/all/capability-resolve-throws-no-close.js +++ b/test/built-ins/Promise/all/capability-resolve-throws-no-close.js @@ -45,11 +45,13 @@ info: | features: [Symbol.iterator] ---*/ +var nextCount = 0; var returnCount = 0; var iter = {}; iter[Symbol.iterator] = function() { return { next: function() { + nextCount += 1; return { done: true }; @@ -68,6 +70,9 @@ var P = function(executor) { }); }; +P.resolve = Promise.resolve; + Promise.all.call(P, iter); +assert.sameValue(nextCount, 1); assert.sameValue(returnCount, 0); diff --git a/test/built-ins/Promise/all/capability-resolve-throws-reject.js b/test/built-ins/Promise/all/capability-resolve-throws-reject.js index 57f3e27558..e4260a4cf0 100644 --- a/test/built-ins/Promise/all/capability-resolve-throws-reject.js +++ b/test/built-ins/Promise/all/capability-resolve-throws-reject.js @@ -54,6 +54,8 @@ var P = function(executor) { }); }; +P.resolve = Promise.resolve; + Promise.all.call(P, []) .then(function() { $DONE('Promise incorrectly fulfilled.'); diff --git a/test/built-ins/Promise/all/invoke-resolve-error-close.js b/test/built-ins/Promise/all/invoke-resolve-error-close.js index aead2b6477..b46e66d49f 100644 --- a/test/built-ins/Promise/all/invoke-resolve-error-close.js +++ b/test/built-ins/Promise/all/invoke-resolve-error-close.js @@ -42,7 +42,7 @@ iterDoneSpy[Symbol.iterator] = function() { }; Promise.resolve = function() { - throw new Error(); + throw new Test262Error(); }; Promise.all(iterDoneSpy); 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 index 22e75e0df4..ac1bb2966b 100644 --- a/test/built-ins/Promise/all/invoke-resolve-get-error-close.js +++ b/test/built-ins/Promise/all/invoke-resolve-get-error-close.js @@ -3,9 +3,8 @@ /*--- description: > - Error retrieving the constructor's `resolve` method (closing iterator) + Error retrieving the constructor's `resolve` method before iterator being used. esid: sec-performpromiseall -es6id: 25.4.4.1 info: | 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). 12. If result is an abrupt completion, @@ -13,23 +12,29 @@ info: | IteratorClose(iterator, result). b. IfAbruptRejectPromise(result, promiseCapability). - [...] + ... - 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + Runtime Semantics: PerformPromiseAll - [...] - 6. Repeat - [...] - i. Let nextPromise be Invoke(constructor, "resolve", «nextValue»). - j. ReturnIfAbrupt(nextPromise ). + ... + 1. Let promiseResolve be ? Get(constructor, `"resolve"`). + ... + 1. Repeat, + 1. Let next be IteratorStep(iteratorRecord). + ... + 1. Let nextPromise be ? Call(promiseResolve, constructor, < nextValue >). features: [Symbol.iterator] ---*/ var iter = {}; + var returnCount = 0; +var nextCount = 0; + iter[Symbol.iterator] = function() { return { next: function() { + nextCount += 1; return { done: false }; @@ -41,11 +46,12 @@ iter[Symbol.iterator] = function() { }; }; Object.defineProperty(Promise, 'resolve', { - get: function() { + get() { throw new Test262Error(); } }); Promise.all(iter); -assert.sameValue(returnCount, 1); +assert.sameValue(nextCount, 0); +assert.sameValue(returnCount, 0); diff --git a/test/built-ins/Promise/all/invoke-resolve-get-error-reject.js b/test/built-ins/Promise/all/invoke-resolve-get-error-reject.js index d03378253d..06e9ae11f4 100644 --- a/test/built-ins/Promise/all/invoke-resolve-get-error-reject.js +++ b/test/built-ins/Promise/all/invoke-resolve-get-error-reject.js @@ -15,13 +15,15 @@ info: | [...] - 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + Runtime Semantics: PerformPromiseAll - [...] - 6. Repeat - [...] - i. Let nextPromise be Invoke(constructor, "resolve", «nextValue»). - j. ReturnIfAbrupt(nextPromise ). + ... + 1. Let promiseResolve be ? Get(constructor, `"resolve"`). + ... + 1. Repeat, + 1. Let next be IteratorStep(iteratorRecord). + ... + 1. Let nextPromise be ? Call(promiseResolve, constructor, < nextValue >). flags: [async] ---*/ diff --git a/test/built-ins/Promise/all/invoke-resolve-get-once-multiple-calls.js b/test/built-ins/Promise/all/invoke-resolve-get-once-multiple-calls.js new file mode 100644 index 0000000000..4358ff5296 --- /dev/null +++ b/test/built-ins/Promise/all/invoke-resolve-get-once-multiple-calls.js @@ -0,0 +1,45 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Gets constructor's `resolve` method once from zero to many invocations. +esid: sec-promise.all +info: | + Runtime Semantics: PerformPromiseAll + + 1. Let promiseResolve be ? Get(constructor, `"resolve"`). + 1. If IsCallable(promiseResolve) is false, throw a TypeError exception. + ... + 1. Repeat, + ... + 1. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »). +---*/ + +var p1 = Promise.resolve(1); +var p2 = Promise.resolve(1); +var p3 = Promise.reject(1); +var p4 = Promise.resolve(1); +var resolve = Promise.resolve; +var getCount = 0; +var callCount = 0; + +Object.defineProperty(Promise, 'resolve', { + configurable: true, + get() { + getCount += 1; + return function() { + callCount += 1; + return resolve.apply(Promise, arguments); + }; + } +}); + +Promise.all([p1, p2, p3, p4]); + +assert.sameValue( + getCount, 1, 'Got `resolve` only once for each iterated value' +); +assert.sameValue( + callCount, 4, '`resolve` invoked once for each iterated value' +); diff --git a/test/built-ins/Promise/all/invoke-resolve-get-once-no-calls.js b/test/built-ins/Promise/all/invoke-resolve-get-once-no-calls.js new file mode 100644 index 0000000000..36f7fc7c21 --- /dev/null +++ b/test/built-ins/Promise/all/invoke-resolve-get-once-no-calls.js @@ -0,0 +1,42 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Gets constructor's `resolve` method once from zero to many invocations. +esid: sec-promise.allsettled +info: | + Runtime Semantics: PerformPromiseAll + + 1. Let promiseResolve be ? Get(constructor, `"resolve"`). + 1. If IsCallable(promiseResolve) is false, throw a TypeError exception. + ... + 1. Repeat, + ... + 1. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »). +features: [Promise.allSettled] +---*/ + +var resolve = Promise.resolve; +var getCount = 0; +var callCount = 0; + +Object.defineProperty(Promise, 'resolve', { + configurable: true, + get() { + getCount += 1; + return function() { + callCount += 1; + return resolve.apply(Promise, arguments); + }; + } +}); + +Promise.all([]); + +assert.sameValue( + getCount, 1, 'Got `resolve` only once for each iterated value' +); +assert.sameValue( + callCount, 0, '`resolve` not called for empty iterator' +); diff --git a/test/built-ins/Promise/all/species-get-error.js b/test/built-ins/Promise/all/species-get-error.js index 43ed463d6c..f672d50120 100644 --- a/test/built-ins/Promise/all/species-get-error.js +++ b/test/built-ins/Promise/all/species-get-error.js @@ -16,6 +16,8 @@ features: [Symbol.species] function C(executor) { executor(function() {}, function() {}); } + +C.resolve = function() {}; Object.defineProperty(C, Symbol.species, { get: function() { $ERROR("Getter for Symbol.species called"); diff --git a/test/built-ins/Promise/allSettled/capability-executor-called-twice.js b/test/built-ins/Promise/allSettled/capability-executor-called-twice.js index 5212bf0c0e..b537d660d8 100644 --- a/test/built-ins/Promise/allSettled/capability-executor-called-twice.js +++ b/test/built-ins/Promise/allSettled/capability-executor-called-twice.js @@ -24,57 +24,83 @@ features: [Promise.allSettled] ---*/ var checkPoint = ''; -Promise.allSettled.call(function(executor) { +function fn1(executor) { checkPoint += 'a'; executor(); checkPoint += 'b'; executor(function() {}, function() {}); checkPoint += 'c'; -}, []); +} +fn1.resolve = function() { + throw new Test262Error(); +}; +Promise.allSettled.call(fn1, []); assert.sameValue(checkPoint, 'abc', 'executor initially called with no arguments'); -var checkPoint = ''; -Promise.allSettled.call(function(executor) { +checkPoint = ''; +function fn2(executor) { checkPoint += 'a'; executor(undefined, undefined); checkPoint += 'b'; executor(function() {}, function() {}); checkPoint += 'c'; -}, []); +} +fn2.resolve = function() { + throw new Test262Error(); +}; +Promise.allSettled.call(fn2, []); assert.sameValue(checkPoint, 'abc', 'executor initially called with (undefined, undefined)'); -var checkPoint = ''; +checkPoint = ''; +function fn3(executor) { + checkPoint += 'a'; + executor(undefined, function() {}); + checkPoint += 'b'; + executor(function() {}, function() {}); + checkPoint += 'c'; +} +Object.defineProperty(fn3, 'resolve', { + get() { + throw new Test262Error(); + } +}); assert.throws(TypeError, function() { - Promise.allSettled.call(function(executor) { - checkPoint += 'a'; - executor(undefined, function() {}); - checkPoint += 'b'; - executor(function() {}, function() {}); - checkPoint += 'c'; - }, []); + Promise.allSettled.call(fn3, []); }, 'executor initially called with (undefined, function)'); assert.sameValue(checkPoint, 'ab', 'executor initially called with (undefined, function)'); -var checkPoint = ''; +checkPoint = ''; +function fn4(executor) { + checkPoint += 'a'; + executor(function() {}, undefined); + checkPoint += 'b'; + executor(function() {}, function() {}); + checkPoint += 'c'; +} +Object.defineProperty(fn4, 'resolve', { + get() { + throw new Test262Error(); + } +}); assert.throws(TypeError, function() { - Promise.allSettled.call(function(executor) { - checkPoint += 'a'; - executor(function() {}, undefined); - checkPoint += 'b'; - executor(function() {}, function() {}); - checkPoint += 'c'; - }, []); + Promise.allSettled.call(fn4, []); }, 'executor initially called with (function, undefined)'); assert.sameValue(checkPoint, 'ab', 'executor initially called with (function, undefined)'); -var checkPoint = ''; +checkPoint = ''; +function fn5(executor) { + checkPoint += 'a'; + executor('invalid value', 123); + checkPoint += 'b'; + executor(function() {}, function() {}); + checkPoint += 'c'; +} +Object.defineProperty(fn5, 'resolve', { + get() { + throw new Test262Error(); + } +}); assert.throws(TypeError, function() { - Promise.allSettled.call(function(executor) { - checkPoint += 'a'; - executor('invalid value', 123); - checkPoint += 'b'; - executor(function() {}, function() {}); - checkPoint += 'c'; - }, []); + Promise.allSettled.call(fn5, []); }, 'executor initially called with (String, Number)'); assert.sameValue(checkPoint, 'ab', 'executor initially called with (String, Number)'); diff --git a/test/built-ins/Promise/allSettled/capability-executor-not-callable.js b/test/built-ins/Promise/allSettled/capability-executor-not-callable.js index 9826c9abe4..719fe215c1 100644 --- a/test/built-ins/Promise/allSettled/capability-executor-not-callable.js +++ b/test/built-ins/Promise/allSettled/capability-executor-not-callable.js @@ -25,59 +25,83 @@ features: [Promise.allSettled] ---*/ var checkPoint = ''; +function fn1(executor) { + checkPoint += 'a'; +} +Object.defineProperty(fn1, 'resolve', { + get() { throw new Test262Error(); } +}); assert.throws(TypeError, function() { - Promise.allSettled.call(function(executor) { - checkPoint += 'a'; - }, []); + Promise.allSettled.call(fn1, []); }, 'executor not called at all'); assert.sameValue(checkPoint, 'a', 'executor not called at all'); -var checkPoint = ''; +checkPoint = ''; +function fn2(executor) { + checkPoint += 'a'; + executor(); + checkPoint += 'b'; +} +Object.defineProperty(fn2, 'resolve', { + get() { throw new Test262Error(); } +}); assert.throws(TypeError, function() { - Promise.allSettled.call(function(executor) { - checkPoint += 'a'; - executor(); - checkPoint += 'b'; - }, []); + Promise.allSettled.call(fn2, []); }, 'executor called with no arguments'); assert.sameValue(checkPoint, 'ab', 'executor called with no arguments'); -var checkPoint = ''; +checkPoint = ''; +function fn3(executor) { + checkPoint += 'a'; + executor(undefined, undefined); + checkPoint += 'b'; +} +Object.defineProperty(fn3, 'resolve', { + get() { throw new Test262Error(); } +}); assert.throws(TypeError, function() { - Promise.allSettled.call(function(executor) { - checkPoint += 'a'; - executor(undefined, undefined); - checkPoint += 'b'; - }, []); + Promise.allSettled.call(fn3, []); }, 'executor called with (undefined, undefined)'); assert.sameValue(checkPoint, 'ab', 'executor called with (undefined, undefined)'); -var checkPoint = ''; +checkPoint = ''; +function fn4(executor) { + checkPoint += 'a'; + executor(undefined, function() {}); + checkPoint += 'b'; +} +Object.defineProperty(fn4, 'resolve', { + get() { throw new Test262Error(); } +}); assert.throws(TypeError, function() { - Promise.allSettled.call(function(executor) { - checkPoint += 'a'; - executor(undefined, function() {}); - checkPoint += 'b'; - }, []); + Promise.allSettled.call(fn4, []); }, 'executor called with (undefined, function)'); assert.sameValue(checkPoint, 'ab', 'executor called with (undefined, function)'); -var checkPoint = ''; +checkPoint = ''; +function fn5(executor) { + checkPoint += 'a'; + executor(function() {}, undefined); + checkPoint += 'b'; +} +Object.defineProperty(fn5, 'resolve', { + get() { throw new Test262Error(); } +}); assert.throws(TypeError, function() { - Promise.allSettled.call(function(executor) { - checkPoint += 'a'; - executor(function() {}, undefined); - checkPoint += 'b'; - }, []); + Promise.allSettled.call(fn5, []); }, 'executor called with (function, undefined)'); assert.sameValue(checkPoint, 'ab', 'executor called with (function, undefined)'); -var checkPoint = ''; +checkPoint = ''; +function fn6(executor) { + checkPoint += 'a'; + executor(123, 'invalid value'); + checkPoint += 'b'; +} +Object.defineProperty(fn6, 'resolve', { + get() { throw new Test262Error(); } +}); assert.throws(TypeError, function() { - Promise.allSettled.call(function(executor) { - checkPoint += 'a'; - executor(123, 'invalid value'); - checkPoint += 'b'; - }, []); + Promise.allSettled.call(fn6, []); }, 'executor called with (Number, String)'); assert.sameValue(checkPoint, 'ab', 'executor called with (Number, String)'); diff --git a/test/built-ins/Promise/allSettled/capability-resolve-throws-no-close.js b/test/built-ins/Promise/allSettled/capability-resolve-throws-no-close.js index 1b6b578db5..75594b1cc8 100644 --- a/test/built-ins/Promise/allSettled/capability-resolve-throws-no-close.js +++ b/test/built-ins/Promise/allSettled/capability-resolve-throws-no-close.js @@ -55,6 +55,10 @@ var P = function(executor) { }); }; +P.resolve = function() { + throw new Test262Error(); +}; + Promise.allSettled.call(P, iter); assert.sameValue(returnCount, 0); diff --git a/test/built-ins/Promise/allSettled/capability-resolve-throws-reject.js b/test/built-ins/Promise/allSettled/capability-resolve-throws-reject.js index ea0e53ea03..681d1d4c72 100644 --- a/test/built-ins/Promise/allSettled/capability-resolve-throws-reject.js +++ b/test/built-ins/Promise/allSettled/capability-resolve-throws-reject.js @@ -43,6 +43,10 @@ var P = function(executor) { }); }; +P.resolve = function() { + throw new Test262Error(); +}; + Promise.allSettled.call(P, []) .then(function() { $DONE('Promise incorrectly fulfilled.'); diff --git a/test/built-ins/Promise/allSettled/invoke-resolve-get-error-close.js b/test/built-ins/Promise/allSettled/invoke-resolve-get-error-close.js index c09fdcd774..f04144a97c 100644 --- a/test/built-ins/Promise/allSettled/invoke-resolve-get-error-close.js +++ b/test/built-ins/Promise/allSettled/invoke-resolve-get-error-close.js @@ -3,7 +3,7 @@ /*--- description: > - Error retrieving the constructor's `resolve` method (closing iterator) + Error retrieving the constructor's `resolve` method not opening iterator esid: sec-promise.allsettled info: | 6. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability). @@ -21,9 +21,11 @@ features: [Promise.allSettled, Symbol.iterator] var iter = {}; var returnCount = 0; +var nextCount = 0; iter[Symbol.iterator] = function() { return { next() { + nextCount += 1; return { done: false }; @@ -42,4 +44,5 @@ Object.defineProperty(Promise, 'resolve', { Promise.allSettled(iter); -assert.sameValue(returnCount, 1); +assert.sameValue(nextCount, 0); +assert.sameValue(returnCount, 0); diff --git a/test/built-ins/Promise/allSettled/species-get-error.js b/test/built-ins/Promise/allSettled/species-get-error.js index 8f003f32d0..6da57a2149 100644 --- a/test/built-ins/Promise/allSettled/species-get-error.js +++ b/test/built-ins/Promise/allSettled/species-get-error.js @@ -22,4 +22,8 @@ Object.defineProperty(C, Symbol.species, { } }); +C.resolve = function() { + throw new Test262Error(); +}; + Promise.allSettled.call(C, []); diff --git a/test/built-ins/Promise/race/capability-executor-called-twice.js b/test/built-ins/Promise/race/capability-executor-called-twice.js index 652f3201cc..f50ea84148 100644 --- a/test/built-ins/Promise/race/capability-executor-called-twice.js +++ b/test/built-ins/Promise/race/capability-executor-called-twice.js @@ -23,57 +23,77 @@ info: | ---*/ var checkPoint = ""; -Promise.race.call(function(executor) { +function fn1(executor) { checkPoint += "a"; executor(); checkPoint += "b"; executor(function() {}, function() {}); checkPoint += "c"; -}, []); +} +fn1.resolve = function() { + throw new Test262Error(); +}; +Promise.race.call(fn1 , []); assert.sameValue(checkPoint, "abc", "executor initially called with no arguments"); -var checkPoint = ""; -Promise.race.call(function(executor) { +checkPoint = ""; +function fn2(executor) { checkPoint += "a"; executor(undefined, undefined); checkPoint += "b"; executor(function() {}, function() {}); checkPoint += "c"; -}, []); +} +fn2.resolve = function() { + throw new Test262Error(); +}; +Promise.race.call(fn2 , []); assert.sameValue(checkPoint, "abc", "executor initially called with (undefined, undefined)"); -var checkPoint = ""; +checkPoint = ""; +function fn3(executor) { + checkPoint += "a"; + executor(undefined, function() {}); + checkPoint += "b"; + executor(function() {}, function() {}); + checkPoint += "c"; +} +Object.defineProperty(fn3, "resolve", { + get() { throw new Test262Error(); } +}); assert.throws(TypeError, function() { - Promise.race.call(function(executor) { - checkPoint += "a"; - executor(undefined, function() {}); - checkPoint += "b"; - executor(function() {}, function() {}); - checkPoint += "c"; - }, []); + Promise.race.call(fn3 , []); }, "executor initially called with (undefined, function)"); assert.sameValue(checkPoint, "ab", "executor initially called with (undefined, function)"); -var checkPoint = ""; +checkPoint = ""; +function fn4(executor) { + checkPoint += "a"; + executor(function() {}, undefined); + checkPoint += "b"; + executor(function() {}, function() {}); + checkPoint += "c"; +} +Object.defineProperty(fn4, "resolve", { + get() { throw new Test262Error(); } +}); assert.throws(TypeError, function() { - Promise.race.call(function(executor) { - checkPoint += "a"; - executor(function() {}, undefined); - checkPoint += "b"; - executor(function() {}, function() {}); - checkPoint += "c"; - }, []); + Promise.race.call(fn4 , []); }, "executor initially called with (function, undefined)"); assert.sameValue(checkPoint, "ab", "executor initially called with (function, undefined)"); -var checkPoint = ""; +checkPoint = ""; +function fn5(executor) { + checkPoint += "a"; + executor("invalid value", 123); + checkPoint += "b"; + executor(function() {}, function() {}); + checkPoint += "c"; +} +Object.defineProperty(fn5, "resolve", { + get() { throw new Test262Error(); } +}); assert.throws(TypeError, function() { - Promise.race.call(function(executor) { - checkPoint += "a"; - executor("invalid value", 123); - checkPoint += "b"; - executor(function() {}, function() {}); - checkPoint += "c"; - }, []); + Promise.race.call(fn5 , []); }, "executor initially called with (String, Number)"); assert.sameValue(checkPoint, "ab", "executor initially called with (String, Number)"); 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 index cc874421c2..951b509e42 100644 --- a/test/built-ins/Promise/race/invoke-resolve-get-error-close.js +++ b/test/built-ins/Promise/race/invoke-resolve-get-error-close.js @@ -25,10 +25,14 @@ features: [Symbol.iterator] ---*/ var iter = {}; + var returnCount = 0; +var nextCount = 0; + iter[Symbol.iterator] = function() { return { next: function() { + nextCount += 1; return { done: false }; @@ -40,11 +44,12 @@ iter[Symbol.iterator] = function() { }; }; Object.defineProperty(Promise, 'resolve', { - get: function() { + get() { throw new Test262Error(); } }); Promise.race(iter); -assert.sameValue(returnCount, 1); +assert.sameValue(nextCount, 0); +assert.sameValue(returnCount, 0); diff --git a/test/built-ins/Promise/race/invoke-resolve-get-once-multiple-calls.js b/test/built-ins/Promise/race/invoke-resolve-get-once-multiple-calls.js new file mode 100644 index 0000000000..bddd0ade61 --- /dev/null +++ b/test/built-ins/Promise/race/invoke-resolve-get-once-multiple-calls.js @@ -0,0 +1,45 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Gets constructor's `resolve` method once from zero to many invocations. +esid: sec-promise.race +info: | + Runtime Semantics: PerformPromiseRace + + 1. Let promiseResolve be ? Get(constructor, `"resolve"`). + 1. If IsCallable(promiseResolve) is false, throw a TypeError exception. + ... + 1. Repeat, + ... + 1. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »). +---*/ + +var p1 = Promise.resolve(1); +var p2 = Promise.resolve(1); +var p3 = Promise.reject(1); +var p4 = Promise.resolve(1); +var resolve = Promise.resolve; +var getCount = 0; +var callCount = 0; + +Object.defineProperty(Promise, 'resolve', { + configurable: true, + get() { + getCount += 1; + return function() { + callCount += 1; + return resolve.apply(Promise, arguments); + }; + } +}); + +Promise.race([p1, p2, p3, p4]); + +assert.sameValue( + getCount, 1, 'Got `resolve` only once for each iterated value' +); +assert.sameValue( + callCount, 4, '`resolve` invoked once for each iterated value' +); diff --git a/test/built-ins/Promise/race/invoke-resolve-get-once-no-calls.js b/test/built-ins/Promise/race/invoke-resolve-get-once-no-calls.js new file mode 100644 index 0000000000..3c3c27dd7e --- /dev/null +++ b/test/built-ins/Promise/race/invoke-resolve-get-once-no-calls.js @@ -0,0 +1,41 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Gets constructor's `resolve` method once from zero to many invocations. +esid: sec-promise.race +info: | + Runtime Semantics: PerformPromiseRace + + 1. Let promiseResolve be ? Get(constructor, `"resolve"`). + 1. If IsCallable(promiseResolve) is false, throw a TypeError exception. + ... + 1. Repeat, + ... + 1. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »). +---*/ + +var resolve = Promise.resolve; +var getCount = 0; +var callCount = 0; + +Object.defineProperty(Promise, 'resolve', { + configurable: true, + get() { + getCount += 1; + return function() { + callCount += 1; + return resolve.apply(Promise, arguments); + }; + } +}); + +Promise.race([]); + +assert.sameValue( + getCount, 1, 'Got `resolve` only once for each iterated value' +); +assert.sameValue( + callCount, 0, '`resolve` not called for empty iterator' +); diff --git a/test/built-ins/Promise/race/species-get-error.js b/test/built-ins/Promise/race/species-get-error.js index b32fd7ef4d..cbda028e16 100644 --- a/test/built-ins/Promise/race/species-get-error.js +++ b/test/built-ins/Promise/race/species-get-error.js @@ -17,9 +17,12 @@ function C(executor) { executor(function() {}, function() {}); } Object.defineProperty(C, Symbol.species, { - get: function() { - $ERROR("Getter for Symbol.species called"); + get() { + throw new Test262Error("Getter for Symbol.species called"); } }); +C.resolve = function() { + throw new Test262Error(); +}; Promise.race.call(C, []);