diff --git a/test/built-ins/Promise/any/capability-executor-called-twice.js b/test/built-ins/Promise/any/capability-executor-called-twice.js new file mode 100644 index 0000000000..c40485f222 --- /dev/null +++ b/test/built-ins/Promise/any/capability-executor-called-twice.js @@ -0,0 +1,106 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: > + Throws a TypeError if capabilities executor already called with non-undefined values. +info: | + Promise.any ( iterable ) + + ... + 2. Let promiseCapability be ? NewPromiseCapability(C). + ... + + GetCapabilitiesExecutor Functions + + ... + 4. If promiseCapability.[[Resolve]] is not undefined, throw a TypeError exception. + 5. If promiseCapability.[[Reject]] is not undefined, throw a TypeError exception. + 6. Set promiseCapability.[[Resolve]] to resolve. + 7. Set promiseCapability.[[Reject]] to reject. + ... +features: [Promise.any] +---*/ + +var checkPoint = ''; +function fn1(executor) { + checkPoint += 'a'; + executor(); + checkPoint += 'b'; + executor(function() {}, function() {}); + checkPoint += 'c'; +} +fn1.resolve = function() { + throw new Test262Error(); +}; +Promise.any.call(fn1, []); +assert.sameValue(checkPoint, 'abc', 'executor initially called with no arguments'); + +checkPoint = ''; +function fn2(executor) { + checkPoint += 'a'; + executor(undefined, undefined); + checkPoint += 'b'; + executor(function() {}, function() {}); + checkPoint += 'c'; +} +fn2.resolve = function() { + throw new Test262Error(); +}; +Promise.any.call(fn2, []); +assert.sameValue(checkPoint, 'abc', 'executor initially called with (undefined, undefined)'); + +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.any.call(fn3, []); +}, 'executor initially called with (undefined, function)'); +assert.sameValue(checkPoint, 'ab', 'executor initially called with (undefined, function)'); + +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.any.call(fn4, []); +}, 'executor initially called with (function, undefined)'); +assert.sameValue(checkPoint, 'ab', 'executor initially called with (function, undefined)'); + +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.any.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/any/capability-executor-not-callable.js b/test/built-ins/Promise/any/capability-executor-not-callable.js new file mode 100644 index 0000000000..c8be9cd252 --- /dev/null +++ b/test/built-ins/Promise/any/capability-executor-not-callable.js @@ -0,0 +1,107 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: > + Throws a TypeError if either resolve or reject capability is not callable. +info: | + Promise.any ( iterable ) + + ... + 2. Let promiseCapability be ? NewPromiseCapability(C). + ... + + NewPromiseCapability ( C ) + + ... + 5. Let executor be ! CreateBuiltinFunction(steps, « [[Capability]] »). + 6. Set executor.[[Capability]] to promiseCapability. + 7. Let promise be ? Construct(C, « executor »). + 8. If IsCallable(promiseCapability.[[Resolve]]) is false, throw a TypeError exception. + 9. If IsCallable(promiseCapability.[[Reject]]) is false, throw a TypeError exception. + ... +features: [Promise.any] +---*/ + +var checkPoint = ''; +function fn1(executor) { + checkPoint += 'a'; +} +Object.defineProperty(fn1, 'resolve', { + get() { throw new Test262Error(); } +}); +assert.throws(TypeError, function() { + Promise.any.call(fn1, []); +}, 'executor not called at all'); +assert.sameValue(checkPoint, 'a', 'executor not called at all'); + +checkPoint = ''; +function fn2(executor) { + checkPoint += 'a'; + executor(); + checkPoint += 'b'; +} +Object.defineProperty(fn2, 'resolve', { + get() { throw new Test262Error(); } +}); +assert.throws(TypeError, function() { + Promise.any.call(fn2, []); +}, 'executor called with no arguments'); +assert.sameValue(checkPoint, 'ab', 'executor called with no arguments'); + +checkPoint = ''; +function fn3(executor) { + checkPoint += 'a'; + executor(undefined, undefined); + checkPoint += 'b'; +} +Object.defineProperty(fn3, 'resolve', { + get() { throw new Test262Error(); } +}); +assert.throws(TypeError, function() { + Promise.any.call(fn3, []); +}, 'executor called with (undefined, undefined)'); +assert.sameValue(checkPoint, 'ab', 'executor called with (undefined, undefined)'); + +checkPoint = ''; +function fn4(executor) { + checkPoint += 'a'; + executor(undefined, function() {}); + checkPoint += 'b'; +} +Object.defineProperty(fn4, 'resolve', { + get() { throw new Test262Error(); } +}); +assert.throws(TypeError, function() { + Promise.any.call(fn4, []); +}, 'executor called with (undefined, function)'); +assert.sameValue(checkPoint, 'ab', 'executor called with (undefined, function)'); + +checkPoint = ''; +function fn5(executor) { + checkPoint += 'a'; + executor(function() {}, undefined); + checkPoint += 'b'; +} +Object.defineProperty(fn5, 'resolve', { + get() { throw new Test262Error(); } +}); +assert.throws(TypeError, function() { + Promise.any.call(fn5, []); +}, 'executor called with (function, undefined)'); +assert.sameValue(checkPoint, 'ab', 'executor called with (function, undefined)'); + +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.any.call(fn6, []); +}, 'executor called with (Number, String)'); +assert.sameValue(checkPoint, 'ab', 'executor called with (Number, String)'); diff --git a/test/built-ins/Promise/any/ctx-ctor-throws.js b/test/built-ins/Promise/any/ctx-ctor-throws.js new file mode 100644 index 0000000000..41288914fa --- /dev/null +++ b/test/built-ins/Promise/any/ctx-ctor-throws.js @@ -0,0 +1,25 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Promise.any invoked on a constructor value that throws an error +esid: sec-promise.any +info: | + 2. Let promiseCapability be ? NewPromiseCapability(C). + + NewPromiseCapability + + ... + 7. Let promise be ? Construct(C, « executor »). + +features: [Promise.any] +---*/ + +function CustomPromise() { + throw new Test262Error(); +} + +assert.throws(Test262Error, function() { + Promise.any.call(CustomPromise); +}); diff --git a/test/built-ins/Promise/any/ctx-ctor.js b/test/built-ins/Promise/any/ctx-ctor.js new file mode 100644 index 0000000000..7600458ebc --- /dev/null +++ b/test/built-ins/Promise/any/ctx-ctor.js @@ -0,0 +1,34 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Promise.any invoked on a constructor value +esid: sec-promise.any +info: | + 2. Let promiseCapability be ? NewPromiseCapability(C). + ... + 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability). + ... + 7. Return Completion(result). +features: [Promise.any, class] +---*/ + +var executor = null; +var callCount = 0; + +class SubPromise extends Promise { + constructor(a) { + super(a); + executor = a; + callCount += 1; + } +} + +var instance = Promise.any.call(SubPromise, []); + +assert.sameValue(instance.constructor, SubPromise); +assert.sameValue(instance instanceof SubPromise, true); + +assert.sameValue(callCount, 1); +assert.sameValue(typeof executor, 'function'); diff --git a/test/built-ins/Promise/any/ctx-non-ctor.js b/test/built-ins/Promise/any/ctx-non-ctor.js new file mode 100644 index 0000000000..46cc361240 --- /dev/null +++ b/test/built-ins/Promise/any/ctx-non-ctor.js @@ -0,0 +1,47 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Promise.any invoked on a non-constructor value +esid: sec-promise.any +info: | + ... + 2. Let promiseCapability be ? NewPromiseCapability(C). + + NewPromiseCapability ( C ) + + 1. If IsConstructor(C) is false, throw a TypeError exception. + +features: [Promise.any, Symbol] +---*/ + +assert.sameValue(typeof Promise.any, 'function'); + +assert.throws(TypeError, function() { + Promise.any.call(eval); +}); + +assert.throws(TypeError, function() { + Promise.any.call(undefined, []); +}); + +assert.throws(TypeError, function() { + Promise.any.call(null, []); +}); + +assert.throws(TypeError, function() { + Promise.any.call(86, []); +}); + +assert.throws(TypeError, function() { + Promise.any.call('string', []); +}); + +assert.throws(TypeError, function() { + Promise.any.call(true, []); +}); + +assert.throws(TypeError, function() { + Promise.any.call(Symbol(), []); +}); diff --git a/test/built-ins/Promise/any/does-not-perform-species-get-of-custom.js b/test/built-ins/Promise/any/does-not-perform-species-get-of-custom.js new file mode 100644 index 0000000000..cc96789191 --- /dev/null +++ b/test/built-ins/Promise/any/does-not-perform-species-get-of-custom.js @@ -0,0 +1,29 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: > + Promise.any.call(Custom, ...) does not derive a constructor via SpeciesConstructor() +info: | + 1. Let C be the this value. + 2. Let promiseCapability be ? NewPromiseCapability(C). + ... + + NewPromiseCapability ( C ) + + 1. If IsConstructor(C) is false, throw a TypeError exception. + 2. NOTE: C is assumed to be a constructor function that supports the parameter conventions of the Promise constructor (see 25.6.3.1). + ... + +flags: [async] +features: [Promise.any, Symbol.species, class, computed-property-names, Symbol, arrow-function] +---*/ + +class Custom extends Promise { + static get [Symbol.species]() { + throw new Test262Error('Erroneous Get(C, @@species) via SpeciesConstructor() occurred.'); + } +} + +Promise.any.call(Custom, [1]).then(() => $DONE(), $DONE); diff --git a/test/built-ins/Promise/any/does-not-perform-species-get-of-promise.js b/test/built-ins/Promise/any/does-not-perform-species-get-of-promise.js new file mode 100644 index 0000000000..0a32658066 --- /dev/null +++ b/test/built-ins/Promise/any/does-not-perform-species-get-of-promise.js @@ -0,0 +1,29 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: > + Promise.any() does not derive a constructor via SpeciesConstructor() +info: | + 1. Let C be the this value. + 2. Let promiseCapability be ? NewPromiseCapability(C). + ... + + NewPromiseCapability ( C ) + + 1. If IsConstructor(C) is false, throw a TypeError exception. + 2. NOTE: C is assumed to be a constructor function that supports the parameter conventions of the Promise constructor (see 25.6.3.1). + ... + +flags: [async] +features: [Promise.any, Symbol.species, Symbol, arrow-function] +---*/ + +Object.defineProperty(Promise, Symbol.species, { + get() { + throw new Test262Error('Erroneous Get(C, @@species) via SpeciesConstructor() occurred.'); + } +}); + +Promise.any([1]).then(() => $DONE(), $DONE); diff --git a/test/built-ins/Promise/any/invoke-resolve-error-close.js b/test/built-ins/Promise/any/invoke-resolve-error-close.js new file mode 100644 index 0000000000..b9bae20cfd --- /dev/null +++ b/test/built-ins/Promise/any/invoke-resolve-error-close.js @@ -0,0 +1,53 @@ +// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Explicit iterator closing in response to error +esid: sec-promise.any +info: | + 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability). + 6. If result is an abrupt completion, then + a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + Runtime Semantics: PerformPromiseAny + + 8. Repeat + ... + i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »). +flags: [async] +features: [Promise.any, Symbol.iterator, computed-property-names, Symbol, arrow-function] +---*/ + +let error = new Test262Error(); +let nextCount = 0; +let returnCount = 0; +let iter = { + [Symbol.iterator]() { + return { + next() { + nextCount += 1; + return { + value: null, + done: false + }; + }, + return() { + returnCount += 1; + } + }; + } +}; + +Promise.resolve = function() { + throw error; +}; + +Promise.any(iter).then(() => { + $DONE('The promise should be rejected, but was resolved'); +}, (reason) => { + assert.sameValue(nextCount, 1); + assert.sameValue(returnCount, 1); + assert.sameValue(reason, error); +}).then($DONE, $DONE); diff --git a/test/built-ins/Promise/any/invoke-resolve-error-reject.js b/test/built-ins/Promise/any/invoke-resolve-error-reject.js new file mode 100644 index 0000000000..9d6c1afb98 --- /dev/null +++ b/test/built-ins/Promise/any/invoke-resolve-error-reject.js @@ -0,0 +1,32 @@ +// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. 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.any +info: | + 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability). + 6. If result is an abrupt completion, then + a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + Runtime Semantics: PerformPromiseAny + + 8. Repeat + ... + i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »). + +flags: [async] +features: [Promise.any, arrow-function] +---*/ + +let error = new Test262Error(); +Promise.resolve = function() { + throw error; +}; + +Promise.any([1]).then(() => { + $DONE('The promise should be rejected, but was resolved'); + }, (reason) => { + assert.sameValue(reason, error); + }).then($DONE, $DONE); diff --git a/test/built-ins/Promise/any/invoke-resolve-get-error-close.js b/test/built-ins/Promise/any/invoke-resolve-get-error-close.js new file mode 100644 index 0000000000..86566d13b4 --- /dev/null +++ b/test/built-ins/Promise/any/invoke-resolve-get-error-close.js @@ -0,0 +1,57 @@ +// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Error retrieving the constructor's `resolve` method not opening iterator +esid: sec-promise.any +info: | + 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability). + 6. If result is an abrupt completion, then + a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + Runtime Semantics: PerformPromiseAny + + 8. Repeat + ... + i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »). + +flags: [async] +features: [Promise.any, Symbol.iterator, computed-property-names, Symbol, arrow-function] +---*/ + +let error = new Test262Error(); +let nextCount = 0; +let returnCount = 0; +let iter = { + [Symbol.iterator]() { + return { + next() { + nextCount += 1; + return { + value: null, + done: false + }; + }, + return() { + returnCount += 1; + } + }; + } +}; + +Object.defineProperty(Promise, 'resolve', { + get() { + throw error; + } +}); + + +Promise.any(iter).then(() => { + $DONE('The promise should be rejected, but was resolved'); +}, (reason) => { + assert.sameValue(nextCount, 0); + assert.sameValue(returnCount, 1); + assert.sameValue(reason, error); +}).then($DONE, $DONE); diff --git a/test/built-ins/Promise/any/invoke-resolve-get-error-reject.js b/test/built-ins/Promise/any/invoke-resolve-get-error-reject.js new file mode 100644 index 0000000000..c954c01045 --- /dev/null +++ b/test/built-ins/Promise/any/invoke-resolve-get-error-reject.js @@ -0,0 +1,35 @@ +// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Error retrieving the constructor's `resolve` method (rejecting promise) +esid: sec-promise.any +info: | + 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability). + 6. If result is an abrupt completion, then + a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + Runtime Semantics: PerformPromiseAny + + 8. Repeat + ... + i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »). + +flags: [async] +features: [Promise.any, arrow-function] +---*/ + +let error = new Test262Error(); +Object.defineProperty(Promise, 'resolve', { + get() { + throw error; + } +}); + +Promise.any([1]).then(() => { + $DONE('The promise should be rejected, but was resolved'); + }, (reason) => { + assert.sameValue(reason, error); + }).then($DONE, $DONE); diff --git a/test/built-ins/Promise/any/invoke-resolve-get-once-multiple-calls.js b/test/built-ins/Promise/any/invoke-resolve-get-once-multiple-calls.js new file mode 100644 index 0000000000..d8a421f7d6 --- /dev/null +++ b/test/built-ins/Promise/any/invoke-resolve-get-once-multiple-calls.js @@ -0,0 +1,54 @@ +// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. 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.any +info: | + 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability). + 6. If result is an abrupt completion, then + a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + Runtime Semantics: PerformPromiseAny + + 6. Let promiseResolve be ? Get(constructor, "resolve"). + 7. If ! IsCallable(promiseResolve) is false, throw a TypeError exception. + 8. Repeat + ... + i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »). + +flags: [async] +features: [Promise.any, arrow-function, destructuring-binding] +---*/ + +let promises = [ + Promise.reject(1), + Promise.reject(1), + Promise.reject(1), +]; +let boundPromiseResolve = Promise.resolve.bind(Promise); +let getCount = 0; +let callCount = 0; + +Object.defineProperty(Promise, 'resolve', { + configurable: true, + get() { + getCount += 1; + return function(...args) { + callCount += 1; + return boundPromiseResolve(...args); + }; + } +}); + +Promise.any(promises).then(() => { + $DONE('The promise should be rejected, but was resolved'); + }, ({errors}) => { + assert.sameValue(getCount, 1); + assert.sameValue(callCount, 3); + assert.sameValue(errors.length, 3); + }).then($DONE, $DONE); + + diff --git a/test/built-ins/Promise/any/invoke-resolve-get-once-no-calls.js b/test/built-ins/Promise/any/invoke-resolve-get-once-no-calls.js new file mode 100644 index 0000000000..2b7aa1384f --- /dev/null +++ b/test/built-ins/Promise/any/invoke-resolve-get-once-no-calls.js @@ -0,0 +1,49 @@ +// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. 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.any +info: | + 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability). + 6. If result is an abrupt completion, then + a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + Runtime Semantics: PerformPromiseAny + + 6. Let promiseResolve be ? Get(constructor, "resolve"). + 7. If ! IsCallable(promiseResolve) is false, throw a TypeError exception. + 8. Repeat + ... + i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »). + +flags: [async] +features: [Promise.any, arrow-function, destructuring-binding] +---*/ + +let boundPromiseResolve = Promise.resolve.bind(Promise); +let getCount = 0; +let callCount = 0; + +Object.defineProperty(Promise, 'resolve', { + configurable: true, + get() { + getCount += 1; + return function(...args) { + callCount += 1; + return boundPromiseResolve(...args); + }; + } +}); + +Promise.any([]).then(() => { + $DONE('The promise should be rejected, but was resolved'); + }, ({errors}) => { + assert.sameValue(getCount, 1); + assert.sameValue(callCount, 0); + assert.sameValue(errors.length, 0); + }).then($DONE, $DONE); + + diff --git a/test/built-ins/Promise/any/invoke-resolve-not-callable-rejects-with-typerror.js b/test/built-ins/Promise/any/invoke-resolve-not-callable-rejects-with-typerror.js new file mode 100644 index 0000000000..c5e7e16bde --- /dev/null +++ b/test/built-ins/Promise/any/invoke-resolve-not-callable-rejects-with-typerror.js @@ -0,0 +1,28 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + If the constructor's `resolve` method is not callable, reject with a TypeError. +esid: sec-promise.any +info: | + 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability). + + Runtime Semantics: PerformPromiseAny + + 6. Let promiseResolve be ? Get(constructor, "resolve"). + 7. If ! IsCallable(promiseResolve) is false, throw a TypeError exception. + +flags: [async] +features: [Promise.any, arrow-function] +---*/ + +Promise.resolve = null; + +Promise.any([1]) + .then( + () => $DONE('The promise should not be resolved.'), + error => { + assert(error instanceof TypeError); + } + ).then($DONE, $DONE); diff --git a/test/built-ins/Promise/any/invoke-resolve-on-promises-every-iteration-of-custom.js b/test/built-ins/Promise/any/invoke-resolve-on-promises-every-iteration-of-custom.js new file mode 100644 index 0000000000..57a99d4329 --- /dev/null +++ b/test/built-ins/Promise/any/invoke-resolve-on-promises-every-iteration-of-custom.js @@ -0,0 +1,43 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Invocation of the constructor's `resolve` method for iterable with promise values +esid: sec-promise.any +info: | + 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability). + + Runtime Semantics: PerformPromiseAny + + 8. Repeat + ... + i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »). + +flags: [async] +features: [Promise.any, class, arrow-function] +---*/ +class Custom extends Promise {} + +let values = [1, 1, 1]; +let cresolveCallCount = 0; +let presolveCallCount = 0; +let boundCustomResolve = Custom.resolve.bind(Custom); +let boundPromiseResolve = Promise.resolve.bind(Promise); + +Custom.resolve = function(...args) { + cresolveCallCount += 1; + return boundCustomResolve(...args); +}; + +Promise.resolve = function(...args) { + presolveCallCount += 1; + return boundPromiseResolve(...args); +}; + +Promise.any.call(Custom, values) + .then(() => { + assert.sameValue(presolveCallCount, 0, '`Promise.resolve` is never invoked'); + assert.sameValue(cresolveCallCount, 3, '`Custom.resolve` invoked once for every iterated promise'); + }, $DONE).then($DONE, $DONE); + diff --git a/test/built-ins/Promise/any/invoke-resolve-on-promises-every-iteration-of-promise.js b/test/built-ins/Promise/any/invoke-resolve-on-promises-every-iteration-of-promise.js new file mode 100644 index 0000000000..26d8d3332b --- /dev/null +++ b/test/built-ins/Promise/any/invoke-resolve-on-promises-every-iteration-of-promise.js @@ -0,0 +1,34 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Invocation of the constructor's `resolve` method for iterable with promise values +esid: sec-promise.any +info: | + 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability). + + Runtime Semantics: PerformPromiseAny + + 8. Repeat + ... + i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »). + +flags: [async] +features: [Promise.any, arrow-function] +---*/ + +let values = [1,1,1]; +let callCount = 0; +let boundPromiseResolve = Promise.resolve.bind(Promise); + +Promise.resolve = function(...args) { + callCount += 1; + return boundPromiseResolve(...args); +}; + +Promise.any(values) + .then(() => { + assert.sameValue(callCount, 3, '`then` invoked once for every iterated promise'); + }, $DONE).then($DONE, $DONE); + diff --git a/test/built-ins/Promise/any/invoke-resolve-on-values-every-iteration-of-custom.js b/test/built-ins/Promise/any/invoke-resolve-on-values-every-iteration-of-custom.js new file mode 100644 index 0000000000..be6076f074 --- /dev/null +++ b/test/built-ins/Promise/any/invoke-resolve-on-values-every-iteration-of-custom.js @@ -0,0 +1,43 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Invocation of the constructor's `resolve` method for iterable with non-promise values +esid: sec-promise.any +info: | + 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability). + + Runtime Semantics: PerformPromiseAny + + 8. Repeat + ... + i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »). + +flags: [async] +features: [Promise.any, class, arrow-function] +---*/ +class Custom extends Promise {} + +let values = [1, 2, 3]; +let cresolveCallCount = 0; +let presolveCallCount = 0; +let boundCustomResolve = Custom.resolve.bind(Custom); +let boundPromiseResolve = Promise.resolve.bind(Promise); + +Custom.resolve = function(...args) { + cresolveCallCount += 1; + return boundCustomResolve(...args); +}; + +Promise.resolve = function(...args) { + presolveCallCount += 1; + return boundPromiseResolve(...args); +}; + +Promise.any.call(Custom, values) + .then(() => { + assert.sameValue(presolveCallCount, 0, '`Promise.resolve` is never invoked'); + assert.sameValue(cresolveCallCount, 3, '`Custom.resolve` invoked once for every iterated promise'); + }, $DONE).then($DONE, $DONE); + diff --git a/test/built-ins/Promise/any/invoke-resolve-on-values-every-iteration-of-promise.js b/test/built-ins/Promise/any/invoke-resolve-on-values-every-iteration-of-promise.js new file mode 100644 index 0000000000..8f36c669d9 --- /dev/null +++ b/test/built-ins/Promise/any/invoke-resolve-on-values-every-iteration-of-promise.js @@ -0,0 +1,34 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Invocation of the constructor's `resolve` method for iterable with non-promise values +esid: sec-promise.any +info: | + 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability). + + Runtime Semantics: PerformPromiseAny + + 8. Repeat + ... + i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »). + +flags: [async] +features: [Promise.any, arrow-function] +---*/ + +let values = [1, 2, 3]; +let callCount = 0; +let boundPromiseResolve = Promise.resolve.bind(Promise); + +Promise.resolve = function(...args) { + callCount += 1; + return boundPromiseResolve(...args); +}; + +Promise.any(values) + .then(() => { + assert.sameValue(callCount, 3, '`Promise.resolve` invoked once for every iterated value'); + }, $DONE).then($DONE, $DONE); + diff --git a/test/built-ins/Promise/any/invoke-resolve.js b/test/built-ins/Promise/any/invoke-resolve.js new file mode 100644 index 0000000000..820d0ec61e --- /dev/null +++ b/test/built-ins/Promise/any/invoke-resolve.js @@ -0,0 +1,31 @@ +// Copyright (C) 2019 Sergey Rubanov, 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Invocation of the constructor's `resolve` method +esid: sec-promise.any +info: | + 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability). + + Runtime Semantics: PerformPromiseAny + + 8. Repeat + ... + i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »). + ... + r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »). + +flags: [async] +features: [Promise.any, arrow-function] +---*/ + +let boundPromiseResolve = Promise.resolve.bind(Promise); + +Promise.resolve = function(...args) { + assert.sameValue(args.length, 1, '`resolve` invoked with a single argument'); + assert.sameValue(this, Promise, '`this` value is the constructor'); + return boundPromiseResolve(...args); +}; + +Promise.any([1]).then(() => $DONE(), $DONE); diff --git a/test/built-ins/Promise/any/invoke-then-error-close.js b/test/built-ins/Promise/any/invoke-then-error-close.js new file mode 100644 index 0000000000..42d7e92b15 --- /dev/null +++ b/test/built-ins/Promise/any/invoke-then-error-close.js @@ -0,0 +1,50 @@ +// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. 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.any +info: | + 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability). + 6. If result is an abrupt completion, then + a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + Runtime Semantics: PerformPromiseAny + + r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »). + +flags: [async] +features: [Promise.any, Symbol.iterator, arrow-function, computed-property-names, Symbol] +---*/ + +let error = new Test262Error(); +let promise = Promise.resolve(); +let returnCount = 0; +let iter = { + [Symbol.iterator]() { + return { + next() { + return { + done: false, + value: promise + }; + }, + return() { + returnCount += 1; + return {}; + } + }; + } +}; + +promise.then = function() { + throw error; +}; + +Promise.any(iter).then(() => { + $DONE('The promise should be rejected, but was resolved'); +}, (reason) => { + assert.sameValue(returnCount, 1); + assert.sameValue(reason, error); +}).then($DONE, $DONE); diff --git a/test/built-ins/Promise/any/invoke-then-error-reject.js b/test/built-ins/Promise/any/invoke-then-error-reject.js new file mode 100644 index 0000000000..bfd8f11371 --- /dev/null +++ b/test/built-ins/Promise/any/invoke-then-error-reject.js @@ -0,0 +1,32 @@ +// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. 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 (rejecting Promise) +esid: sec-promise.any +info: | + 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability). + 6. If result is an abrupt completion, then + a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + Runtime Semantics: PerformPromiseAny + + r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »). + +flags: [async] +features: [Promise.any, arrow-function] +---*/ +let error = new Test262Error(); +let promise = Promise.resolve(); + +promise.then = function() { + throw error; +}; + +Promise.any([promise]).then(() => { + $DONE('The promise should be rejected, but was resolved'); +}, (reason) => { + assert.sameValue(reason, error); +}).then($DONE, $DONE); diff --git a/test/built-ins/Promise/any/invoke-then-get-error-close.js b/test/built-ins/Promise/any/invoke-then-get-error-close.js new file mode 100644 index 0000000000..b2d174cbf4 --- /dev/null +++ b/test/built-ins/Promise/any/invoke-then-get-error-close.js @@ -0,0 +1,51 @@ +// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. 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-promise.any +info: | + 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability). + 6. If result is an abrupt completion, then + a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + Runtime Semantics: PerformPromiseAny + + r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »). + +flags: [async] +features: [Promise.any, Symbol.iterator, arrow-function, computed-property-names, Symbol] +---*/ +let error = new Test262Error(); +let promise = Promise.resolve(); +let returnCount = 0; +let iter = { + [Symbol.iterator]() { + return { + next() { + return { + done: false, + value: promise + }; + }, + return() { + returnCount += 1; + return {}; + } + }; + } +}; + +Object.defineProperty(promise, 'then', { + get() { + throw error; + } +}); + +Promise.any(iter).then(() => { + $DONE('The promise should be rejected, but was resolved'); +}, (reason) => { + assert.sameValue(returnCount, 1); + assert.sameValue(reason, error); +}).then($DONE, $DONE); diff --git a/test/built-ins/Promise/any/invoke-then-get-error-reject.js b/test/built-ins/Promise/any/invoke-then-get-error-reject.js new file mode 100644 index 0000000000..b202898aec --- /dev/null +++ b/test/built-ins/Promise/any/invoke-then-get-error-reject.js @@ -0,0 +1,33 @@ +// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. 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.any +info: | + 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability). + 6. If result is an abrupt completion, then + a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + Runtime Semantics: PerformPromiseAny + + r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »). + +flags: [async] +features: [Promise.any, arrow-function] +---*/ +let error = new Test262Error(); +let promise = Promise.resolve(); + +Object.defineProperty(promise, 'then', { + get() { + throw error; + } +}); + +Promise.any([promise]).then(() => { + $DONE('The promise should be rejected, but was resolved'); +}, (reason) => { + assert.sameValue(reason, error); +}).then($DONE, $DONE); diff --git a/test/built-ins/Promise/any/invoke-then-on-promises-every-iteration.js b/test/built-ins/Promise/any/invoke-then-on-promises-every-iteration.js new file mode 100644 index 0000000000..bc6281e5d4 --- /dev/null +++ b/test/built-ins/Promise/any/invoke-then-on-promises-every-iteration.js @@ -0,0 +1,41 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Invocation of the instance's `then` method +esid: sec-promise.any +info: | + 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability). + 6. If result is an abrupt completion, then + a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + Runtime Semantics: PerformPromiseAny + + r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »). + +flags: [async] +features: [Promise.any, arrow-function] +---*/ + +let promises = [ + Promise.resolve(), + Promise.resolve(), + Promise.resolve(), +]; +let callCount = 0; + +promises.forEach(promise => { + let boundThen = promise.then.bind(promise); + promise.then = function(...args) { + assert.sameValue(this, promises[callCount]); + callCount += 1; + return boundThen(...args); + }; +}); + +Promise.any(promises) + .then(() => { + assert.sameValue(callCount, 3, '`then` invoked once for every iterated value'); + }, $DONE).then($DONE, $DONE); diff --git a/test/built-ins/Promise/any/invoke-then.js b/test/built-ins/Promise/any/invoke-then.js new file mode 100644 index 0000000000..b8b1ccdb6d --- /dev/null +++ b/test/built-ins/Promise/any/invoke-then.js @@ -0,0 +1,34 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Invocation of the instance's `then` method +esid: sec-promise.any +info: | + 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability). + 6. If result is an abrupt completion, then + a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + Runtime Semantics: PerformPromiseAny + + r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »). + +flags: [async] +features: [Promise.any, arrow-function] +---*/ + +let promise = new Promise(() => {}); +let boundThen = promise.then.bind(promise); + +promise.then = function(resolver, rejectElement) { + assert.sameValue(this, promise); + assert.sameValue(typeof resolver, 'function'); + assert.sameValue(resolver.length, 1, 'resolver.length is 1'); + assert.sameValue(typeof rejectElement, 'function'); + assert.sameValue(rejectElement.length, 1, 'rejectElement.length is 0'); + return boundThen(resolver, rejectElement); +}; + +Promise.any([promise]).then(() => $DONE(), $DONE); diff --git a/test/built-ins/Promise/any/is-function.js b/test/built-ins/Promise/any/is-function.js new file mode 100644 index 0000000000..a55b7c7cdf --- /dev/null +++ b/test/built-ins/Promise/any/is-function.js @@ -0,0 +1,10 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: Promise.any is callable +features: [Promise.any] +---*/ + +assert.sameValue(typeof Promise.any, 'function'); diff --git a/test/built-ins/Promise/any/iter-arg-is-empty-iterable-reject.js b/test/built-ins/Promise/any/iter-arg-is-empty-iterable-reject.js new file mode 100644 index 0000000000..14fb3cae1d --- /dev/null +++ b/test/built-ins/Promise/any/iter-arg-is-empty-iterable-reject.js @@ -0,0 +1,39 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: > + Promise.any([]) rejects with AggregateError, empty errors array. +info: | + Runtime Semantics: PerformPromiseAny ( iteratorRecord, constructor, resultCapability ) + + ... + 3. Let errors be a new empty List. + ... + 8. Repeat, + a. Let next be IteratorStep(iteratorRecord). + b. If next is an abrupt completion, set iteratorRecord.[[Done]] to true. + c. ReturnIfAbrupt(next). + d. If next is false, then + i. Set iteratorRecord.[[Done]] to true. + ii. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1. + iii. If remainingElementsCount.[[Value]] is 0, then + 1. Let error be a newly created AggregateError object. + 2. Set error.[[AggregateErrors]] to errors. + 3. Return ThrowCompletion(error). + ... + +flags: [async] +features: [AggregateError, Promise.any, arrow-function] +---*/ + +Promise.any([]) + .then( + () => $DONE('The promise should be rejected, but was resolved'), + error => { + assert.sameValue(Object.getPrototypeOf(error), AggregateError.prototype); + assert(error instanceof AggregateError); + assert.sameValue(error.errors.length, 0); + } + ).then($DONE, $DONE); diff --git a/test/built-ins/Promise/any/iter-arg-is-empty-string-reject.js b/test/built-ins/Promise/any/iter-arg-is-empty-string-reject.js new file mode 100644 index 0000000000..cb3e319766 --- /dev/null +++ b/test/built-ins/Promise/any/iter-arg-is-empty-string-reject.js @@ -0,0 +1,39 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: > + Promise.any('') rejects with AggregateError, empty errors array. +info: | + Runtime Semantics: PerformPromiseAny ( iteratorRecord, constructor, resultCapability ) + + ... + 3. Let errors be a new empty List. + ... + 8. Repeat, + a. Let next be IteratorStep(iteratorRecord). + b. If next is an abrupt completion, set iteratorRecord.[[Done]] to true. + c. ReturnIfAbrupt(next). + d. If next is false, then + i. Set iteratorRecord.[[Done]] to true. + ii. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1. + iii. If remainingElementsCount.[[Value]] is 0, then + 1. Let error be a newly created AggregateError object. + 2. Set error.[[AggregateErrors]] to errors. + 3. Return ThrowCompletion(error). + ... + +features: [AggregateError, Promise.any, arrow-function] +flags: [async] +---*/ + +Promise.any('') + .then( + () => $DONE('The promise should be rejected, but was resolved'), + error => { + assert.sameValue(Object.getPrototypeOf(error), AggregateError.prototype); + assert(error instanceof AggregateError); + assert.sameValue(error.errors.length, 0); + } + ).then($DONE, $DONE); diff --git a/test/built-ins/Promise/any/iter-arg-is-false-reject.js b/test/built-ins/Promise/any/iter-arg-is-false-reject.js new file mode 100644 index 0000000000..d9ca00e7d3 --- /dev/null +++ b/test/built-ins/Promise/any/iter-arg-is-false-reject.js @@ -0,0 +1,36 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: > + Promise.any(false) rejects with TypeError. +info: | + Promise.any ( iterable ) + + ... + 3. Let iteratorRecord be GetIterator(iterable). + 4. IfAbruptRejectPromise(iteratorRecord, promiseCapability). + ... + + #sec-getiterator + GetIterator ( obj [ , hint [ , method ] ] ) + + ... + Let iterator be ? Call(method, obj). + If Type(iterator) is not Object, throw a TypeError exception. + ... +features: [Promise.any] +flags: [async] +---*/ + +try { + Promise.any(false).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype); + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/test/built-ins/Promise/any/iter-arg-is-null-reject.js b/test/built-ins/Promise/any/iter-arg-is-null-reject.js new file mode 100644 index 0000000000..1fad1fbe66 --- /dev/null +++ b/test/built-ins/Promise/any/iter-arg-is-null-reject.js @@ -0,0 +1,36 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: > + Promise.any(null) rejects with TypeError. +info: | + Promise.any ( iterable ) + + ... + 3. Let iteratorRecord be GetIterator(iterable). + 4. IfAbruptRejectPromise(iteratorRecord, promiseCapability). + ... + + #sec-getiterator + GetIterator ( obj [ , hint [ , method ] ] ) + + ... + Let iterator be ? Call(method, obj). + If Type(iterator) is not Object, throw a TypeError exception. + ... +features: [Promise.any] +flags: [async] +---*/ + +try { + Promise.any(null).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype); + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/test/built-ins/Promise/any/iter-arg-is-number-reject.js b/test/built-ins/Promise/any/iter-arg-is-number-reject.js new file mode 100644 index 0000000000..2e09657b8d --- /dev/null +++ b/test/built-ins/Promise/any/iter-arg-is-number-reject.js @@ -0,0 +1,36 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: > + Promise.any(number) rejects with TypeError. +info: | + Promise.any ( iterable ) + + ... + 3. Let iteratorRecord be GetIterator(iterable). + 4. IfAbruptRejectPromise(iteratorRecord, promiseCapability). + ... + + #sec-getiterator + GetIterator ( obj [ , hint [ , method ] ] ) + + ... + Let iterator be ? Call(method, obj). + If Type(iterator) is not Object, throw a TypeError exception. + ... +features: [Promise.any] +flags: [async] +---*/ + +try { + Promise.any(1).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype); + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/test/built-ins/Promise/any/iter-arg-is-poisoned.js b/test/built-ins/Promise/any/iter-arg-is-poisoned.js new file mode 100644 index 0000000000..679ca788f9 --- /dev/null +++ b/test/built-ins/Promise/any/iter-arg-is-poisoned.js @@ -0,0 +1,42 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: > + Promise.any(poisoned iterable) rejects with whatever error is thrown. +info: | + Promise.any ( iterable ) + + ... + 3. Let iteratorRecord be GetIterator(iterable). + 4. IfAbruptRejectPromise(iteratorRecord, promiseCapability). + ... + + #sec-getiterator + GetIterator ( obj [ , hint [ , method ] ] ) + + ... + Let iterator be ? Call(method, obj). + ... +features: [Promise.any, Symbol, Symbol.iterator, arrow-function] +flags: [async] +---*/ + +var poison = []; +Object.defineProperty(poison, Symbol.iterator, { + get() { + throw new Test262Error(); + } +}); + +try { + Promise.any(poison).then(() => { + $DONE('The promise should be rejected, but was resolved'); + }, (error) => { + assert.sameValue(Object.getPrototypeOf(error), Test262Error.prototype); + assert(error instanceof Test262Error); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/test/built-ins/Promise/any/iter-arg-is-string-resolve.js b/test/built-ins/Promise/any/iter-arg-is-string-resolve.js new file mode 100644 index 0000000000..31553ea977 --- /dev/null +++ b/test/built-ins/Promise/any/iter-arg-is-string-resolve.js @@ -0,0 +1,36 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: > + Promise.any('non-empty-string') resolves with the first character in the non-empty string +info: | + Promise.any ( iterable ) + + ... + 3. Let iteratorRecord be GetIterator(iterable). + 4. IfAbruptRejectPromise(iteratorRecord, promiseCapability). + ... + + #sec-getiterator + GetIterator ( obj [ , hint [ , method ] ] ) + + ... + Let iterator be ? Call(method, obj). + If Type(iterator) is not Object, throw a TypeError exception. + ... +features: [Promise.any, arrow-function] +flags: [async] +---*/ + +try { + Promise.any('xyz').then(v => { + assert.sameValue(v, 'x'); + assert.sameValue(v.length, 1); + }, error => { + $DONE(`The promise should be resolved, but was rejected with error: ${error.message}`); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be resolved, but threw an exception: ${error.message}`); +} diff --git a/test/built-ins/Promise/any/iter-arg-is-symbol-reject.js b/test/built-ins/Promise/any/iter-arg-is-symbol-reject.js new file mode 100644 index 0000000000..8cc96f153c --- /dev/null +++ b/test/built-ins/Promise/any/iter-arg-is-symbol-reject.js @@ -0,0 +1,49 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: > + Promise.any(Symbol()) rejects with TypeError. +info: | + Promise.any ( iterable ) + + ... + 3. Let iteratorRecord be GetIterator(iterable). + 4. IfAbruptRejectPromise(iteratorRecord, promiseCapability). + ... + + GetIterator ( obj [ , hint [ , method ] ] ) + + ... + 3. If method is not present, then + a. If hint is async, then + ... + b. Otherwise, set method to ? GetMethod(obj, @@iterator). + 4. Let iterator be ? Call(method, obj). + 5. If Type(iterator) is not Object, throw a TypeError exception. + ... + + GetMethod + + 2. Let func be ? GetV(V, P). + 3. If func is either undefined or null, return undefined. + 4. If IsCallable(func) is false, throw a TypeError exception. + + Call ( F, V [ , argumentsList ] ) + + 2. If IsCallable(F) is false, throw a TypeError exception. +features: [Promise.any, Symbol] +flags: [async] +---*/ + +try { + Promise.any(Symbol()).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype); + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/test/built-ins/Promise/any/iter-arg-is-true-reject.js b/test/built-ins/Promise/any/iter-arg-is-true-reject.js new file mode 100644 index 0000000000..3678db6c49 --- /dev/null +++ b/test/built-ins/Promise/any/iter-arg-is-true-reject.js @@ -0,0 +1,49 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: > + Promise.any(true) rejects with TypeError. +info: | + Promise.any ( iterable ) + + ... + 3. Let iteratorRecord be GetIterator(iterable). + 4. IfAbruptRejectPromise(iteratorRecord, promiseCapability). + ... + + GetIterator ( obj [ , hint [ , method ] ] ) + + ... + 3. If method is not present, then + a. If hint is async, then + ... + b. Otherwise, set method to ? GetMethod(obj, @@iterator). + 4. Let iterator be ? Call(method, obj). + 5. If Type(iterator) is not Object, throw a TypeError exception. + ... + + GetMethod + + 2. Let func be ? GetV(V, P). + 3. If func is either undefined or null, return undefined. + 4. If IsCallable(func) is false, throw a TypeError exception. + + Call ( F, V [ , argumentsList ] ) + + 2. If IsCallable(F) is false, throw a TypeError exception. +features: [Promise.any] +flags: [async] +---*/ + +try { + Promise.any(true).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype); + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/test/built-ins/Promise/any/iter-arg-is-undefined-reject.js b/test/built-ins/Promise/any/iter-arg-is-undefined-reject.js new file mode 100644 index 0000000000..8224953f9b --- /dev/null +++ b/test/built-ins/Promise/any/iter-arg-is-undefined-reject.js @@ -0,0 +1,49 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: > + Promise.any(undefined) rejects with TypeError. +info: | + Promise.any ( iterable ) + + ... + 3. Let iteratorRecord be GetIterator(iterable). + 4. IfAbruptRejectPromise(iteratorRecord, promiseCapability). + ... + + GetIterator ( obj [ , hint [ , method ] ] ) + + ... + 3. If method is not present, then + a. If hint is async, then + ... + b. Otherwise, set method to ? GetMethod(obj, @@iterator). + 4. Let iterator be ? Call(method, obj). + 5. If Type(iterator) is not Object, throw a TypeError exception. + ... + + GetMethod + + 2. Let func be ? GetV(V, P). + 3. If func is either undefined or null, return undefined. + 4. If IsCallable(func) is false, throw a TypeError exception. + + Call ( F, V [ , argumentsList ] ) + + 2. If IsCallable(F) is false, throw a TypeError exception. +features: [Promise.any] +flags: [async] +---*/ + +try { + Promise.any(undefined).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype); + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/test/built-ins/Promise/any/iter-assigned-false-reject.js b/test/built-ins/Promise/any/iter-assigned-false-reject.js new file mode 100644 index 0000000000..9e6e32a213 --- /dev/null +++ b/test/built-ins/Promise/any/iter-assigned-false-reject.js @@ -0,0 +1,53 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: > + Reject when argument's Symbol.iterator property has the value false +info: | + Promise.any ( iterable ) + + ... + 4. Let iteratorRecord be GetIterator(iterable). + 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability). + ... + + GetIterator ( obj [ , hint [ , method ] ] ) + + ... + 3. If method is not present, then + a. If hint is async, then + i. Set method to ? GetMethod(obj, @@asyncIterator). + ii. If method is undefined, then + 1. Let syncMethod be ? GetMethod(obj, @@iterator). + 2. Let syncIteratorRecord be ? GetIterator(obj, sync, syncMethod). + ... + 4. Let iterator be ? Call(method, obj). + ... + + GetMethod + + 2. Let func be ? GetV(V, P). + 3. If func is either undefined or null, return undefined. + 4. If IsCallable(func) is false, throw a TypeError exception. + + Call ( F, V [ , argumentsList ] ) + + 2. If IsCallable(F) is false, throw a TypeError exception. +features: [Promise.any, Symbol.iterator, Symbol, computed-property-names] +flags: [async] +---*/ + +try { + Promise.any({ + [Symbol.iterator]: false + }).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype); + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/test/built-ins/Promise/any/iter-assigned-null-reject.js b/test/built-ins/Promise/any/iter-assigned-null-reject.js new file mode 100644 index 0000000000..08e9b18ad5 --- /dev/null +++ b/test/built-ins/Promise/any/iter-assigned-null-reject.js @@ -0,0 +1,51 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: > + Reject when argument's Symbol.iterator property has the value null +info: | + Promise.any ( iterable ) + + ... + 4. Let iteratorRecord be GetIterator(iterable). + 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability). + ... + + GetIterator ( obj [ , hint [ , method ] ] ) + + ... + 3. If method is not present, then + a. If hint is async, then + ... + b. Otherwise, set method to ? GetMethod(obj, @@iterator). + 4. Let iterator be ? Call(method, obj). + 5. If Type(iterator) is not Object, throw a TypeError exception. + ... + + GetMethod + + 2. Let func be ? GetV(V, P). + 3. If func is either undefined or null, return undefined. + 4. If IsCallable(func) is false, throw a TypeError exception. + + Call ( F, V [ , argumentsList ] ) + + 2. If IsCallable(F) is false, throw a TypeError exception. +features: [Promise.any, Symbol.iterator, Symbol, computed-property-names] +flags: [async] +---*/ + +try { + Promise.any({ + [Symbol.iterator]: null + }).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype); + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/test/built-ins/Promise/any/iter-assigned-number-reject.js b/test/built-ins/Promise/any/iter-assigned-number-reject.js new file mode 100644 index 0000000000..4e600b4278 --- /dev/null +++ b/test/built-ins/Promise/any/iter-assigned-number-reject.js @@ -0,0 +1,51 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: > + Reject when argument's Symbol.iterator property has the value 1 +info: | + Promise.any ( iterable ) + + ... + 4. Let iteratorRecord be GetIterator(iterable). + 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability). + ... + + GetIterator ( obj [ , hint [ , method ] ] ) + + ... + 3. If method is not present, then + a. If hint is async, then + ... + b. Otherwise, set method to ? GetMethod(obj, @@iterator). + 4. Let iterator be ? Call(method, obj). + 5. If Type(iterator) is not Object, throw a TypeError exception. + ... + + GetMethod + + 2. Let func be ? GetV(V, P). + 3. If func is either undefined or null, return undefined. + 4. If IsCallable(func) is false, throw a TypeError exception. + + Call ( F, V [ , argumentsList ] ) + + 2. If IsCallable(F) is false, throw a TypeError exception. +features: [Promise.any, Symbol.iterator, Symbol, computed-property-names] +flags: [async] +---*/ + +try { + Promise.any({ + [Symbol.iterator]: 1 + }).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype); + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/test/built-ins/Promise/any/iter-assigned-string-reject.js b/test/built-ins/Promise/any/iter-assigned-string-reject.js new file mode 100644 index 0000000000..ab37eaca38 --- /dev/null +++ b/test/built-ins/Promise/any/iter-assigned-string-reject.js @@ -0,0 +1,51 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: > + Reject when argument's Symbol.iterator property has the value "" +info: | + Promise.any ( iterable ) + + ... + 4. Let iteratorRecord be GetIterator(iterable). + 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability). + ... + + GetIterator ( obj [ , hint [ , method ] ] ) + + ... + 3. If method is not present, then + a. If hint is async, then + ... + b. Otherwise, set method to ? GetMethod(obj, @@iterator). + 4. Let iterator be ? Call(method, obj). + 5. If Type(iterator) is not Object, throw a TypeError exception. + ... + + GetMethod + + 2. Let func be ? GetV(V, P). + 3. If func is either undefined or null, return undefined. + 4. If IsCallable(func) is false, throw a TypeError exception. + + Call ( F, V [ , argumentsList ] ) + + 2. If IsCallable(F) is false, throw a TypeError exception. +features: [Promise.any, Symbol.iterator, Symbol, computed-property-names] +flags: [async] +---*/ + +try { + Promise.any({ + [Symbol.iterator]: '' + }).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype); + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/test/built-ins/Promise/any/iter-assigned-symbol-reject.js b/test/built-ins/Promise/any/iter-assigned-symbol-reject.js new file mode 100644 index 0000000000..341afd3d79 --- /dev/null +++ b/test/built-ins/Promise/any/iter-assigned-symbol-reject.js @@ -0,0 +1,51 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: > + Reject when argument's Symbol.iterator property has the value Symbol() +info: | + Promise.any ( iterable ) + + ... + 4. Let iteratorRecord be GetIterator(iterable). + 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability). + ... + + GetIterator ( obj [ , hint [ , method ] ] ) + + ... + 3. If method is not present, then + a. If hint is async, then + ... + b. Otherwise, set method to ? GetMethod(obj, @@iterator). + 4. Let iterator be ? Call(method, obj). + 5. If Type(iterator) is not Object, throw a TypeError exception. + ... + + GetMethod + + 2. Let func be ? GetV(V, P). + 3. If func is either undefined or null, return undefined. + 4. If IsCallable(func) is false, throw a TypeError exception. + + Call ( F, V [ , argumentsList ] ) + + 2. If IsCallable(F) is false, throw a TypeError exception. +features: [Promise.any, Symbol, Symbol.iterator, computed-property-names] +flags: [async] +---*/ + +try { + Promise.any({ + [Symbol.iterator]: Symbol() + }).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype); + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/test/built-ins/Promise/any/iter-assigned-true-reject.js b/test/built-ins/Promise/any/iter-assigned-true-reject.js new file mode 100644 index 0000000000..5eebb151bd --- /dev/null +++ b/test/built-ins/Promise/any/iter-assigned-true-reject.js @@ -0,0 +1,51 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: > + Reject when argument's Symbol.iterator property has the value true +info: | + Promise.any ( iterable ) + + ... + 4. Let iteratorRecord be GetIterator(iterable). + 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability). + ... + + GetIterator ( obj [ , hint [ , method ] ] ) + + ... + 3. If method is not present, then + a. If hint is async, then + ... + b. Otherwise, set method to ? GetMethod(obj, @@iterator). + 4. Let iterator be ? Call(method, obj). + 5. If Type(iterator) is not Object, throw a TypeError exception. + ... + + GetMethod + + 2. Let func be ? GetV(V, P). + 3. If func is either undefined or null, return undefined. + 4. If IsCallable(func) is false, throw a TypeError exception. + + Call ( F, V [ , argumentsList ] ) + + 2. If IsCallable(F) is false, throw a TypeError exception. +features: [Promise.any, Symbol.iterator, Symbol, computed-property-names] +flags: [async] +---*/ + +try { + Promise.any({ + [Symbol.iterator]: true + }).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype); + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/test/built-ins/Promise/any/iter-assigned-undefined-reject.js b/test/built-ins/Promise/any/iter-assigned-undefined-reject.js new file mode 100644 index 0000000000..037669016f --- /dev/null +++ b/test/built-ins/Promise/any/iter-assigned-undefined-reject.js @@ -0,0 +1,51 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: > + Reject when argument's Symbol.iterator property has the value undefined +info: | + Promise.any ( iterable ) + + ... + 4. Let iteratorRecord be GetIterator(iterable). + 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability). + ... + + GetIterator ( obj [ , hint [ , method ] ] ) + + ... + 3. If method is not present, then + a. If hint is async, then + ... + b. Otherwise, set method to ? GetMethod(obj, @@iterator). + 4. Let iterator be ? Call(method, obj). + 5. If Type(iterator) is not Object, throw a TypeError exception. + ... + + GetMethod + + 2. Let func be ? GetV(V, P). + 3. If func is either undefined or null, return undefined. + 4. If IsCallable(func) is false, throw a TypeError exception. + + Call ( F, V [ , argumentsList ] ) + + 2. If IsCallable(F) is false, throw a TypeError exception. +features: [Promise.any, Symbol.iterator, Symbol, computed-property-names] +flags: [async] +---*/ + +try { + Promise.any({ + [Symbol.iterator]: undefined + }).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype); + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/test/built-ins/Promise/any/iter-step-err-no-close.js b/test/built-ins/Promise/any/iter-step-err-no-close.js new file mode 100644 index 0000000000..329240b707 --- /dev/null +++ b/test/built-ins/Promise/any/iter-step-err-no-close.js @@ -0,0 +1,60 @@ +// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: > + Error when advancing the provided iterable (not closing iterator) +info: | + Promise.any ( iterable ) + + 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability). + 6. If result is an abrupt completion, then + a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + Runtime Semantics: PerformPromiseAny + + 8. Repeat + a. Let next be IteratorStep(iteratorRecord). + b. If next is an abrupt completion, set iteratorRecord.[[done]] to true. + c. ReturnIfAbrupt(next). + +flags: [async] +features: [Promise.any, Symbol.iterator, computed-property-names, Symbol, arrow-function] +---*/ + +let returnCount = 0; +let poisonedDone = {}; +let error = new Test262Error(); +Object.defineProperties(poisonedDone, { + done: { + get() { + throw error; + } + }, + value: { + get() {} + } +}); +let iterStepThrows = { + [Symbol.iterator]() { + return { + next() { + return poisonedDone; + }, + return() { + returnCount += 1; + return {}; + } + }; + } +}; + +Promise.any(iterStepThrows).then( + () => { + $DONE('The promise should be rejected.'); +}, (reason) => { + assert.sameValue(reason, error); + assert.sameValue(returnCount, 0); +}).then($DONE, $DONE); diff --git a/test/built-ins/Promise/any/iter-step-err-reject.js b/test/built-ins/Promise/any/iter-step-err-reject.js new file mode 100644 index 0000000000..d06a2e0111 --- /dev/null +++ b/test/built-ins/Promise/any/iter-step-err-reject.js @@ -0,0 +1,56 @@ +// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: > + Error when advancing the provided iterable (rejecting promise) +info: | + Promise.any ( iterable ) + + 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability). + 6. If result is an abrupt completion, then + a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + Runtime Semantics: PerformPromiseAny + + 8. Repeat + a. Let next be IteratorStep(iteratorRecord). + b. If next is an abrupt completion, set iteratorRecord.[[done]] to true. + c. ReturnIfAbrupt(next). + +flags: [async] +features: [Promise.any, Symbol.iterator, computed-property-names, Symbol, arrow-function] +---*/ + +let poisonedDone = {}; +let error = new Test262Error(); +Object.defineProperties(poisonedDone, { + done: { + get() { + throw error; + } + }, + value: { + get() { + $DONE('The `value` property should not be accessed.'); + } + } +}); +let iterStepThrows = { + [Symbol.iterator]() { + return { + next() { + return poisonedDone; + } + }; + } +}; + +Promise.any(iterStepThrows).then( + () => { + $DONE('The promise should be rejected.'); +}, (reason) => { + assert.sameValue(reason, error); +}).then($DONE, $DONE); diff --git a/test/built-ins/Promise/any/length.js b/test/built-ins/Promise/any/length.js new file mode 100644 index 0000000000..d043a88ede --- /dev/null +++ b/test/built-ins/Promise/any/length.js @@ -0,0 +1,28 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: Promise.any `length` property +info: | + ES Section 17: + Every built-in Function object, including constructors, has a length + property whose value is an integer. Unless otherwise specified, this value + is equal to the largest number of named arguments shown in the subclause + headings for the function description, including optional parameters. + + [...] + + Unless otherwise specified, the length property of a built-in Function + object has the attributes { [[Writable]]: false, [[Enumerable]]: false, + [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [Promise.any] +---*/ + +verifyProperty(Promise.any, 'length', { + configurable: true, + writable: false, + enumerable: false, + value: 1, +}); diff --git a/test/built-ins/Promise/any/name.js b/test/built-ins/Promise/any/name.js new file mode 100644 index 0000000000..91a0664eae --- /dev/null +++ b/test/built-ins/Promise/any/name.js @@ -0,0 +1,29 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: Promise.any `name` property +info: | + ES Section 17: + + Every built-in Function object, including constructors, that is not + identified as an anonymous function has a name property whose value is a + String. Unless otherwise specified, this value is the name that is given to + the function in this specification. + + [...] + + Unless otherwise specified, the name property of a built-in Function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [Promise.any] +---*/ + +verifyProperty(Promise.any, 'name', { + configurable: true, + writable: false, + enumerable: false, + value: 'any', +}); diff --git a/test/built-ins/Promise/any/new-reject-function.js b/test/built-ins/Promise/any/new-reject-function.js new file mode 100644 index 0000000000..b73cc82882 --- /dev/null +++ b/test/built-ins/Promise/any/new-reject-function.js @@ -0,0 +1,51 @@ +// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-performpromiseany +description: > + Each Promise.any element is called with a new Promise.any Reject Element function. +info: | + Runtime Semantics: PerformPromiseAny ( iteratorRecord, constructor, resultCapability ) + + ... + k. Let rejectElement be ! CreateBuiltinFunction(steps, « [[AlreadyCalled]], [[Index]], [[Errors]], [[Capability]], [[RemainingElements]] »). + ... + r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »). + ... + +features: [Promise.any] +---*/ + +function rejectFunction() {} + +function Constructor(executor) { + executor(rejectFunction, $ERROR); +} +Constructor.resolve = function(v) { + return v; +}; + +var callCount1 = 0; +var callCount2 = 0; +var p1OnRejected; + +var p1 = { + then(_, onRejected) { + callCount1 += 1; + p1OnRejected = onRejected; + assert.notSameValue(onRejected, rejectFunction, 'p1.then'); + } +}; +var p2 = { + then(_, onRejected) { + callCount2 += 1; + assert.notSameValue(onRejected, rejectFunction, 'p2.then'); + assert.notSameValue(onRejected, p1OnRejected, 'p1.onRejected != p2.onRejected'); + } +}; + +Promise.any.call(Constructor, [p1, p2]); +assert.sameValue(callCount1, 1, 'p1.then call count'); +assert.sameValue(callCount2, 1, 'p2.then call count'); + diff --git a/test/built-ins/Promise/any/prop-desc.js b/test/built-ins/Promise/any/prop-desc.js new file mode 100644 index 0000000000..d6676a40bc --- /dev/null +++ b/test/built-ins/Promise/any/prop-desc.js @@ -0,0 +1,21 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: Promise.any property descriptor +info: | + ES Section 17 + + Every other data property described in clauses 18 through 26 and in Annex + B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +includes: [propertyHelper.js] +features: [Promise.any] +---*/ + +verifyProperty(Promise, 'any', { + configurable: true, + writable: true, + enumerable: false, +}); diff --git a/test/built-ins/Promise/any/reject-all-mixed.js b/test/built-ins/Promise/any/reject-all-mixed.js new file mode 100644 index 0000000000..194f4eef18 --- /dev/null +++ b/test/built-ins/Promise/any/reject-all-mixed.js @@ -0,0 +1,26 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: > + Promise.any rejection reasons from various rejections are all present +flags: [async] +features: [Promise.any, arrow-function] +---*/ + +let rejections = [ + Promise.reject('a'), + new Promise((_, reject) => reject('b')), + Promise.all([Promise.reject('c')]), + Promise.resolve(Promise.reject('d')), +]; + +Promise.any(rejections) + .then( + () => $DONE('The promise should be rejected, but was resolved'), + error => { + assert.sameValue(error.errors.length, rejections.length); + assert.sameValue(error.errors.join(''), 'abcd'); + } + ).then($DONE, $DONE); diff --git a/test/built-ins/Promise/any/reject-deferred.js b/test/built-ins/Promise/any/reject-deferred.js new file mode 100644 index 0000000000..496fbff5ff --- /dev/null +++ b/test/built-ins/Promise/any/reject-deferred.js @@ -0,0 +1,31 @@ +// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-promise.any +description: Rejecting through deferred invocation of the provided resolving function +info: | + ... + 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability). + ... + + +flags: [async] +features: [AggregateError, Promise.any, arrow-function] +---*/ + +var rejection = {}; +var thenable = { + then(_, reject) { + new Promise((resolve) => resolve()) + .then(() => reject(rejection)); + } +}; + +Promise.any([thenable]) + .then(() => { + $DONE('The promise should be rejected.'); + }, (aggregate) => { + assert(aggregate instanceof AggregateError); + assert.sameValue(aggregate.errors.length, 1); + assert.sameValue(aggregate.errors[0], rejection); + }).then($DONE, $DONE); diff --git a/test/built-ins/Promise/any/reject-element-function-extensible.js b/test/built-ins/Promise/any/reject-element-function-extensible.js new file mode 100644 index 0000000000..030bc36835 --- /dev/null +++ b/test/built-ins/Promise/any/reject-element-function-extensible.js @@ -0,0 +1,29 @@ +// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any-reject-element-functions +description: The [[Extensible]] slot of Promise.any Reject Element functions +info: | + 17 ECMAScript Standard Built-in Objects: + Unless specified otherwise, the [[Extensible]] internal slot + of a built-in object initially has the value true. +features: [Promise.any] +---*/ + +var rejectElementFunction; +var thenable = { + then(_, reject) { + rejectElementFunction = reject; + } +}; + +function NotPromise(executor) { + executor(function() {}, function() {}); +} +NotPromise.resolve = function(v) { + return v; +}; +Promise.any.call(NotPromise, [thenable]); + +assert(Object.isExtensible(rejectElementFunction)); diff --git a/test/built-ins/Promise/any/reject-element-function-length.js b/test/built-ins/Promise/any/reject-element-function-length.js new file mode 100644 index 0000000000..15437ff73c --- /dev/null +++ b/test/built-ins/Promise/any/reject-element-function-length.js @@ -0,0 +1,40 @@ +// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any-reject-element-functions +description: The `length` property of Promise.any Reject Element functions +info: | + The length property of a Promise.any Reject Element function is 1. + + 17 ECMAScript Standard Built-in Objects: + Unless otherwise specified, the length property of a built-in Function + object has the attributes { [[Writable]]: false, [[Enumerable]]: false, + [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [Promise.any] +---*/ + +var rejectElementFunction; +var thenable = { + then(_, reject) { + rejectElementFunction = reject; + } +}; + +function NotPromise(executor) { + executor(function() {}, function() {}); +} +NotPromise.resolve = function(v) { + return v; +}; +Promise.any.call(NotPromise, [thenable]); + +assert.sameValue(rejectElementFunction.length, 1); + +verifyProperty(rejectElementFunction, 'length', { + value: 1, + enumerable: false, + writable: false, + configurable: true, +}); diff --git a/test/built-ins/Promise/any/reject-element-function-name.js b/test/built-ins/Promise/any/reject-element-function-name.js new file mode 100644 index 0000000000..9487836134 --- /dev/null +++ b/test/built-ins/Promise/any/reject-element-function-name.js @@ -0,0 +1,39 @@ +// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any-reject-element-functions +description: The `name` property of Promise.any Reject Element functions +info: | + A promise resolve function is an anonymous built-in function. + + 17 ECMAScript Standard Built-in Objects: + Every built-in function object, including constructors, has a `name` + property whose value is a String. Functions that are identified as + anonymous functions use the empty string as the value of the `name` + property. + Unless otherwise specified, the `name` property of a built-in function + object has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, + [[Configurable]]: *true* }. +includes: [propertyHelper.js] +features: [Promise.any] +---*/ + +var rejectElementFunction; +var thenable = { + then(_, reject) { + rejectElementFunction = reject; + } +}; + +function NotPromise(executor) { + executor(function() {}, function() {}); +} +NotPromise.resolve = function(v) { + return v; +}; +Promise.any.call(NotPromise, [thenable]); + +verifyProperty(rejectElementFunction, "name", { + value: "", writable: false, enumerable: false, configurable: true +}); diff --git a/test/built-ins/Promise/any/reject-element-function-nonconstructor.js b/test/built-ins/Promise/any/reject-element-function-nonconstructor.js new file mode 100644 index 0000000000..687e96c8bb --- /dev/null +++ b/test/built-ins/Promise/any/reject-element-function-nonconstructor.js @@ -0,0 +1,33 @@ +// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any-reject-element-functions +description: Promise.any Reject Element functions are not constructors +info: | + 17 ECMAScript Standard Built-in Objects: + Built-in function objects that are not identified as constructors do not + implement the [[Construct]] internal method unless otherwise specified + in the description of a particular function. +features: [Promise.any] +---*/ + +var rejectElementFunction; +var thenable = { + then(_, reject) { + rejectElementFunction = reject; + } +}; + +function NotPromise(executor) { + executor(function() {}, function() {}); +} +NotPromise.resolve = function(v) { + return v; +}; +Promise.any.call(NotPromise, [thenable]); + +assert.sameValue(Object.prototype.hasOwnProperty.call(rejectElementFunction, 'prototype'), false); +assert.throws(TypeError, function() { + new rejectElementFunction(); +}); diff --git a/test/built-ins/Promise/any/reject-element-function-prototype.js b/test/built-ins/Promise/any/reject-element-function-prototype.js new file mode 100644 index 0000000000..b2e1369be6 --- /dev/null +++ b/test/built-ins/Promise/any/reject-element-function-prototype.js @@ -0,0 +1,31 @@ +// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any-reject-element-functions +description: The [[Prototype]] of Promise.any Reject Element functions +info: | + 17 ECMAScript Standard Built-in Objects: + Unless otherwise specified every built-in function and every built-in + constructor has the Function prototype object, which is the initial + value of the expression Function.prototype (19.2.3), as the value of + its [[Prototype]] internal slot. +features: [Promise.any] +---*/ + +var rejectElementFunction; +var thenable = { + then(_, reject) { + rejectElementFunction = reject; + } +}; + +function NotPromise(executor) { + executor(function() {}, function() {}); +} +NotPromise.resolve = function(v) { + return v; +}; +Promise.any.call(NotPromise, [thenable]); + +assert.sameValue(Object.getPrototypeOf(rejectElementFunction), Function.prototype); diff --git a/test/built-ins/Promise/any/resolve-from-reject-catch.js b/test/built-ins/Promise/any/resolve-from-reject-catch.js new file mode 100644 index 0000000000..bbefced968 --- /dev/null +++ b/test/built-ins/Promise/any/resolve-from-reject-catch.js @@ -0,0 +1,22 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: > + Promise.any resolves with the first item that does not reject. +flags: [async] +features: [Promise.any, arrow-function] +---*/ + +let fulfillables = [ + Promise.reject('a'), + new Promise((resolve, reject) => reject('b')), + Promise.all([Promise.reject('c')]), + Promise.reject('d').catch(v => v), +]; + +Promise.any(fulfillables) + .then((resolution) => { + assert.sameValue(resolution, 'd'); + }).then($DONE, $DONE); diff --git a/test/built-ins/Promise/any/resolve-from-resolve-reject-catch.js b/test/built-ins/Promise/any/resolve-from-resolve-reject-catch.js new file mode 100644 index 0000000000..e5f97d7efd --- /dev/null +++ b/test/built-ins/Promise/any/resolve-from-resolve-reject-catch.js @@ -0,0 +1,22 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: > + Promise.any resolves with the first item that does not reject. +flags: [async] +features: [Promise.any, arrow-function] +---*/ + +let fulfillables = [ + Promise.reject('a'), + new Promise((resolve, reject) => reject('b')), + Promise.all([Promise.reject('c')]), + Promise.resolve(Promise.reject('d').catch(v => v)), +]; + +Promise.any(fulfillables) + .then((resolution) => { + assert.sameValue(resolution, 'd'); + }).then($DONE, $DONE); diff --git a/test/built-ins/Promise/any/resolve-ignores-late-rejection-deferred.js b/test/built-ins/Promise/any/resolve-ignores-late-rejection-deferred.js new file mode 100644 index 0000000000..e49303cfc0 --- /dev/null +++ b/test/built-ins/Promise/any/resolve-ignores-late-rejection-deferred.js @@ -0,0 +1,41 @@ +// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Resolved promises ignore rejections through deferred invocation of the + provided resolving function +esid: sec-promise.any +info: | + 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability). + + Runtime Semantics: PerformPromiseAny + + 8. Repeat + ... + r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »). + +flags: [async] +features: [Promise.any, arrow-function] +---*/ + +var resolver = { + then(resolve) { + new Promise((resolve) => resolve()) + .then(() => resolve(42)); + } +}; +var lateRejector = { + then(resolve, reject) { + new Promise((resolve) => resolve()) + .then(() => { + resolve(9); + reject(); + }); + } +}; + +Promise.any([resolver, lateRejector]) + .then(resolution => { + assert.sameValue(resolution, 42); + }).then($DONE, $DONE); diff --git a/test/built-ins/Promise/any/resolve-ignores-late-rejection.js b/test/built-ins/Promise/any/resolve-ignores-late-rejection.js new file mode 100644 index 0000000000..fca6653525 --- /dev/null +++ b/test/built-ins/Promise/any/resolve-ignores-late-rejection.js @@ -0,0 +1,37 @@ +// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Resolved promises ignore rejections through immediate invocation of the + provided resolving function +esid: sec-promise.any +info: | + 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability). + + Runtime Semantics: PerformPromiseAny + + 8. Repeat + ... + r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »). + +flags: [async] +features: [Promise.any, arrow-function] +---*/ + +var resolver = { + then(resolve) { + resolve(42); + } +}; +var lateRejector = { + then(resolve, reject) { + resolve(33); + reject(); + } +}; + +Promise.any([resolver, lateRejector]) + .then(resolution => { + assert.sameValue(resolution, 42); + }).then($DONE, $DONE); diff --git a/test/built-ins/Promise/any/returns-promise.js b/test/built-ins/Promise/any/returns-promise.js new file mode 100644 index 0000000000..745696fec6 --- /dev/null +++ b/test/built-ins/Promise/any/returns-promise.js @@ -0,0 +1,24 @@ +// Copyright (C) 2019 Sergey Rubanov. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.any +description: Promise.any returns a Promise +info: | + Promise.any ( iterable ) + + 2. Let promiseCapability be ? NewPromiseCapability(C). + 3. Let iteratorRecord be GetIterator(iterable). + 4. IfAbruptRejectPromise(iteratorRecord, promiseCapability). + 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability). + 6. If result is an abrupt completion, then + a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result). + b. IfAbruptRejectPromise(result, promiseCapability). + 7. Return Completion(result). +features: [Promise.any] +---*/ + +var p = Promise.any([]); + +assert(p instanceof Promise); +assert.sameValue(Object.getPrototypeOf(p), Promise.prototype);