diff --git a/test/built-ins/Promise/all/invoke-resolve-on-promises-every-iteration-of-custom.js b/test/built-ins/Promise/all/invoke-resolve-on-promises-every-iteration-of-custom.js new file mode 100644 index 0000000000..cfb44d4f89 --- /dev/null +++ b/test/built-ins/Promise/all/invoke-resolve-on-promises-every-iteration-of-custom.js @@ -0,0 +1,43 @@ +// Copyright (C) 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 for iterable with promise values +esid: sec-promise.all +info: | + Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + + Runtime Semantics: PerformPromiseAll + + Repeat + ... + Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »). + +flags: [async] +features: [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.all.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/all/invoke-resolve-on-promises-every-iteration-of-promise.js b/test/built-ins/Promise/all/invoke-resolve-on-promises-every-iteration-of-promise.js new file mode 100644 index 0000000000..f3f682cb55 --- /dev/null +++ b/test/built-ins/Promise/all/invoke-resolve-on-promises-every-iteration-of-promise.js @@ -0,0 +1,34 @@ +// Copyright (C) 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 for iterable with promise values +esid: sec-promise.all +info: | + Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + + Runtime Semantics: PerformPromiseAll + + Repeat + ... + i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »). + +flags: [async] +features: [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.all(values) + .then(() => { + assert.sameValue(callCount, 3, '`then` invoked once for every iterated promise'); + }, $DONE).then($DONE, $DONE); + diff --git a/test/built-ins/Promise/all/invoke-resolve-on-values-every-iteration-of-promise.js b/test/built-ins/Promise/all/invoke-resolve-on-values-every-iteration-of-promise.js new file mode 100644 index 0000000000..8524bca54c --- /dev/null +++ b/test/built-ins/Promise/all/invoke-resolve-on-values-every-iteration-of-promise.js @@ -0,0 +1,34 @@ +// Copyright (C) 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 for iterable with non-promise values +esid: sec-promise.all +info: | + Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + + Runtime Semantics: PerformPromiseAll + + Repeat + ... + i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »). + +flags: [async] +features: [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.all(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/all/resolve-ignores-late-rejection-deferred.js b/test/built-ins/Promise/all/resolve-ignores-late-rejection-deferred.js new file mode 100644 index 0000000000..8f2beef58b --- /dev/null +++ b/test/built-ins/Promise/all/resolve-ignores-late-rejection-deferred.js @@ -0,0 +1,42 @@ +// 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: | + Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + + Runtime Semantics: PerformPromiseAll + + Repeat + ... + r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »). + +flags: [async] +features: [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.all([resolver, lateRejector]) + .then(resolution => { + assert.sameValue(resolution[0], 42); + assert.sameValue(resolution[1], 9); + }).then($DONE, $DONE); diff --git a/test/built-ins/Promise/all/resolve-ignores-late-rejection.js b/test/built-ins/Promise/all/resolve-ignores-late-rejection.js new file mode 100644 index 0000000000..7e23a3b892 --- /dev/null +++ b/test/built-ins/Promise/all/resolve-ignores-late-rejection.js @@ -0,0 +1,38 @@ +// 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.all +info: | + Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + + Runtime Semantics: PerformPromiseAll + + Repeat + ... + r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »). + +flags: [async] +features: [arrow-function] +---*/ + +var resolver = { + then(resolve) { + resolve(42); + } +}; +var lateRejector = { + then(resolve, reject) { + resolve(33); + reject(); + } +}; + +Promise.all([resolver, lateRejector]) + .then(resolution => { + assert.sameValue(resolution[0], 42); + assert.sameValue(resolution[1], 33); + }).then($DONE, $DONE); diff --git a/test/built-ins/Promise/all/resolve-not-callable-reject-with-typeerror.js b/test/built-ins/Promise/all/resolve-not-callable-reject-with-typeerror.js new file mode 100644 index 0000000000..d30242af3d --- /dev/null +++ b/test/built-ins/Promise/all/resolve-not-callable-reject-with-typeerror.js @@ -0,0 +1,28 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +description: > + If the constructor's `resolve` method is not callable, reject with a TypeError. +info: | + Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability). + + Runtime Semantics: PerformPromiseAny + + Let promiseResolve be ? Get(constructor, "resolve"). + If ! IsCallable(promiseResolve) is false, throw a TypeError exception. + +flags: [async] +features: [arrow-function] +---*/ + +Promise.resolve = null; + +Promise.all([1]) + .then( + () => $DONE('The promise should not be resolved.'), + error => { + assert(error instanceof TypeError); + } + ).then($DONE, $DONE); diff --git a/test/built-ins/Promise/allSettled/invoke-resolve-on-promises-every-iteration-of-custom.js b/test/built-ins/Promise/allSettled/invoke-resolve-on-promises-every-iteration-of-custom.js new file mode 100644 index 0000000000..26d06477d1 --- /dev/null +++ b/test/built-ins/Promise/allSettled/invoke-resolve-on-promises-every-iteration-of-custom.js @@ -0,0 +1,43 @@ +// Copyright (C) 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 for iterable with promise values +esid: sec-promise.allSettled +info: | + 7. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability). + + Runtime Semantics: PerformPromiseAllSettled + + 7. Repeat + ... + i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »). + +flags: [async] +features: [Promise.allSettled, 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.allSettled.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/allSettled/invoke-resolve-on-promises-every-iteration-of-promise.js b/test/built-ins/Promise/allSettled/invoke-resolve-on-promises-every-iteration-of-promise.js new file mode 100644 index 0000000000..05d53bffb2 --- /dev/null +++ b/test/built-ins/Promise/allSettled/invoke-resolve-on-promises-every-iteration-of-promise.js @@ -0,0 +1,34 @@ +// Copyright (C) 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 for iterable with promise values +esid: sec-promise.allSettled +info: | + 7. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability). + + Runtime Semantics: PerformPromiseAllSettled + + 7. Repeat + ... + i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »). + +flags: [async] +features: [Promise.allSettled, 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.allSettled(values) + .then(() => { + assert.sameValue(callCount, 3, '`then` invoked once for every iterated promise'); + }, $DONE).then($DONE, $DONE); + diff --git a/test/built-ins/Promise/allSettled/invoke-resolve-on-values-every-iteration-of-promise.js b/test/built-ins/Promise/allSettled/invoke-resolve-on-values-every-iteration-of-promise.js new file mode 100644 index 0000000000..92df13be3a --- /dev/null +++ b/test/built-ins/Promise/allSettled/invoke-resolve-on-values-every-iteration-of-promise.js @@ -0,0 +1,34 @@ +// Copyright (C) 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 for iterable with non-promise values +esid: sec-promise.allSettled +info: | + 5. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability). + + Runtime Semantics: PerformPromiseAllSettled + + 8. Repeat + ... + i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »). + +flags: [async] +features: [Promise.allSettled, 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.allSettled(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/allSettled/resolve-ignores-late-rejection-deferred.js b/test/built-ins/Promise/allSettled/resolve-ignores-late-rejection-deferred.js new file mode 100644 index 0000000000..a8b89a4655 --- /dev/null +++ b/test/built-ins/Promise/allSettled/resolve-ignores-late-rejection-deferred.js @@ -0,0 +1,44 @@ +// 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.allSettled +info: | + Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability). + + Runtime Semantics: PerformPromiseAllSettled + + Repeat + ... + r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »). + +flags: [async] +features: [Promise.allSettled, 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.allSettled([resolver, lateRejector]) + .then(resolution => { + assert.sameValue(resolution[0].value, 42); + assert.sameValue(resolution[0].status, 'fulfilled'); + assert.sameValue(resolution[1].value, 9); + assert.sameValue(resolution[1].status, 'fulfilled'); + }).then($DONE, $DONE); diff --git a/test/built-ins/Promise/allSettled/resolve-ignores-late-rejection.js b/test/built-ins/Promise/allSettled/resolve-ignores-late-rejection.js new file mode 100644 index 0000000000..884883a5f5 --- /dev/null +++ b/test/built-ins/Promise/allSettled/resolve-ignores-late-rejection.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. + +/*--- +description: > + Resolved promises ignore rejections through immediate invocation of the + provided resolving function +esid: sec-promise.allSettled +info: | + Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability). + + Runtime Semantics: PerformPromiseAllSettled + + Repeat + ... + r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »). + +flags: [async] +features: [Promise.allSettled, arrow-function] +---*/ + +var resolver = { + then(resolve) { + resolve(42); + } +}; +var lateRejector = { + then(resolve, reject) { + resolve(33); + reject(); + } +}; + +Promise.allSettled([resolver, lateRejector]) + .then(resolution => { + assert.sameValue(resolution[0].value, 42); + assert.sameValue(resolution[0].status, 'fulfilled'); + assert.sameValue(resolution[1].value, 33); + assert.sameValue(resolution[1].status, 'fulfilled'); + }).then($DONE, $DONE); diff --git a/test/built-ins/Promise/allSettled/resolve-not-callable-reject-with-typeerror.js b/test/built-ins/Promise/allSettled/resolve-not-callable-reject-with-typeerror.js new file mode 100644 index 0000000000..42180b8fc2 --- /dev/null +++ b/test/built-ins/Promise/allSettled/resolve-not-callable-reject-with-typeerror.js @@ -0,0 +1,28 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.allSettled +description: > + If the constructor's `resolve` method is not callable, reject with a TypeError. +info: | + Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability). + + Runtime Semantics: PerformPromiseAllSettled + + Let promiseResolve be ? Get(constructor, "resolve"). + If ! IsCallable(promiseResolve) is false, throw a TypeError exception. + +flags: [async] +features: [Promise.allSettled, arrow-function] +---*/ + +Promise.resolve = null; + +Promise.allSettled([1]) + .then( + () => $DONE('The promise should not be resolved.'), + error => { + assert(error instanceof TypeError); + } + ).then($DONE, $DONE);