diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /js/src/tests/test262/built-ins/Promise/all | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/tests/test262/built-ins/Promise/all')
98 files changed, 3991 insertions, 0 deletions
diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A1.1_T1.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A1.1_T1.js new file mode 100644 index 0000000000..1cf29b6a21 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A1.1_T1.js @@ -0,0 +1,12 @@ +// Copyright 2014 Cubane Canada, Inc. All rights reserved. +// See LICENSE for details. + +/*--- +info: Promise.all is callable +es6id: 25.4.4.1_A1.1_T1 +author: Sam Mikes +description: Promise.all is callable +---*/ +assert.sameValue(typeof Promise.all, "function", 'The value of `typeof Promise.all` is expected to be "function"'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.1_T1.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.1_T1.js new file mode 100644 index 0000000000..5d27aaab35 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.1_T1.js @@ -0,0 +1,14 @@ +// Copyright 2014 Cubane Canada, Inc. All rights reserved. +// See LICENSE for details. + +/*--- +info: Promise.all([]) is a Promise +es6id: 25.4.4.1_A2.1_T1 +author: Sam Mikes +description: Promise.all returns a Promise +---*/ + +var p = Promise.all([]); +assert(!!(p instanceof Promise), 'The value of !!(p instanceof Promise) is expected to be true'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.2_T1.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.2_T1.js new file mode 100644 index 0000000000..8a3eaceae9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.2_T1.js @@ -0,0 +1,28 @@ +// |reftest| async +// Copyright 2014 Cubane Canada, Inc. All rights reserved. +// See LICENSE for details. + +/*--- +info: Promise.all([]) is resolved immediately +es6id: 25.4.4.1_A2.2_T1 +author: Sam Mikes +includes: [promiseHelper.js] +description: Promise.all([]) returns immediately +flags: [async] +---*/ + +var sequence = []; + +Promise.all([]).then(function() { + sequence.push(2); +}).catch($DONE); + +Promise.resolve().then(function() { + sequence.push(3); +}).then(function() { + sequence.push(4); + assert.sameValue(sequence.length, 4); + checkSequence(sequence, "Promises resolved in unexpected sequence"); +}).then($DONE, $DONE); + +sequence.push(1); diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.3_T1.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.3_T1.js new file mode 100644 index 0000000000..c737bb4f99 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.3_T1.js @@ -0,0 +1,17 @@ +// |reftest| async +// Copyright 2014 Cubane Canada, Inc. All rights reserved. +// See LICENSE for details. + +/*--- +info: Promise.all([]) returns a promise for a new empty array +es6id: 25.4.4.1_A2.3_T1 +author: Sam Mikes +description: Promise.all([]) returns a promise for an array +flags: [async] +---*/ + +var arg = []; + +Promise.all(arg).then(function(result) { + assert(!!(result instanceof Array), 'The value of !!(result instanceof Array) is expected to be true'); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.3_T2.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.3_T2.js new file mode 100644 index 0000000000..ad9bfa6c48 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.3_T2.js @@ -0,0 +1,17 @@ +// |reftest| async +// Copyright 2014 Cubane Canada, Inc. All rights reserved. +// See LICENSE for details. + +/*--- +info: Promise.all is resolved with a new empty array +es6id: 25.4.4.1_A2.3_T2 +author: Sam Mikes +description: Promise.all([]) returns a Promise for an empty array +flags: [async] +---*/ + +var arg = []; + +Promise.all(arg).then(function(result) { + assert.sameValue(result.length, 0, 'The value of result.length is expected to be 0'); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.3_T3.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.3_T3.js new file mode 100644 index 0000000000..09b598f3fc --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.3_T3.js @@ -0,0 +1,17 @@ +// |reftest| async +// Copyright 2014 Cubane Canada, Inc. All rights reserved. +// See LICENSE for details. + +/*--- +info: Promise.all([]) is resolved with Promise for a new empty array +es6id: 25.4.4.1_A2.3_T3 +author: Sam Mikes +description: Promise.all([]) is resolved with a Promise for a new array +flags: [async] +---*/ + +var arg = []; + +Promise.all(arg).then(function(result) { + assert.notSameValue(result, arg, 'The value of result is expected to not equal the value of `arg`'); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A3.1_T1.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A3.1_T1.js new file mode 100644 index 0000000000..88e7558c3d --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A3.1_T1.js @@ -0,0 +1,22 @@ +// |reftest| async +// Copyright 2014 Cubane Canada, Inc. All rights reserved. +// See LICENSE for details. + +/*--- +info: | + Promise.all expects an iterable argument; + ref 7.4.1 non-Object fails CheckIterable + ref 7.4.2 GetIterator throws TypeError if CheckIterable fails +es6id: 25.4.4.1_A3.1_T1 +author: Sam Mikes +description: Promise.all(3) returns Promise rejected with TypeError +flags: [async] +---*/ + +var nonIterable = 3; + +Promise.all(nonIterable).then(function() { + throw new Test262Error('Promise unexpectedly resolved: Promise.all(nonIterable) should throw TypeError'); +}, function(err) { + assert(!!(err instanceof TypeError), 'The value of !!(err instanceof TypeError) is expected to be true'); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A3.1_T2.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A3.1_T2.js new file mode 100644 index 0000000000..23c5d8390d --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A3.1_T2.js @@ -0,0 +1,21 @@ +// |reftest| async +// Copyright 2014 Cubane Canada, Inc. All rights reserved. +// See LICENSE for details. + +/*--- +info: | + Promise.all expects an iterable argument; + fails if recieves an abrupt completion + ref 7.4.1 non-Object fails CheckIterable + ref 7.4.2 GetIterator throws TypeError if CheckIterable fails +es6id: S25.4.4.1_A3.1_T2 +author: Sam Mikes +description: Promise.all(new Error()) returns Promise rejected with TypeError +flags: [async] +---*/ + +Promise.all(new Error("abrupt")).then(function() { + throw new Test262Error('Promise unexpectedly resolved: Promise.all(abruptCompletion) should throw TypeError'); +}, function(err) { + assert(!!(err instanceof TypeError), 'The value of !!(err instanceof TypeError) is expected to be true'); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A3.1_T3.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A3.1_T3.js new file mode 100644 index 0000000000..9a93d8bd9f --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A3.1_T3.js @@ -0,0 +1,27 @@ +// |reftest| async +// Copyright 2014 Cubane Canada, Inc. All rights reserved. +// See LICENSE for details. + +/*--- +info: | + Promise.all expects an iterable argument; + fails if GetIterator returns an abrupt completion. +es6id: S25.4.4.1_A3.1_T3 +author: Sam Mikes +description: Promise.all((throw on GetIterator)) returns Promise rejected with TypeError +features: [Symbol.iterator] +flags: [async] +---*/ + +var iterThrows = {}; +Object.defineProperty(iterThrows, Symbol.iterator, { + get: function() { + throw new Error("abrupt completion"); + } +}); + +Promise.all(iterThrows).then(function() { + throw new Test262Error('Promise unexpectedly fulfilled: Promise.all(iterThrows) should throw TypeError'); +}, function(err) { + assert(!!(err instanceof Error), 'The value of !!(err instanceof Error) is expected to be true'); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A4.1_T1.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A4.1_T1.js new file mode 100644 index 0000000000..e63ccb33c7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A4.1_T1.js @@ -0,0 +1,18 @@ +// Copyright 2014 Cubane Canada, Inc. All rights reserved. +// See LICENSE for details. + +/*--- +info: | + Promise.all should throw if 'this' does not conform to Promise constructor +es6id: S25.4.4.1_A4.1_T1 +description: this must conform to Promise constructor in Promise.all +author: Sam Mikes +---*/ + +function ZeroArgConstructor() {} + +assert.throws(TypeError, function() { + Promise.all.call(ZeroArgConstructor, []); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A5.1_T1.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A5.1_T1.js new file mode 100644 index 0000000000..b670d9e937 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A5.1_T1.js @@ -0,0 +1,30 @@ +// |reftest| async +// Copyright 2014 Cubane Canada, Inc. All rights reserved. +// See LICENSE for details. + +/*--- +info: | + Promise.all expects an iterable argument; + rejects if IteratorStep() throws +es6id: S25.4.4.1_A5.1_T1 +author: Sam Mikes +description: iterator.next throws, causing Promise.all to reject +features: [Symbol.iterator] +flags: [async] +---*/ + +var iterThrows = {}; +var error = new Test262Error(); +iterThrows[Symbol.iterator] = function() { + return { + next: function() { + throw error; + } + }; +}; + +Promise.all(iterThrows).then(function() { + throw new Test262Error('Promise unexpectedly resolved: Promise.all(iterThrows) should throw TypeError'); +}, function(reason) { + assert.sameValue(reason, error, 'The value of reason is expected to equal the value of error'); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A7.1_T1.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A7.1_T1.js new file mode 100644 index 0000000000..0cc08b3f2a --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A7.1_T1.js @@ -0,0 +1,24 @@ +// |reftest| async +// Copyright 2014 Cubane Canada, Inc. All rights reserved. +// See LICENSE for details. + +/*--- +info: | + Promise.all with 1-element array + should accept an array with settled promise +es6id: S25.4.4.1_A6.1_T2 +author: Sam Mikes +description: Promise.all([p1]) is resolved with a promise for a one-element array +flags: [async] +---*/ + +var p1 = Promise.resolve(3); + +var pAll = Promise.all([p1]); + +pAll.then(function(result) { + assert(!!(pAll instanceof Promise), 'The value of !!(pAll instanceof Promise) is expected to be true'); + assert(!!(result instanceof Array), 'The value of !!(result instanceof Array) is expected to be true'); + assert.sameValue(result.length, 1, 'The value of result.length is expected to be 1'); + assert.sameValue(result[0], 3, 'The value of result[0] is expected to be 3'); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A7.2_T1.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A7.2_T1.js new file mode 100644 index 0000000000..19e00ba2a4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A7.2_T1.js @@ -0,0 +1,40 @@ +// |reftest| async +// Copyright 2014 Cubane Canada, Inc. All rights reserved. +// See LICENSE for details. + +/*--- +info: | + Promise.all with 1-element array + should accept an array with settled promise +es6id: S25.4.4.1_A7.2_T1 +author: Sam Mikes +description: Promise.all() accepts a one-element array +includes: [promiseHelper.js] +flags: [async] +---*/ + +var sequence = []; + +var p1 = new Promise(function(resolve) { + resolve({}); +}); + +sequence.push(1); + +Promise.all([p1]).then(function(resolved) { + sequence.push(4); + assert.sameValue(sequence.length, 4); + checkSequence(sequence, "Expected Promise.all().then to queue second"); +}).catch($DONE); + +p1.then(function() { + sequence.push(3); + assert.sameValue(sequence.length, 3); + checkSequence(sequence, "Expected p1.then to queue first"); +}).then(function() { + sequence.push(5); + assert.sameValue(sequence.length, 5); + checkSequence(sequence, "Expected final then to queue last"); +}).then($DONE, $DONE); + +sequence.push(2); diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A8.1_T1.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A8.1_T1.js new file mode 100644 index 0000000000..89e246e08e --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A8.1_T1.js @@ -0,0 +1,42 @@ +// |reftest| async +// Copyright 2014 Cubane Canada, Inc. All rights reserved. +// See LICENSE for details. + +/*--- +es6id: S25.4.4.1_A8.1_T1 +author: Sam Mikes +description: Promise.all([p1, p2]) resolution functions are called in predictable sequence +includes: [promiseHelper.js] +flags: [async] +---*/ + +var sequence = []; + +var p1 = new Promise(function(resolve) { + resolve(1); +}); +var p2 = new Promise(function(resolve) { + resolve(2); +}); + +sequence.push(1); + +p1.then(function() { + sequence.push(3); + assert.sameValue(sequence.length, 3); + checkSequence(sequence, "Expected to be called first."); +}).catch($DONE); + +Promise.all([p1, p2]).then(function() { + sequence.push(5); + assert.sameValue(sequence.length, 5); + checkSequence(sequence, "Expected to be called third."); +}).then($DONE, $DONE); + +p2.then(function() { + sequence.push(4); + assert.sameValue(sequence.length, 4); + checkSequence(sequence, "Expected to be called second."); +}).catch($DONE); + +sequence.push(2); diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A8.2_T1.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A8.2_T1.js new file mode 100644 index 0000000000..d5ffb354d8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A8.2_T1.js @@ -0,0 +1,26 @@ +// |reftest| async +// Copyright 2014 Cubane Canada, Inc. All rights reserved. +// See LICENSE for details. + +/*--- +info: | + Promise.all with 2-element array +es6id: S25.4.4.1_A8.1_T1 +author: Sam Mikes +description: Promise.all() rejects when a promise in its array rejects +flags: [async] +---*/ + +var rejectP1, + p1 = new Promise(function(resolve, reject) { + rejectP1 = reject; + }), + p2 = Promise.resolve(2); + +Promise.all([p1, p2]).then(function(resolve) { + throw new Test262Error("Did not expect promise to be fulfilled."); +}, function(rejected) { + assert.sameValue(rejected, 1, 'The value of rejected is expected to be 1'); +}).then($DONE, $DONE); + +rejectP1(1); diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A8.2_T2.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A8.2_T2.js new file mode 100644 index 0000000000..71390b4c71 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A8.2_T2.js @@ -0,0 +1,26 @@ +// |reftest| async +// Copyright 2014 Cubane Canada, Inc. All rights reserved. +// See LICENSE for details. + +/*--- +info: | + Promise.all with 2-element array +es6id: S25.4.4.1_A8.2_T2 +author: Sam Mikes +description: Promise.all() rejects when second promise in array rejects +flags: [async] +---*/ + +var rejectP2, + p1 = Promise.resolve(1), + p2 = new Promise(function(resolve, reject) { + rejectP2 = reject; + }); + +Promise.all([p1, p2]).then(function() { + throw new Test262Error("Did not expect promise to be fulfilled."); +}, function(rejected) { + assert.sameValue(rejected, 2, 'The value of rejected is expected to be 2'); +}).then($DONE, $DONE); + +rejectP2(2); diff --git a/js/src/tests/test262/built-ins/Promise/all/browser.js b/js/src/tests/test262/built-ins/Promise/all/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/browser.js diff --git a/js/src/tests/test262/built-ins/Promise/all/call-resolve-element-after-return.js b/js/src/tests/test262/built-ins/Promise/all/call-resolve-element-after-return.js new file mode 100644 index 0000000000..0204c9b790 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/call-resolve-element-after-return.js @@ -0,0 +1,55 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es6id: 25.4.4.1.2 +description: > + Cannot change result value of resolved Promise.all element after Promise.all() returned. +info: | + Promise.all Resolve Element Functions + + 1. Let alreadyCalled be the value of F's [[AlreadyCalled]] internal slot. + 2. If alreadyCalled.[[value]] is true, return undefined. + 3. Set alreadyCalled.[[value]] to true. + ... +---*/ + +var callCount = 0; +var valuesArray; + +function Constructor(executor) { + function resolve(values) { + callCount += 1; + valuesArray = values; + assert(Array.isArray(values), "values is array"); + assert.sameValue(values.length, 1, "values.length"); + assert.sameValue(values[0], "expectedValue", "values[0]"); + } + executor(resolve, Test262Error.thrower); +} +Constructor.resolve = function(v) { + return v; +}; + +var p1OnFulfilled; + +var p1 = { + then: function(onFulfilled, onRejected) { + p1OnFulfilled = onFulfilled; + onFulfilled("expectedValue"); + } +}; + +assert.sameValue(callCount, 0, "callCount before call to all()"); + +Promise.all.call(Constructor, [p1]); + +assert.sameValue(callCount, 1, "callCount after call to all()"); +assert.sameValue(valuesArray[0], "expectedValue", "valuesArray after call to all()"); + +p1OnFulfilled("unexpectedValue"); + +assert.sameValue(callCount, 1, "callCount after call to onFulfilled()"); +assert.sameValue(valuesArray[0], "expectedValue", "valuesArray after call to onFulfilled()"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/call-resolve-element-items.js b/js/src/tests/test262/built-ins/Promise/all/call-resolve-element-items.js new file mode 100644 index 0000000000..19d0ad3f45 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/call-resolve-element-items.js @@ -0,0 +1,52 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es6id: 25.4.4.1.2 +description: > + Cannot change result value of resolved Promise.all elements. +info: | + Promise.all Resolve Element Functions + + 1. Let alreadyCalled be the value of F's [[AlreadyCalled]] internal slot. + 2. If alreadyCalled.[[value]] is true, return undefined. + 3. Set alreadyCalled.[[value]] to true. + ... +---*/ + +var callCount = 0; + +function Constructor(executor) { + function resolve(values) { + callCount += 1; + assert(Array.isArray(values), "values is array"); + assert.sameValue(values.length, 2, "values length"); + assert.sameValue(values[0], "expectedValue-p1", "values[0]"); + assert.sameValue(values[1], "expectedValue-p2", "values[1]"); + } + executor(resolve, Test262Error.thrower); +} +Constructor.resolve = function(v) { + return v; +}; + +var p1 = { + then: function(onFulfilled, onRejected) { + onFulfilled("expectedValue-p1"); + onFulfilled("unexpectedValue-p1"); + } +}; +var p2 = { + then: function(onFulfilled, onRejected) { + onFulfilled("expectedValue-p2"); + onFulfilled("unexpectedValue-p2"); + } +}; + +assert.sameValue(callCount, 0, "callCount before call to all()"); + +Promise.all.call(Constructor, [p1, p2]); + +assert.sameValue(callCount, 1, "callCount after call to all()"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/call-resolve-element.js b/js/src/tests/test262/built-ins/Promise/all/call-resolve-element.js new file mode 100644 index 0000000000..c559e30e8d --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/call-resolve-element.js @@ -0,0 +1,45 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es6id: 25.4.4.1.2 +description: > + Cannot change result value of resolved Promise.all element. +info: | + Promise.all Resolve Element Functions + + 1. Let alreadyCalled be the value of F's [[AlreadyCalled]] internal slot. + 2. If alreadyCalled.[[value]] is true, return undefined. + 3. Set alreadyCalled.[[value]] to true. + ... +---*/ + +var callCount = 0; + +function Constructor(executor) { + function resolve(values) { + callCount += 1; + assert(Array.isArray(values), "values is array"); + assert.sameValue(values.length, 1, "values length"); + assert.sameValue(values[0], "expectedValue", "values[0]"); + } + executor(resolve, Test262Error.thrower); +} +Constructor.resolve = function(v) { + return v; +}; + +var p1 = { + then: function(onFulfilled, onRejected) { + onFulfilled("expectedValue"); + onFulfilled("unexpectedValue"); + } +}; + +assert.sameValue(callCount, 0, "callCount before call to all()"); + +Promise.all.call(Constructor, [p1]); + +assert.sameValue(callCount, 1, "callCount after call to all()"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/capability-executor-called-twice.js b/js/src/tests/test262/built-ins/Promise/all/capability-executor-called-twice.js new file mode 100644 index 0000000000..992f6cb1c2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/capability-executor-called-twice.js @@ -0,0 +1,104 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +description: > + Throws a TypeError if capabilities executor already called with non-undefined values. +info: | + Promise.all ( iterable ) + + ... + 6. Let promiseCapability be NewPromiseCapability(C). + 7. ReturnIfAbrupt(promiseCapability). + ... + + GetCapabilitiesExecutor Functions + ... + 3. If promiseCapability.[[Resolve]] is not undefined, throw a TypeError exception. + 4. If promiseCapability.[[Reject]] is not undefined, throw a TypeError exception. + 5. Set promiseCapability.[[Resolve]] to resolve. + 6. Set promiseCapability.[[Reject]] to reject. + ... + + PerformPromiseAll ( iteratorRecord, constructor, resultCapability ) + + ... + 1. Let promiseResolve be ? Get(constructor, `"resolve"`). + 1. If IsCallable(promiseResolve) is *false*, throw a *TypeError* exception. + ... +---*/ + +var checkPoint = ""; +function fn1(executor) { + checkPoint += "a"; + executor(); + checkPoint += "b"; + executor(function() {}, function() {}); + checkPoint += "c"; +} +fn1.resolve = function() {}; +Promise.all.call(fn1, []); +assert.sameValue(checkPoint, "abc", "executor initially called with no arguments"); + +checkPoint = ""; +function fn2(executor) { + checkPoint += "a"; + executor(undefined, undefined); + checkPoint += "b"; + executor(function() {}, function() {}); + checkPoint += "c"; +} +fn2.resolve = function() {}; +Promise.all.call(fn2, []); +assert.sameValue(checkPoint, "abc", "executor initially called with (undefined, undefined)"); + +checkPoint = ""; +function fn3(executor) { + checkPoint += "a"; + executor(undefined, function() {}); + checkPoint += "b"; + executor(function() {}, function() {}); + checkPoint += "c"; +} +Object.defineProperty(fn3, 'resolve', { + get() { throw new Test262Error; } +}); +assert.throws(TypeError, function() { + Promise.all.call(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.all.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.all.call(fn5, []); +}, "executor initially called with (String, Number)"); +assert.sameValue(checkPoint, "ab", "executor initially called with (String, Number)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/capability-executor-not-callable.js b/js/src/tests/test262/built-ins/Promise/all/capability-executor-not-callable.js new file mode 100644 index 0000000000..7b2d1c1312 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/capability-executor-not-callable.js @@ -0,0 +1,109 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es6id: 25.4.4.1 +description: > + Throws a TypeError if either resolve or reject capability is not callable. +info: | + Promise.all ( iterable ) + + ... + 6. Let promiseCapability be NewPromiseCapability(C). + 7. ReturnIfAbrupt(promiseCapability). + ... + + 25.4.1.5 NewPromiseCapability ( C ) + ... + 4. Let executor be a new built-in function object as defined in GetCapabilitiesExecutor Functions (25.4.1.5.1). + 5. Set the [[Capability]] internal slot of executor to promiseCapability. + 6. Let promise be Construct(C, «executor»). + 7. ReturnIfAbrupt(promise). + 8. If IsCallable(promiseCapability.[[Resolve]]) is false, throw a TypeError exception. + 9. If IsCallable(promiseCapability.[[Reject]]) is false, throw a TypeError exception. + ... +---*/ + +var checkPoint = ""; +function fn1(executor) { + checkPoint += "a"; +} +Object.defineProperty(fn1, 'resolve', { + get() { throw new Test262Error; } +}); +assert.throws(TypeError, function() { + Promise.all.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.all.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.all.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.all.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.all.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.all.call(fn6, []); +}, "executor called with (Number, String)"); +assert.sameValue(checkPoint, "ab", "executor called with (Number, String)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/capability-resolve-throws-no-close.js b/js/src/tests/test262/built-ins/Promise/all/capability-resolve-throws-no-close.js new file mode 100644 index 0000000000..2be75cf0ca --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/capability-resolve-throws-no-close.js @@ -0,0 +1,79 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-promise.all +description: > + Iterator is not closed when the "resolve" capability returns an abrupt + completion. +info: | + 1. Let C be the this value. + [...] + 3. Let promiseCapability be ? NewPromiseCapability(C). + [...] + 7. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + 8. If result is an abrupt completion, then + a. If iteratorRecord.[[Done]] is false, let result be + IteratorClose(iterator, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + + [...] + 6. Repeat + [...] + d. If next is false, then + [...] + iii. If remainingElementsCount.[[Value]] is 0, then + 1. Let valuesArray be CreateArrayFromList(values). + 2. Perform ? Call(resultCapability.[[Resolve]], undefined, « + valuesArray »). + + 25.4.1.1.1 IfAbruptRejectPromise + + IfAbruptRejectPromise is a short hand for a sequence of algorithm steps that + use a PromiseCapability Record. An algorithm step of the form: + + 1. IfAbruptRejectPromise(value, capability). + + means the same thing as: + + 1. If value is an abrupt completion, then + a. Perform ? Call(capability.[[Reject]], undefined, « value.[[Value]] »). + b. Return capability.[[Promise]]. + 2. Else if value is a Completion Record, let value be value.[[Value]]. +features: [Symbol.iterator] +---*/ + +var nextCount = 0; +var returnCount = 0; +var iter = {}; +iter[Symbol.iterator] = function() { + return { + next: function() { + nextCount += 1; + return { + done: true + }; + }, + return: function() { + returnCount += 1; + return {}; + } + }; +}; +var P = function(executor) { + return new Promise(function(_, reject) { + executor(function() { + throw new Test262Error(); + }, reject); + }); +}; + +P.resolve = Promise.resolve; + +Promise.all.call(P, iter); + +assert.sameValue(nextCount, 1); +assert.sameValue(returnCount, 0); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/capability-resolve-throws-reject.js b/js/src/tests/test262/built-ins/Promise/all/capability-resolve-throws-reject.js new file mode 100644 index 0000000000..cae47e18f8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/capability-resolve-throws-reject.js @@ -0,0 +1,68 @@ +// |reftest| async +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-promise.all +description: > + Promise is rejected when the "resolve" capability returns an abrupt + completion. +info: | + 1. Let C be the this value. + [...] + 3. Let promiseCapability be ? NewPromiseCapability(C). + [...] + 7. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + 8. If result is an abrupt completion, then + a. If iteratorRecord.[[Done]] is false, let result be + IteratorClose(iterator, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + + [...] + 6. Repeat + [...] + d. If next is false, then + [...] + iii. If remainingElementsCount.[[Value]] is 0, then + 1. Let valuesArray be CreateArrayFromList(values). + 2. Perform ? Call(resultCapability.[[Resolve]], undefined, « + valuesArray »). + + 25.4.1.1.1 IfAbruptRejectPromise + + IfAbruptRejectPromise is a short hand for a sequence of algorithm steps that + use a PromiseCapability Record. An algorithm step of the form: + + 1. IfAbruptRejectPromise(value, capability). + + means the same thing as: + + 1. If value is an abrupt completion, then + a. Perform ? Call(capability.[[Reject]], undefined, « value.[[Value]] »). + b. Return capability.[[Promise]]. + 2. Else if value is a Completion Record, let value be value.[[Value]]. +flags: [async] +---*/ + +var thrown = new Test262Error(); +var P = function(executor) { + return new Promise(function(_, reject) { + executor(function() { + throw thrown; + }, reject); + }); +}; + +P.resolve = Promise.resolve; + +Promise.all.call(P, []) + .then(function() { + $DONE('Promise incorrectly fulfilled.'); + }, function(reason) { + if (reason !== thrown) { + $DONE('Promise rejected with incorrect "reason."'); + return; + } + $DONE(); + }); diff --git a/js/src/tests/test262/built-ins/Promise/all/ctx-ctor-throws.js b/js/src/tests/test262/built-ins/Promise/all/ctx-ctor-throws.js new file mode 100644 index 0000000000..13de0ef9ca --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/ctx-ctor-throws.js @@ -0,0 +1,28 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + `Promise.all` invoked on a constructor value that throws an error +es6id: 25.4.4.1 +info: | + 1. Let C be the this value. + [...] + 6. Let promiseCapability be NewPromiseCapability(C). + 7. ReturnIfAbrupt(promiseCapability). + + 25.4.1.5 NewPromiseCapability + [...] + 6. Let promise be Construct(C, «executor»). + 7. ReturnIfAbrupt(promise). +---*/ + +var CustomPromise = function() { + throw new Test262Error(); +}; + +assert.throws(Test262Error, function() { + Promise.all.call(CustomPromise); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/ctx-ctor.js b/js/src/tests/test262/built-ins/Promise/all/ctx-ctor.js new file mode 100644 index 0000000000..b6fd1068a3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/ctx-ctor.js @@ -0,0 +1,39 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + `Promise.all` invoked on a constructor value +es6id: 25.4.4.1 +info: | + 1. Let C be the this value. + [...] + 6. Let promiseCapability be NewPromiseCapability(C). + [...] + 10. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}. + 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + [...] + 13. Return Completion(result). +features: [class] +---*/ + +var executor = null; +var callCount = 0; + +class SubPromise extends Promise { + constructor(a) { + super(a); + executor = a; + callCount += 1; + } +} + +var instance = Promise.all.call(SubPromise, []); + +assert.sameValue(instance.constructor, SubPromise); +assert.sameValue(instance instanceof SubPromise, true); + +assert.sameValue(callCount, 1); +assert.sameValue(typeof executor, 'function'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/ctx-non-ctor.js b/js/src/tests/test262/built-ins/Promise/all/ctx-non-ctor.js new file mode 100644 index 0000000000..d7206e5efb --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/ctx-non-ctor.js @@ -0,0 +1,22 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + `Promise.all` invoked on a non-constructor value +es6id: 25.4.4.1 +info: | + [...] + 6. Let promiseCapability be NewPromiseCapability(C). + 7. ReturnIfAbrupt(promiseCapability). + + 25.4.1.5 NewPromiseCapability ( C ) + + 1. If IsConstructor(C) is false, throw a TypeError exception. +---*/ + +assert.throws(TypeError, function() { + Promise.all.call(eval); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/ctx-non-object.js b/js/src/tests/test262/built-ins/Promise/all/ctx-non-object.js new file mode 100644 index 0000000000..decd8ad556 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/ctx-non-object.js @@ -0,0 +1,38 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + `Promise.all` invoked on a non-object value +es6id: 25.4.4.1 +info: | + 1. Let C be the this value. + 2. If Type(C) is not Object, throw a TypeError exception. +features: [Symbol] +---*/ + +assert.throws(TypeError, function() { + Promise.all.call(undefined, []); +}); + +assert.throws(TypeError, function() { + Promise.all.call(null, []); +}); + +assert.throws(TypeError, function() { + Promise.all.call(86, []); +}); + +assert.throws(TypeError, function() { + Promise.all.call('string', []); +}); + +assert.throws(TypeError, function() { + Promise.all.call(true, []); +}); + +assert.throws(TypeError, function() { + Promise.all.call(Symbol(), []); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/does-not-invoke-array-setters.js b/js/src/tests/test262/built-ins/Promise/all/does-not-invoke-array-setters.js new file mode 100644 index 0000000000..9a7c4c3fde --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/does-not-invoke-array-setters.js @@ -0,0 +1,39 @@ +// |reftest| async +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es6id: 25.4.4.1.1 +description: > + Indexed setter properties on Array.prototype are not invoked. +info: | + Runtime Semantics: PerformPromiseAll( iteratorRecord, constructor, resultCapability) + + ... + 4. Let remainingElementsCount be a new Record { [[value]]: 1 }. + ... + 6.d ... + ii. Set remainingElementsCount.[[value]] to remainingElementsCount.[[value]] − 1. + iii. If remainingElementsCount.[[value]] is 0, + 1. Let valuesArray be CreateArrayFromList(values). + ... + ... + + 7.3.16 CreateArrayFromList (elements) + ... + 4. For each element e of elements + a. Let status be CreateDataProperty(array, ToString(n), e). + b. Assert: status is true. + ... +flags: [async] +---*/ + +Object.defineProperty(Array.prototype, 0, { + set: function() { + throw new Test262Error("Setter on Array.prototype called"); + } +}); + +Promise.all([42]).then(function() { + $DONE(); +}, $DONE); diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-error-close.js b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-error-close.js new file mode 100644 index 0000000000..58c50705d6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-error-close.js @@ -0,0 +1,51 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Explicit iterator closing in response to error +esid: sec-promise.all +info: | + 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + 12. If result is an abrupt completion, + a. If iteratorRecord.[[done]] is false, let result be + IteratorClose(iterator, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + [...] + + 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + + [...] + 6. Repeat + [...] + i. Let nextPromise be Invoke(constructor, "resolve", «nextValue»). + j. ReturnIfAbrupt(nextPromise ). +features: [Symbol.iterator] +---*/ + +var iterDoneSpy = {}; +var callCount = 0; +iterDoneSpy[Symbol.iterator] = function() { + return { + next: function() { + return { + value: null, + done: false + }; + }, + return: function() { + callCount += 1; + } + }; +}; + +Promise.resolve = function() { + throw new Test262Error(); +}; + +Promise.all(iterDoneSpy); + +assert.sameValue(callCount, 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-error-reject.js b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-error-reject.js new file mode 100644 index 0000000000..e6a968cffe --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-error-reject.js @@ -0,0 +1,39 @@ +// |reftest| async +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Promise rejection in response to error +esid: sec-promise.all +info: | + 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + 12. If result is an abrupt completion, + a. If iteratorRecord.[[done]] is false, let result be + IteratorClose(iterator, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + [...] + + 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + + [...] + 6. Repeat + [...] + i. Let nextPromise be Invoke(constructor, "resolve", «nextValue»). + j. ReturnIfAbrupt(nextPromise ). +flags: [async] +---*/ + +var thrown = new Test262Error(); +Promise.resolve = function() { + throw thrown; +}; + +Promise.all([1]) + .then(function() { + throw new Test262Error('The promise should not be fulfilled.'); + }, function(reason) { + if (reason !== thrown) { + throw new Test262Error('The promise should be rejected with the thrown error object'); + } + }).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-get-error-reject.js b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-get-error-reject.js new file mode 100644 index 0000000000..037b999b71 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-get-error-reject.js @@ -0,0 +1,41 @@ +// |reftest| async +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Error retrieving the constructor's `resolve` method (rejecting promise) +esid: sec-performpromiseall +info: | + 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + 12. If result is an abrupt completion, + a. If iteratorRecord.[[done]] is false, let result be + IteratorClose(iterator, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + [...] + + Runtime Semantics: PerformPromiseAll + + ... + 1. Let promiseResolve be ? Get(constructor, `"resolve"`). + ... + 1. Repeat, + 1. Let next be IteratorStep(iteratorRecord). + ... + 1. Let nextPromise be ? Call(promiseResolve, constructor, < nextValue >). +flags: [async] +---*/ + +var error = new Test262Error(); +Object.defineProperty(Promise, 'resolve', { + get: function() { + throw error; + } +}); + +Promise.all([new Promise(function() {})]).then(function() { + throw new Test262Error('The promise should be rejected'); +}, function(reason) { + assert.sameValue(reason, error); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-get-error.js b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-get-error.js new file mode 100644 index 0000000000..4bfc0a8afb --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-get-error.js @@ -0,0 +1,41 @@ +// |reftest| async +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +description: > + Promise.resolve is retrieved before GetIterator call (abrupt lookup). +info: | + Promise.all ( iterable ) + + [...] + 3. Let promiseResolve be GetPromiseResolve(C). + 4. IfAbruptRejectPromise(promiseResolve, promiseCapability). + + GetPromiseResolve ( promiseConstructor ) + + [...] + 2. Let promiseResolve be ? Get(promiseConstructor, "resolve"). +flags: [async] +features: [Symbol.iterator] +---*/ + +const iter = { + get [Symbol.iterator]() { + throw new Test262Error('unreachable'); + }, +}; + +const resolveError = { name: 'MyError' }; +Object.defineProperty(Promise, 'resolve', { + get() { + throw resolveError; + }, +}); + +Promise.all(iter).then(() => { + throw new Test262Error('The promise should be rejected, but it was resolved'); +}, (reason) => { + assert.sameValue(reason, resolveError); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-get-once-multiple-calls.js b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-get-once-multiple-calls.js new file mode 100644 index 0000000000..1789a4a30b --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-get-once-multiple-calls.js @@ -0,0 +1,47 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Gets constructor's `resolve` method once from zero to many invocations. +esid: sec-promise.all +info: | + Runtime Semantics: PerformPromiseAll + + 1. Let promiseResolve be ? Get(constructor, `"resolve"`). + 1. If IsCallable(promiseResolve) is false, throw a TypeError exception. + ... + 1. Repeat, + ... + 1. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »). +---*/ + +var p1 = Promise.resolve(1); +var p2 = Promise.resolve(1); +var p3 = Promise.reject(1); +var p4 = Promise.resolve(1); +var resolve = Promise.resolve; +var getCount = 0; +var callCount = 0; + +Object.defineProperty(Promise, 'resolve', { + configurable: true, + get() { + getCount += 1; + return function() { + callCount += 1; + return resolve.apply(Promise, arguments); + }; + } +}); + +Promise.all([p1, p2, p3, p4]); + +assert.sameValue( + getCount, 1, 'Got `resolve` only once for each iterated value' +); +assert.sameValue( + callCount, 4, '`resolve` invoked once for each iterated value' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-get-once-no-calls.js b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-get-once-no-calls.js new file mode 100644 index 0000000000..ec86fba799 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-get-once-no-calls.js @@ -0,0 +1,43 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Gets constructor's `resolve` method once from zero to many invocations. +esid: sec-promise.all +info: | + Runtime Semantics: PerformPromiseAll + + 1. Let promiseResolve be ? Get(constructor, `"resolve"`). + 1. If IsCallable(promiseResolve) is false, throw a TypeError exception. + ... + 1. Repeat, + ... + 1. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »). +---*/ + +var resolve = Promise.resolve; +var getCount = 0; +var callCount = 0; + +Object.defineProperty(Promise, 'resolve', { + configurable: true, + get() { + getCount += 1; + return function() { + callCount += 1; + return resolve.apply(Promise, arguments); + }; + } +}); + +Promise.all([]); + +assert.sameValue( + getCount, 1, 'Got `resolve` only once for each iterated value' +); +assert.sameValue( + callCount, 0, '`resolve` not called for empty iterator' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-on-promises-every-iteration-of-custom.js b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-on-promises-every-iteration-of-custom.js new file mode 100644 index 0000000000..84855dc903 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-on-promises-every-iteration-of-custom.js @@ -0,0 +1,44 @@ +// |reftest| async +// 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'); + }).then($DONE, $DONE); + diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-on-promises-every-iteration-of-promise.js b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-on-promises-every-iteration-of-promise.js new file mode 100644 index 0000000000..14f562465a --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-on-promises-every-iteration-of-promise.js @@ -0,0 +1,35 @@ +// |reftest| async +// 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'); + }).then($DONE, $DONE); + diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-on-values-every-iteration-of-promise.js b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-on-values-every-iteration-of-promise.js new file mode 100644 index 0000000000..2e5b928f51 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-on-values-every-iteration-of-promise.js @@ -0,0 +1,35 @@ +// |reftest| async +// 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'); + }).then($DONE, $DONE); + diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-return.js b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-return.js new file mode 100644 index 0000000000..6f63505b7a --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-return.js @@ -0,0 +1,49 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Use of the value returned by the constructor's `resolve` method. +es6id: 25.4.4.1 +info: | + [...] + 6. Let promiseCapability be NewPromiseCapability(C). + [...] + 11. Let result be PerformPromiseAll(iteratorRecord, promiseCapability, C). + [...] + + 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + [...] + 6. Repeat + [...] + i. Let nextPromise be Invoke(constructor, "resolve", «nextValue»). + [...] + r. Let result be Invoke(nextPromise, "then", resolveElement, + promiseCapability.[[Reject]]»). + [...] +---*/ + +var originalCallCount = 0; +var newCallCount = 0; +var P = function(executor) { + executor(function() {}, function() {}); +}; +P.resolve = function() { + return newThenable; +}; + +var originalThenable = { + then: function() { + originalCallCount += 1; + } +}; +var newThenable = { + then: function() { + newCallCount += 1; + } +}; + +Promise.all.call(P, [originalThenable]); + +assert.sameValue(originalCallCount, 0, 'original `then` method not invoked'); +assert.sameValue(newCallCount, 1, 'new `then` method invoked exactly once'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-resolve.js b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve.js new file mode 100644 index 0000000000..448bf9e22e --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve.js @@ -0,0 +1,54 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Invocation of the constructor's `resolve` method +es6id: 25.4.4.1 +info: | + 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + + [...] + + 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + + [...] + 6. Repeat + [...] + i. Let nextPromise be Invoke(constructor, "resolve", «nextValue»). +---*/ + +var p1 = new Promise(function() {}); +var p2 = new Promise(function() {}); +var p3 = new Promise(function() {}); +var resolve = Promise.resolve; +var callCount = 0; +var current = p1; +var next = p2; +var afterNext = p3; + +Promise.resolve = function(nextValue) { + assert.sameValue( + nextValue, current, '`resolve` invoked with next iterated value' + ); + assert.sameValue( + arguments.length, 1, '`resolve` invoked with a single argument' + ); + assert.sameValue(this, Promise, '`this` value is the constructor'); + + current = next; + next = afterNext; + afterNext = null; + + callCount += 1; + + return resolve.apply(Promise, arguments); +}; + +Promise.all([p1, p2, p3]); + +assert.sameValue( + callCount, 3, '`resolve` invoked once for each iterated value' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-then-error-close.js b/js/src/tests/test262/built-ins/Promise/all/invoke-then-error-close.js new file mode 100644 index 0000000000..fffd528d2d --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/invoke-then-error-close.js @@ -0,0 +1,53 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: > + Error thrown when invoking the instance's `then` method (closing iterator) +esid: sec-performpromiseall +info: | + 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + 12. If result is an abrupt completion, + a. If iteratorRecord.[[done]] is false, let result be + IteratorClose(iterator, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + [...] + + 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + + [...] + 6. Repeat + [...] + r. Let result be Invoke(nextPromise, "then", «resolveElement, + resultCapability.[[Reject]]»). + s. ReturnIfAbrupt(result). +features: [Symbol.iterator] +---*/ + +var promise = new Promise(function() {}); +var returnCount = 0; +var iter = {}; +iter[Symbol.iterator] = function() { + return { + next: function() { + return { + done: false, + value: promise + }; + }, + return: function() { + returnCount += 1; + return {}; + } + }; +}; + +promise.then = function() { + throw new Test262Error(); +}; + +Promise.all(iter); + +assert.sameValue(returnCount, 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-then-error-reject.js b/js/src/tests/test262/built-ins/Promise/all/invoke-then-error-reject.js new file mode 100644 index 0000000000..4e91208d87 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/invoke-then-error-reject.js @@ -0,0 +1,40 @@ +// |reftest| async +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Error thrown when invoking the instance's `then` method (rejecting Promise) +esid: sec-performpromiseall +info: | + 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + 12. If result is an abrupt completion, + a. If iteratorRecord.[[done]] is false, let result be + IteratorClose(iterator, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + [...] + + 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + + [...] + 6. Repeat + [...] + r. Let result be Invoke(nextPromise, "then", «resolveElement, + resultCapability.[[Reject]]»). + s. ReturnIfAbrupt(result). +flags: [async] +---*/ + +var promise = new Promise(function() {}); +var error = new Test262Error(); + +promise.then = function() { + throw error; +}; + +Promise.all([promise]).then(function() { + throw new Test262Error('The promise should be rejected'); +}, function(reason) { + assert.sameValue(reason, error); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-then-get-error-close.js b/js/src/tests/test262/built-ins/Promise/all/invoke-then-get-error-close.js new file mode 100644 index 0000000000..7a5b7ce446 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/invoke-then-get-error-close.js @@ -0,0 +1,55 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: > + Error thrown when accesing the instance's `then` method (closing iterator) +esid: sec-performpromiseall +info: | + 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + 12. If result is an abrupt completion, + a. If iteratorRecord.[[done]] is false, let result be + IteratorClose(iterator, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + [...] + + 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + + [...] + 6. Repeat + [...] + r. Let result be Invoke(nextPromise, "then", «resolveElement, + resultCapability.[[Reject]]»). + s. ReturnIfAbrupt(result). +features: [Symbol.iterator] +---*/ + +var promise = new Promise(function() {}); +var returnCount = 0; +var iter = {}; +iter[Symbol.iterator] = function() { + return { + next: function() { + return { + done: false, + value: promise + }; + }, + return: function() { + returnCount += 1; + return {}; + } + }; +}; + +Object.defineProperty(promise, 'then', { + get: function() { + throw new Test262Error(); + } +}); + +Promise.all(iter); + +assert.sameValue(returnCount, 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-then-get-error-reject.js b/js/src/tests/test262/built-ins/Promise/all/invoke-then-get-error-reject.js new file mode 100644 index 0000000000..6f5fa60bf2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/invoke-then-get-error-reject.js @@ -0,0 +1,41 @@ +// |reftest| async +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: > + Error thrown when accessing the instance's `then` method (rejecting Promise) +esid: sec-performpromiseall +info: | + 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + 12. If result is an abrupt completion, + a. If iteratorRecord.[[done]] is false, let result be + IteratorClose(iterator, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + [...] + + 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + + [...] + 6. Repeat + [...] + r. Let result be Invoke(nextPromise, "then", «resolveElement, + resultCapability.[[Reject]]»). + s. ReturnIfAbrupt(result). +flags: [async] +---*/ + +var promise = new Promise(function() {}); +var error = new Test262Error(); + +Object.defineProperty(promise, 'then', { + get: function() { + throw error; + } +}); + +Promise.all([promise]).then(function() { + throw new Test262Error('The promise should be rejected'); +}, function(reason) { + assert.sameValue(reason, error); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-then.js b/js/src/tests/test262/built-ins/Promise/all/invoke-then.js new file mode 100644 index 0000000000..80113deb33 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/invoke-then.js @@ -0,0 +1,57 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Invocation of the instance's `then` method +es6id: 25.4.4.1 +info: | + 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + + [...] + + 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + + [...] + 6. Repeat + [...] + r. Let result be Invoke(nextPromise, "then", «resolveElement, + resultCapability.[[Reject]]»). +---*/ + +var p1 = new Promise(function() {}); +var p2 = new Promise(function() {}); +var p3 = new Promise(function() {}); +var callCount = 0; +var currentThis = p1; +var nextThis = p2; +var afterNextThis = p3; + +p1.then = p2.then = p3.then = function(a, b) { + assert.sameValue(typeof a, 'function', 'type of first argument'); + assert.sameValue( + a.length, + 1, + 'ES6 25.4.1.3.2: The length property of a promise resolve function is 1.' + ); + assert.sameValue(typeof b, 'function', 'type of second argument'); + assert.sameValue( + b.length, + 1, + 'ES6 25.4.1.3.1: The length property of a promise reject function is 1.' + ); + assert.sameValue(arguments.length, 2, '`then` invoked with two arguments'); + assert.sameValue(this, currentThis, '`this` value'); + + currentThis = nextThis; + nextThis = afterNextThis; + afterNextThis = null; + + callCount += 1; +}; + +Promise.all([p1, p2, p3]); + +assert.sameValue(callCount, 3, '`then` invoked once for every iterated value'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-false-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-false-reject.js new file mode 100644 index 0000000000..258cc45054 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-false-reject.js @@ -0,0 +1,34 @@ +// |reftest| async +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +description: > + Reject when argument is `false` +info: | + ... + Let iteratorRecord be GetIterator(iterable). + 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: [Symbol.iterator] +flags: [async] +---*/ + +try { + Promise.all(false).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-null-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-null-reject.js new file mode 100644 index 0000000000..a527580294 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-null-reject.js @@ -0,0 +1,34 @@ +// |reftest| async +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +description: > + Reject when argument is `null` +info: | + ... + Let iteratorRecord be GetIterator(iterable). + 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: [Symbol.iterator] +flags: [async] +---*/ + +try { + Promise.all(null).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-number-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-number-reject.js new file mode 100644 index 0000000000..0bfee0b2f7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-number-reject.js @@ -0,0 +1,34 @@ +// |reftest| async +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +description: > + Reject when argument is a number +info: | + ... + Let iteratorRecord be GetIterator(iterable). + 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: [Symbol.iterator] +flags: [async] +---*/ + +try { + Promise.all(1).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-string-resolve.js b/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-string-resolve.js new file mode 100644 index 0000000000..c20288b677 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-string-resolve.js @@ -0,0 +1,34 @@ +// |reftest| async +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +description: > + Resolve when argument is a string +info: | + ... + Let iteratorRecord be GetIterator(iterable). + 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: [Symbol.iterator] +flags: [async] +---*/ + +try { + Promise.all("").then(function(v) { + assert.sameValue(v.length, 0); + }, function() { + $DONE('The promise should be resolved, but was rejected'); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be resolved, but threw an exception: ${error.message}`); +} diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-symbol-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-symbol-reject.js new file mode 100644 index 0000000000..b3c22c06de --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-symbol-reject.js @@ -0,0 +1,34 @@ +// |reftest| async +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +description: > + Reject when argument is a symbol +info: | + ... + Let iteratorRecord be GetIterator(iterable). + 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: [Symbol.iterator] +flags: [async] +---*/ + +try { + Promise.all(Symbol()).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-true-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-true-reject.js new file mode 100644 index 0000000000..9c62656960 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-true-reject.js @@ -0,0 +1,34 @@ +// |reftest| async +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +description: > + Reject when argument is `true` +info: | + ... + Let iteratorRecord be GetIterator(iterable). + 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: [Symbol.iterator] +flags: [async] +---*/ + +try { + Promise.all(true).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-undefined-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-undefined-reject.js new file mode 100644 index 0000000000..9e9459776a --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-undefined-reject.js @@ -0,0 +1,34 @@ +// |reftest| async +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +description: > + Reject when argument is `undefined` +info: | + ... + Let iteratorRecord be GetIterator(iterable). + 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: [Symbol.iterator] +flags: [async] +---*/ + +try { + Promise.all(undefined).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-assigned-false-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-assigned-false-reject.js new file mode 100644 index 0000000000..09f3b39bf3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/iter-assigned-false-reject.js @@ -0,0 +1,36 @@ +// |reftest| async +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +description: > + Reject when argument's Symbol.iterator property has the value false +info: | + ... + Let iteratorRecord be GetIterator(iterable). + 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: [Symbol.iterator] +flags: [async] +---*/ + +try { + Promise.all({ + [Symbol.iterator]: false + }).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-assigned-null-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-assigned-null-reject.js new file mode 100644 index 0000000000..ce77efa446 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/iter-assigned-null-reject.js @@ -0,0 +1,36 @@ +// |reftest| async +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +description: > + Reject when argument's Symbol.iterator property has the value null +info: | + ... + Let iteratorRecord be GetIterator(iterable). + 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: [Symbol.iterator] +flags: [async] +---*/ + +try { + Promise.all({ + [Symbol.iterator]: null + }).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-assigned-number-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-assigned-number-reject.js new file mode 100644 index 0000000000..4c63977bc0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/iter-assigned-number-reject.js @@ -0,0 +1,36 @@ +// |reftest| async +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +description: > + Reject when argument's Symbol.iterator property has the value 1 +info: | + ... + Let iteratorRecord be GetIterator(iterable). + 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: [Symbol.iterator] +flags: [async] +---*/ + +try { + Promise.all({ + [Symbol.iterator]: 1 + }).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-assigned-string-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-assigned-string-reject.js new file mode 100644 index 0000000000..8f23475cd4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/iter-assigned-string-reject.js @@ -0,0 +1,36 @@ +// |reftest| async +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +description: > + Reject when argument's Symbol.iterator property has the value "" +info: | + ... + Let iteratorRecord be GetIterator(iterable). + 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: [Symbol.iterator] +flags: [async] +---*/ + +try { + Promise.all({ + [Symbol.iterator]: "" + }).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-assigned-symbol-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-assigned-symbol-reject.js new file mode 100644 index 0000000000..1eaa109428 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/iter-assigned-symbol-reject.js @@ -0,0 +1,36 @@ +// |reftest| async +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +description: > + Reject when argument's Symbol.iterator property has the value Symbol() +info: | + ... + Let iteratorRecord be GetIterator(iterable). + 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: [Symbol.iterator] +flags: [async] +---*/ + +try { + Promise.all({ + [Symbol.iterator]: Symbol() + }).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-assigned-true-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-assigned-true-reject.js new file mode 100644 index 0000000000..172235e9ef --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/iter-assigned-true-reject.js @@ -0,0 +1,36 @@ +// |reftest| async +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +description: > + Reject when argument's Symbol.iterator property has the value true +info: | + ... + Let iteratorRecord be GetIterator(iterable). + 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: [Symbol.iterator] +flags: [async] +---*/ + +try { + Promise.all({ + [Symbol.iterator]: true + }).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-assigned-undefined-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-assigned-undefined-reject.js new file mode 100644 index 0000000000..9d8e741728 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/iter-assigned-undefined-reject.js @@ -0,0 +1,36 @@ +// |reftest| async +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +description: > + Reject when argument's Symbol.iterator property has the value undefined +info: | + ... + Let iteratorRecord be GetIterator(iterable). + 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: [Symbol.iterator] +flags: [async] +---*/ + +try { + Promise.all({ + [Symbol.iterator]: undefined + }).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-next-val-err-no-close.js b/js/src/tests/test262/built-ins/Promise/all/iter-next-val-err-no-close.js new file mode 100644 index 0000000000..ad0d763ace --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/iter-next-val-err-no-close.js @@ -0,0 +1,57 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +description: > + Error when accessing an iterator result's `value` property (not closing + iterator) +info: | + 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + 12. If result is an abrupt completion, + a. If iteratorRecord.[[done]] is false, let result be + IteratorClose(iterator, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + [...] + + 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + + [...] + 6. Repeat + [...] + e. Let nextValue be IteratorValue(next). + f. If nextValue is an abrupt completion, set iteratorRecord.[[done]] to + true. + g. ReturnIfAbrupt(nextValue). +features: [Symbol.iterator] +---*/ + +var iterNextValThrows = {}; +var returnCount = 0; +var poisonedVal = { + done: false +}; +var error = new Test262Error(); +Object.defineProperty(poisonedVal, 'value', { + get: function() { + throw error; + } +}); +iterNextValThrows[Symbol.iterator] = function() { + return { + next: function() { + return poisonedVal; + }, + return: function() { + returnCount += 1; + return {}; + } + }; +}; + +Promise.all(iterNextValThrows); + +assert.sameValue(returnCount, 0); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-next-val-err-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-next-val-err-reject.js new file mode 100644 index 0000000000..b8dabaa0d8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/iter-next-val-err-reject.js @@ -0,0 +1,54 @@ +// |reftest| async +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +description: > + Error when accessing an iterator result's `value` property (rejecting + promise) +info: | + 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + 12. If result is an abrupt completion, + a. If iteratorRecord.[[done]] is false, let result be + IteratorClose(iterator, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + [...] + + 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + + [...] + 6. Repeat + [...] + e. Let nextValue be IteratorValue(next). + f. If nextValue is an abrupt completion, set iteratorRecord.[[done]] to + true. + g. ReturnIfAbrupt(nextValue). +features: [Symbol.iterator] +flags: [async] +---*/ + +var iterNextValThrows = {}; +var poisonedVal = { + done: false +}; +var error = new Test262Error(); +Object.defineProperty(poisonedVal, 'value', { + get: function() { + throw error; + } +}); +iterNextValThrows[Symbol.iterator] = function() { + return { + next: function() { + return poisonedVal; + } + }; +}; + +Promise.all(iterNextValThrows).then(function() { + $DONE('The promise should be rejected.'); +}, function(reason) { + assert.sameValue(reason, error); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-returns-false-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-returns-false-reject.js new file mode 100644 index 0000000000..68c9b42031 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/iter-returns-false-reject.js @@ -0,0 +1,38 @@ +// |reftest| async +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +description: > + Reject when argument's Symbol.iterator returns false +info: | + ... + Let iteratorRecord be GetIterator(iterable). + 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: [Symbol.iterator] +flags: [async] +---*/ + +try { + Promise.all({ + [Symbol.iterator]() { + return false; + } + }).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-returns-null-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-returns-null-reject.js new file mode 100644 index 0000000000..f0f8c80cc3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/iter-returns-null-reject.js @@ -0,0 +1,38 @@ +// |reftest| async +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +description: > + Reject when argument's Symbol.iterator returns null +info: | + ... + Let iteratorRecord be GetIterator(iterable). + 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: [Symbol.iterator] +flags: [async] +---*/ + +try { + Promise.all({ + [Symbol.iterator]() { + return null; + } + }).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-returns-number-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-returns-number-reject.js new file mode 100644 index 0000000000..0b130ef77e --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/iter-returns-number-reject.js @@ -0,0 +1,38 @@ +// |reftest| async +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +description: > + Reject when argument's Symbol.iterator returns a number +info: | + ... + Let iteratorRecord be GetIterator(iterable). + 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: [Symbol.iterator] +flags: [async] +---*/ + +try { + Promise.all({ + [Symbol.iterator]() { + return 1; + } + }).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-returns-string-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-returns-string-reject.js new file mode 100644 index 0000000000..37dd3692b0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/iter-returns-string-reject.js @@ -0,0 +1,38 @@ +// |reftest| async +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +description: > + Reject when argument's Symbol.iterator returns a string +info: | + ... + Let iteratorRecord be GetIterator(iterable). + 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: [Symbol.iterator] +flags: [async] +---*/ + +try { + Promise.all({ + [Symbol.iterator]() { + return ""; + } + }).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-returns-symbol-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-returns-symbol-reject.js new file mode 100644 index 0000000000..023ef1f66a --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/iter-returns-symbol-reject.js @@ -0,0 +1,38 @@ +// |reftest| async +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +description: > + Reject when argument's Symbol.iterator returns a symbol +info: | + ... + Let iteratorRecord be GetIterator(iterable). + 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: [Symbol.iterator] +flags: [async] +---*/ + +try { + Promise.all({ + [Symbol.iterator]() { + return Symbol(); + } + }).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-returns-true-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-returns-true-reject.js new file mode 100644 index 0000000000..4211c8d1ed --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/iter-returns-true-reject.js @@ -0,0 +1,38 @@ +// |reftest| async +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +description: > + Reject when argument's Symbol.iterator returns true +info: | + ... + Let iteratorRecord be GetIterator(iterable). + 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: [Symbol.iterator] +flags: [async] +---*/ + +try { + Promise.all({ + [Symbol.iterator]() { + return true; + } + }).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-returns-undefined-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-returns-undefined-reject.js new file mode 100644 index 0000000000..3ed1c633d2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/iter-returns-undefined-reject.js @@ -0,0 +1,38 @@ +// |reftest| async +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +description: > + Reject when argument's Symbol.iterator returns undefined +info: | + ... + Let iteratorRecord be GetIterator(iterable). + 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: [Symbol.iterator] +flags: [async] +---*/ + +try { + Promise.all({ + [Symbol.iterator]() { + return undefined; + } + }).then(function() { + $DONE('The promise should be rejected, but was resolved'); + }, function(error) { + assert(error instanceof TypeError); + }).then($DONE, $DONE); +} catch (error) { + $DONE(`The promise should be rejected, but threw an exception: ${error.message}`); +} diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-step-err-no-close.js b/js/src/tests/test262/built-ins/Promise/all/iter-step-err-no-close.js new file mode 100644 index 0000000000..e0f9b679aa --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/iter-step-err-no-close.js @@ -0,0 +1,59 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +description: > + Error when advancing the provided iterable (not closing iterator) +info: | + 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + 12. If result is an abrupt completion, + a. If iteratorRecord.[[done]] is false, let result be + IteratorClose(iterator, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + [...] + + 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + + [...] + 6. Repeat + a. Let next be IteratorStep(iteratorRecord.[[iterator]]). + b. If next is an abrupt completion, set iteratorRecord.[[done]] to + true. + c. ReturnIfAbrupt(next). +features: [Symbol.iterator] +---*/ + +var iterStepThrows = {}; +var poisonedDone = {}; +var returnCount = 0; +var error = new Test262Error(); +Object.defineProperty(poisonedDone, 'done', { + get: function() { + throw error; + } +}); +Object.defineProperty(poisonedDone, 'value', { + get: function() { + throw new Test262Error('The `value` property should not be accessed.'); + } +}); + +iterStepThrows[Symbol.iterator] = function() { + return { + next: function() { + return poisonedDone; + }, + return: function() { + returnCount += 1; + return {}; + } + }; +}; + +Promise.all(iterStepThrows); + +assert.sameValue(returnCount, 0); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-step-err-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-step-err-reject.js new file mode 100644 index 0000000000..0f927aac75 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/iter-step-err-reject.js @@ -0,0 +1,56 @@ +// |reftest| async +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +description: > + Error when advancing the provided iterable (rejecting promise) +info: | + 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + 12. If result is an abrupt completion, + a. If iteratorRecord.[[done]] is false, let result be + IteratorClose(iterator, result). + b. IfAbruptRejectPromise(result, promiseCapability). + + [...] + + 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + + [...] + 6. Repeat + a. Let next be IteratorStep(iteratorRecord.[[iterator]]). + b. If next is an abrupt completion, set iteratorRecord.[[done]] to + true. + c. ReturnIfAbrupt(next). +features: [Symbol.iterator] +flags: [async] +---*/ + +var iterStepThrows = {}; +var poisonedDone = {}; +var error = new Test262Error(); +Object.defineProperty(poisonedDone, 'done', { + get: function() { + throw error; + } +}); +Object.defineProperty(poisonedDone, 'value', { + get: function() { + $DONE('The `value` property should not be accessed.'); + } +}); + +iterStepThrows[Symbol.iterator] = function() { + return { + next: function() { + return poisonedDone; + } + }; +}; + +Promise.all(iterStepThrows).then(function() { + $DONE('The promise should be rejected.'); +}, function(reason) { + assert.sameValue(reason, error); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Promise/all/length.js b/js/src/tests/test262/built-ins/Promise/all/length.js new file mode 100644 index 0000000000..7769497c7c --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/length.js @@ -0,0 +1,27 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.4.4.1 +description: Promise.all `length` property +info: | + ES6 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] +---*/ + +assert.sameValue(Promise.all.length, 1); + +verifyNotEnumerable(Promise.all, 'length'); +verifyNotWritable(Promise.all, 'length'); +verifyConfigurable(Promise.all, 'length'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/name.js b/js/src/tests/test262/built-ins/Promise/all/name.js new file mode 100644 index 0000000000..552ba841dd --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/name.js @@ -0,0 +1,28 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.4.4.1 +description: Promise.all `name` property +info: | + ES6 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] +---*/ + +assert.sameValue(Promise.all.name, 'all'); + +verifyNotEnumerable(Promise.all, 'name'); +verifyNotWritable(Promise.all, 'name'); +verifyConfigurable(Promise.all, 'name'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/new-resolve-function.js b/js/src/tests/test262/built-ins/Promise/all/new-resolve-function.js new file mode 100644 index 0000000000..9d668f67e2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/new-resolve-function.js @@ -0,0 +1,51 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es6id: 25.4.4.1.1 +description: > + Each Promise.all element is called with a new Promise.all Resolve Element function. +info: | + Runtime Semantics: PerformPromiseAll( iteratorRecord, constructor, resultCapability) + + ... + k. Let resolveElement be a new built-in function object as defined in Promise.all Resolve Element Functions. + ... + r. Let result be Invoke(nextPromise, "then", «resolveElement, resultCapability.[[Reject]]»). + ... +---*/ + +function resolveFunction() {} + +function Constructor(executor) { + executor(resolveFunction, Test262Error.thrower); +} +Constructor.resolve = function(v) { + return v; +}; + +var callCount1 = 0, + callCount2 = 0; +var p1OnFulfilled; + +var p1 = { + then: function(onFulfilled, onRejected) { + callCount1 += 1; + p1OnFulfilled = onFulfilled; + assert.notSameValue(onFulfilled, resolveFunction, "p1.then"); + } +}; +var p2 = { + then: function(onFulfilled, onRejected) { + callCount2 += 1; + assert.notSameValue(onFulfilled, resolveFunction, "p2.then"); + assert.notSameValue(onFulfilled, p1OnFulfilled, "p1.onFulfilled != p2.onFulfilled"); + } +}; + +Promise.all.call(Constructor, [p1, p2]); + +assert.sameValue(callCount1, 1, "p1.then call count"); +assert.sameValue(callCount2, 1, "p2.then call count"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/not-a-constructor.js b/js/src/tests/test262/built-ins/Promise/all/not-a-constructor.js new file mode 100644 index 0000000000..9ab0f8e49e --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/not-a-constructor.js @@ -0,0 +1,31 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-ecmascript-standard-built-in-objects +description: > + Promise.all does not implement [[Construct]], is not new-able +info: | + ECMAScript Function 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. + + sec-evaluatenew + + ... + 7. If IsConstructor(constructor) is false, throw a TypeError exception. + ... +includes: [isConstructor.js] +features: [Reflect.construct, arrow-function] +---*/ + +assert.sameValue(isConstructor(Promise.all), false, 'isConstructor(Promise.all) must return false'); + +assert.throws(TypeError, () => { + new Promise.all([]); +}, '`new Promise.all([])` throws TypeError'); + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/prop-desc.js b/js/src/tests/test262/built-ins/Promise/all/prop-desc.js new file mode 100644 index 0000000000..b40599802b --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/prop-desc.js @@ -0,0 +1,21 @@ +// Copyright 2015 Jordan Harband. All rights reserved. +// See LICENSE for details. + +/*--- +es6id: 25.4.4.1_A1.3_T1 +author: Jordan Harband +description: Promise.all property descriptor +info: | + ES6 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] +---*/ + +verifyNotEnumerable(Promise, 'all'); +verifyWritable(Promise, 'all'); +verifyConfigurable(Promise, 'all'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/reject-deferred.js b/js/src/tests/test262/built-ins/Promise/all/reject-deferred.js new file mode 100644 index 0000000000..c439bcaf75 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/reject-deferred.js @@ -0,0 +1,43 @@ +// |reftest| async +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Rejecting through deferred invocation of the provided resolving function +es6id: 25.4.4.1 +info: | + [...] + 6. Let promiseCapability be NewPromiseCapability(C). + [...] + 11. Let result be PerformPromiseAll(iteratorRecord, promiseCapability, C). + [...] + + 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + [...] + 6. Repeat + [...] + r. Let result be Invoke(nextPromise, "then", resolveElement, + promiseCapability.[[Reject]]»). + + 25.4.1.3.1 Promise Reject Functions + [...] + 6. Return RejectPromise(promise, reason). +flags: [async] +---*/ + +var thenable = { + then: function(_, reject) { + new Promise(function(resolve) { + resolve(); + }) + .then(function() { + reject(); + }); + } +}; + +Promise.all([thenable]) + .then(function() { + $DONE('The promise should not be fulfilled.'); + }, function(x) { + $DONE(); + }); diff --git a/js/src/tests/test262/built-ins/Promise/all/reject-ignored-deferred.js b/js/src/tests/test262/built-ins/Promise/all/reject-ignored-deferred.js new file mode 100644 index 0000000000..482a48b0a3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/reject-ignored-deferred.js @@ -0,0 +1,59 @@ +// |reftest| async +// Copyright (C) 2016 the V8 project authors. 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 +es6id: 25.4.4.1 +info: | + [...] + 6. Let promiseCapability be NewPromiseCapability(C). + [...] + 11. Let result be PerformPromiseAll(iteratorRecord, promiseCapability, C). + [...] + + 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + [...] + 6. Repeat + [...] + r. Let result be Invoke(nextPromise, "then", resolveElement, + promiseCapability.[[Reject]]»). + + 25.4.1.3.1 Promise Reject Functions + [...] + 2. Let promise be the value of F's [[Promise]] internal slot. + 3. Let alreadyResolved be the value of F's [[AlreadyResolved]] internal + slot. + 4. If alreadyResolved.[[value]] is true, return undefined. +flags: [async] +---*/ + +var fulfiller = { + then: function(resolve) { + new Promise(function(resolve) { + resolve(); + }) + .then(function() { + resolve(); + }); + } +}; +var rejector = { + then: function(resolve, reject) { + new Promise(function(resolve) { + resolve(); + }) + .then(function() { + resolve(); + reject(); + }); + } +}; + +Promise.all([fulfiller, rejector]) + .then(function() { + $DONE(); + }, function() { + $DONE('The promise should not be rejected.'); + }); diff --git a/js/src/tests/test262/built-ins/Promise/all/reject-ignored-immed.js b/js/src/tests/test262/built-ins/Promise/all/reject-ignored-immed.js new file mode 100644 index 0000000000..3a8b8ebd62 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/reject-ignored-immed.js @@ -0,0 +1,49 @@ +// |reftest| async +// Copyright (C) 2016 the V8 project authors. 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 +es6id: 25.4.4.1 +info: | + [...] + 6. Let promiseCapability be NewPromiseCapability(C). + [...] + 11. Let result be PerformPromiseAll(iteratorRecord, promiseCapability, C). + [...] + + 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + [...] + 6. Repeat + [...] + r. Let result be Invoke(nextPromise, "then", resolveElement, + promiseCapability.[[Reject]]»). + + 25.4.1.3.1 Promise Reject Functions + [...] + 2. Let promise be the value of F's [[Promise]] internal slot. + 3. Let alreadyResolved be the value of F's [[AlreadyResolved]] internal + slot. + 4. If alreadyResolved.[[value]] is true, return undefined. +flags: [async] +---*/ + +var fulfiller = { + then: function(resolve) { + resolve(); + } +}; +var lateRejector = { + then: function(resolve, reject) { + resolve(); + reject(); + } +}; + +Promise.all([fulfiller, lateRejector]) + .then(function() { + $DONE(); + }, function() { + $DONE('The promise should not be rejected.'); + }); diff --git a/js/src/tests/test262/built-ins/Promise/all/reject-immed.js b/js/src/tests/test262/built-ins/Promise/all/reject-immed.js new file mode 100644 index 0000000000..4c476081ae --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/reject-immed.js @@ -0,0 +1,38 @@ +// |reftest| async +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Rejecting through immediate invocation of the provided resolving function +es6id: 25.4.4.1 +info: | + [...] + 6. Let promiseCapability be NewPromiseCapability(C). + [...] + 11. Let result be PerformPromiseAll(iteratorRecord, promiseCapability, C). + [...] + + 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + [...] + 6. Repeat + [...] + r. Let result be Invoke(nextPromise, "then", resolveElement, + promiseCapability.[[Reject]]»). + + 25.4.1.3.1 Promise Reject Functions + [...] + 6. Return RejectPromise(promise, reason). +flags: [async] +---*/ + +var thenable = { + then: function(_, reject) { + reject(); + } +}; + +Promise.all([thenable]) + .then(function() { + $DONE('The promise should not be fulfilled.'); + }, function(x) { + $DONE(); + }); diff --git a/js/src/tests/test262/built-ins/Promise/all/resolve-before-loop-exit-from-same.js b/js/src/tests/test262/built-ins/Promise/all/resolve-before-loop-exit-from-same.js new file mode 100644 index 0000000000..54705cb2fe --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/resolve-before-loop-exit-from-same.js @@ -0,0 +1,75 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es6id: 25.4.4.1.1 +description: > + Cannot tamper remainingElementsCount when Promise.all resolve element function is called twice in a row. +info: | + Runtime Semantics: PerformPromiseAll( iteratorRecord, constructor, resultCapability) + + ... + 4. Let remainingElementsCount be a new Record { [[value]]: 1 }. + ... + 6.d ... + ii. Set remainingElementsCount.[[value]] to remainingElementsCount.[[value]] − 1. + iii. If remainingElementsCount.[[value]] is 0, + 1. Let valuesArray be CreateArrayFromList(values). + 2. Let resolveResult be Call(resultCapability.[[Resolve]], undefined, «valuesArray»). + 3. ReturnIfAbrupt(resolveResult). + ... + + 25.4.4.1.2 Promise.all Resolve Element Functions + 1. Let alreadyCalled be the value of F's [[AlreadyCalled]] internal slot. + 2. If alreadyCalled.[[value]] is true, return undefined. + 3. Set alreadyCalled.[[value]] to true. + ... +---*/ + +var callCount = 0; + +function Constructor(executor) { + function resolve(values) { + callCount += 1; + assert(Array.isArray(values), "values is array"); + assert.sameValue(values.length, 3, "values length"); + assert.sameValue(values[0], "p1-fulfill", "values[0]"); + assert.sameValue(values[1], "p2-fulfill", "values[1]"); + assert.sameValue(values[2], "p3-fulfill", "values[2]"); + } + executor(resolve, Test262Error.thrower); +} +Constructor.resolve = function(v) { + return v; +}; + +var p1OnFulfilled; + +var p1 = { + then: function(onFulfilled, onRejected) { + p1OnFulfilled = onFulfilled; + } +}; +var p2 = { + then: function(onFulfilled, onRejected) { + onFulfilled("p2-fulfill"); + onFulfilled("p2-fulfill-unexpected"); + } +}; +var p3 = { + then: function(onFulfilled, onRejected) { + onFulfilled("p3-fulfill"); + } +}; + +assert.sameValue(callCount, 0, "callCount before call to all()"); + +Promise.all.call(Constructor, [p1, p2, p3]); + +assert.sameValue(callCount, 0, "callCount after call to all()"); + +p1OnFulfilled("p1-fulfill"); + +assert.sameValue(callCount, 1, "callCount after resolving p1"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/resolve-before-loop-exit.js b/js/src/tests/test262/built-ins/Promise/all/resolve-before-loop-exit.js new file mode 100644 index 0000000000..7ba90e2d9a --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/resolve-before-loop-exit.js @@ -0,0 +1,71 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es6id: 25.4.4.1.1 +description: > + Cannot tamper remainingElementsCount when two Promise.all resolve element functions are called in succession. +info: | + Runtime Semantics: PerformPromiseAll( iteratorRecord, constructor, resultCapability) + + ... + 4. Let remainingElementsCount be a new Record { [[value]]: 1 }. + ... + 6.d ... + ii. Set remainingElementsCount.[[value]] to remainingElementsCount.[[value]] − 1. + iii. If remainingElementsCount.[[value]] is 0, + 1. Let valuesArray be CreateArrayFromList(values). + 2. Let resolveResult be Call(resultCapability.[[Resolve]], undefined, «valuesArray»). + 3. ReturnIfAbrupt(resolveResult). + ... + + 25.4.4.1.2 Promise.all Resolve Element Functions + 1. Let alreadyCalled be the value of F's [[AlreadyCalled]] internal slot. + 2. If alreadyCalled.[[value]] is true, return undefined. + 3. Set alreadyCalled.[[value]] to true. + ... +---*/ + +var callCount = 0; + +function Constructor(executor) { + function resolve(values) { + callCount += 1; + assert(Array.isArray(values), "values is array"); + assert.sameValue(values.length, 3, "values length"); + assert.sameValue(values[0], "p1-fulfill", "values[0]"); + assert.sameValue(values[1], "p2-fulfill", "values[1]"); + assert.sameValue(values[2], "p3-fulfill", "values[2]"); + } + executor(resolve, Test262Error.thrower); +} +Constructor.resolve = function(v) { + return v; +}; + +var p1OnFulfilled; + +var p1 = { + then: function(onFulfilled, onRejected) { + p1OnFulfilled = onFulfilled; + } +}; +var p2 = { + then: function(onFulfilled, onRejected) { + p1OnFulfilled("p1-fulfill"); + onFulfilled("p2-fulfill"); + } +}; +var p3 = { + then: function(onFulfilled, onRejected) { + onFulfilled("p3-fulfill"); + } +}; + +assert.sameValue(callCount, 0, "callCount before call to all()"); + +Promise.all.call(Constructor, [p1, p2, p3]); + +assert.sameValue(callCount, 1, "callCount after call to all()"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-extensible.js b/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-extensible.js new file mode 100644 index 0000000000..5b0a6b0218 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-extensible.js @@ -0,0 +1,30 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es6id: 25.4.4.1.2 +description: The [[Extensible]] slot of Promise.all Resolve 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. +---*/ + +var resolveElementFunction; +var thenable = { + then: function(fulfill) { + resolveElementFunction = fulfill; + } +}; + +function NotPromise(executor) { + executor(function() {}, function() {}); +} +NotPromise.resolve = function(v) { + return v; +}; +Promise.all.call(NotPromise, [thenable]); + +assert(Object.isExtensible(resolveElementFunction)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-length.js b/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-length.js new file mode 100644 index 0000000000..6a3568870b --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-length.js @@ -0,0 +1,38 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es6id: 25.4.4.1.2 +description: The `length` property of Promise.all Resolve Element functions +info: | + The length property of a Promise.all resolve 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] +---*/ + +var resolveElementFunction; +var thenable = { + then: function(fulfill) { + resolveElementFunction = fulfill; + } +}; + +function NotPromise(executor) { + executor(function() {}, function() {}); +} +NotPromise.resolve = function(v) { + return v; +}; +Promise.all.call(NotPromise, [thenable]); + +assert.sameValue(resolveElementFunction.length, 1); + +verifyNotEnumerable(resolveElementFunction, "length"); +verifyNotWritable(resolveElementFunction, "length"); +verifyConfigurable(resolveElementFunction, "length"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-name.js b/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-name.js new file mode 100644 index 0000000000..cb30b5a007 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-name.js @@ -0,0 +1,40 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all-resolve-element-functions +description: The `name` property of Promise.all Resolve 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] +---*/ + +var resolveElementFunction; +var thenable = { + then: function(fulfill) { + resolveElementFunction = fulfill; + } +}; + +function NotPromise(executor) { + executor(function() {}, function() {}); +} +NotPromise.resolve = function(v) { + return v; +}; +Promise.all.call(NotPromise, [thenable]); + +verifyProperty(resolveElementFunction, "name", { + value: "", writable: false, enumerable: false, configurable: true +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-nonconstructor.js b/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-nonconstructor.js new file mode 100644 index 0000000000..14c832f80c --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-nonconstructor.js @@ -0,0 +1,34 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es6id: 25.4.4.1.2 +description: Promise.all Resolve 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. +---*/ + +var resolveElementFunction; +var thenable = { + then: function(fulfill) { + resolveElementFunction = fulfill; + } +}; + +function NotPromise(executor) { + executor(function() {}, function() {}); +} +NotPromise.resolve = function(v) { + return v; +}; +Promise.all.call(NotPromise, [thenable]); + +assert.sameValue(Object.prototype.hasOwnProperty.call(resolveElementFunction, "prototype"), false); +assert.throws(TypeError, function() { + new resolveElementFunction(); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-property-order.js b/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-property-order.js new file mode 100644 index 0000000000..a8bcc951de --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-property-order.js @@ -0,0 +1,32 @@ +// Copyright (C) 2020 ExE Boss. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-createbuiltinfunction +description: Promise.all resolve element function property order +info: | + Set order: "length", "name" +---*/ + +var resolveElementFunction; +var thenable = { + then: function(fulfill) { + resolveElementFunction = fulfill; + } +}; + +function NotPromise(executor) { + executor(function() {}, function() {}); +} +NotPromise.resolve = function(v) { + return v; +}; +Promise.all.call(NotPromise, [thenable]); + +var propNames = Object.getOwnPropertyNames(resolveElementFunction); +var lengthIndex = propNames.indexOf("length"); +var nameIndex = propNames.indexOf("name"); + +assert(lengthIndex >= 0 && nameIndex === lengthIndex + 1, + "The `length` property comes before the `name` property on built-in functions"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-prototype.js b/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-prototype.js new file mode 100644 index 0000000000..7daca24a61 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-prototype.js @@ -0,0 +1,32 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es6id: 25.4.4.1.2 +description: The [[Prototype]] of Promise.all Resolve 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. +---*/ + +var resolveElementFunction; +var thenable = { + then: function(fulfill) { + resolveElementFunction = fulfill; + } +}; + +function NotPromise(executor) { + executor(function() {}, function() {}); +} +NotPromise.resolve = function(v) { + return v; +}; +Promise.all.call(NotPromise, [thenable]); + +assert.sameValue(Object.getPrototypeOf(resolveElementFunction), Function.prototype); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/resolve-from-same-thenable.js b/js/src/tests/test262/built-ins/Promise/all/resolve-from-same-thenable.js new file mode 100644 index 0000000000..1a788c624c --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/resolve-from-same-thenable.js @@ -0,0 +1,81 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es6id: 25.4.4.1.1 +description: > + Cannot tamper remainingElementsCount when Promise.all resolve element function is called multiple times. +info: | + Runtime Semantics: PerformPromiseAll( iteratorRecord, constructor, resultCapability) + + ... + 4. Let remainingElementsCount be a new Record { [[value]]: 1 }. + ... + 6.d ... + ii. Set remainingElementsCount.[[value]] to remainingElementsCount.[[value]] − 1. + iii. If remainingElementsCount.[[value]] is 0, + 1. Let valuesArray be CreateArrayFromList(values). + 2. Let resolveResult be Call(resultCapability.[[Resolve]], undefined, «valuesArray»). + 3. ReturnIfAbrupt(resolveResult). + ... + + 25.4.4.1.2 Promise.all Resolve Element Functions + 1. Let alreadyCalled be the value of F's [[AlreadyCalled]] internal slot. + 2. If alreadyCalled.[[value]] is true, return undefined. + 3. Set alreadyCalled.[[value]] to true. + ... +---*/ + +var callCount = 0; + +function Constructor(executor) { + function resolve(values) { + callCount += 1; + assert(Array.isArray(values, "values is array")); + assert.sameValue(values.length, 3, "values length"); + assert.sameValue(values[0], "p1-fulfill", "values[0]"); + assert.sameValue(values[1], "p2-fulfill", "values[1]"); + assert.sameValue(values[2], "p3-fulfill", "values[2]"); + } + executor(resolve, Test262Error.thrower); +} +Constructor.resolve = function(v) { + return v; +}; + +var p1OnFulfilled, p2OnFulfilled, p3OnFulfilled; + +var p1 = { + then: function(onFulfilled, onRejected) { + p1OnFulfilled = onFulfilled; + } +}; +var p2 = { + then: function(onFulfilled, onRejected) { + p2OnFulfilled = onFulfilled; + } +}; +var p3 = { + then: function(onFulfilled, onRejected) { + p3OnFulfilled = onFulfilled; + } +}; + +assert.sameValue(callCount, 0, "callCount before call to all()"); + +Promise.all.call(Constructor, [p1, p2, p3]); + +assert.sameValue(callCount, 0, "callCount after call to all()"); + +p1OnFulfilled("p1-fulfill"); +p1OnFulfilled("p1-fulfill-unexpected-1"); +p1OnFulfilled("p1-fulfill-unexpected-2"); + +assert.sameValue(callCount, 0, "callCount after resolving p1"); + +p2OnFulfilled("p2-fulfill"); +p3OnFulfilled("p3-fulfill"); + +assert.sameValue(callCount, 1, "callCount after resolving all elements"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/resolve-ignores-late-rejection-deferred.js b/js/src/tests/test262/built-ins/Promise/all/resolve-ignores-late-rejection-deferred.js new file mode 100644 index 0000000000..3b8f52a09a --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/resolve-ignores-late-rejection-deferred.js @@ -0,0 +1,43 @@ +// |reftest| async +// 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/js/src/tests/test262/built-ins/Promise/all/resolve-ignores-late-rejection.js b/js/src/tests/test262/built-ins/Promise/all/resolve-ignores-late-rejection.js new file mode 100644 index 0000000000..cb830c90ff --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/resolve-ignores-late-rejection.js @@ -0,0 +1,39 @@ +// |reftest| async +// 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/js/src/tests/test262/built-ins/Promise/all/resolve-non-callable.js b/js/src/tests/test262/built-ins/Promise/all/resolve-non-callable.js new file mode 100644 index 0000000000..8807b8fc60 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/resolve-non-callable.js @@ -0,0 +1,37 @@ +// |reftest| async +// Copyright (C) 2020 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-promise.all +description: > + Promise.resolve is retrieved before GetIterator call (non-callable). +info: | + Promise.all ( iterable ) + + [...] + 3. Let promiseResolve be GetPromiseResolve(C). + 4. IfAbruptRejectPromise(promiseResolve, promiseCapability). + + GetPromiseResolve ( promiseConstructor ) + + [...] + 2. Let promiseResolve be ? Get(promiseConstructor, "resolve"). + 3. If IsCallable(promiseResolve) is false, throw a TypeError exception. +flags: [async] +features: [Symbol.iterator] +---*/ + +const iter = { + get [Symbol.iterator]() { + throw new Test262Error("unreachable"); + }, +}; + +Promise.resolve = "certainly not callable"; + +Promise.all(iter).then(() => { + throw new Test262Error("The promise should be rejected, but it was resolved"); +}, (reason) => { + assert(reason instanceof TypeError); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Promise/all/resolve-non-thenable.js b/js/src/tests/test262/built-ins/Promise/all/resolve-non-thenable.js new file mode 100644 index 0000000000..76c1781fd5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/resolve-non-thenable.js @@ -0,0 +1,76 @@ +// |reftest| async +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Resolving with a non-thenable object value +es6id: 25.4.4.1 +info: | + [...] + 6. Let promiseCapability be NewPromiseCapability(C). + [...] + 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + [...] + + 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + [...] + 6. Repeat + [...] + d. If next is false, + [...] + iii. If remainingElementsCount.[[value]] is 0, + 1. Let valuesArray be CreateArrayFromList(values). + 2. Let resolveResult be Call(resultCapability.[[Resolve]], + undefined, «valuesArray»). + 3. ReturnIfAbrupt(resolveResult) + iv. Return resultCapability.[[Promise]]. + + 25.4.1.3.2 Promise Resolve Functions + [...] + 8. Let then be Get(resolution, "then"). + 9. If then is an abrupt completion, then + [...] + 10. Let thenAction be then.[[value]]. + 11. If IsCallable(thenAction) is false, then + a. Return FulfillPromise(promise, resolution). +flags: [async] +---*/ + +var v1 = {}; +var v2 = {}; +var v3 = {}; + +Promise.all([v1, v2, v3]) + .then(function(values) { + if (!values) { + $DONE('The promise should be resolved with a value.'); + return; + } + if (values.constructor !== Array) { + $DONE('The promise should be resolved with an Array instance.'); + return; + } + + if (values.length !== 3) { + $DONE('The promise should be resolved with an array of proper length.'); + return; + } + + if (values[0] !== v1) { + $DONE('The promise should be resolved with the correct element values (#1)'); + return; + } + + if (values[1] !== v2) { + $DONE('The promise should be resolved with the correct element values (#2)'); + return; + } + + if (values[2] !== v3) { + $DONE('The promise should be resolved with the correct element values (#3)'); + return; + } + + $DONE(); + }, function() { + $DONE('The promise should not be rejected.'); + }); diff --git a/js/src/tests/test262/built-ins/Promise/all/resolve-not-callable-reject-with-typeerror.js b/js/src/tests/test262/built-ins/Promise/all/resolve-not-callable-reject-with-typeerror.js new file mode 100644 index 0000000000..c310818802 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/resolve-not-callable-reject-with-typeerror.js @@ -0,0 +1,29 @@ +// |reftest| async +// 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/js/src/tests/test262/built-ins/Promise/all/resolve-poisoned-then.js b/js/src/tests/test262/built-ins/Promise/all/resolve-poisoned-then.js new file mode 100644 index 0000000000..d877f7d3da --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/resolve-poisoned-then.js @@ -0,0 +1,72 @@ +// |reftest| async +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Resolving with an object with a "poisoned" `then` property +es6id: 25.4.4.1 +info: | + [...] + 6. Let promiseCapability be NewPromiseCapability(C). + [...] + 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + [...] + + 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + [...] + 6. Repeat + [...] + d. If next is false, + [...] + iii. If remainingElementsCount.[[value]] is 0, + 1. Let valuesArray be CreateArrayFromList(values). + 2. Let resolveResult be Call(resultCapability.[[Resolve]], + undefined, «valuesArray»). + 3. ReturnIfAbrupt(resolveResult) + iv. Return resultCapability.[[Promise]]. + + 7.3.16 CreateArrayFromList (elements) + [...] + 2. Let array be ArrayCreate(0) (see 9.4.2.2). + + 9.4.2.2 ArrayCreate(length, proto) + [...] + 4. If the proto argument was not passed, let proto be the intrinsic object + %ArrayPrototype%. + 5. Let A be a newly created Array exotic object. + [...] + 8. Set the [[Prototype]] internal slot of A to proto. + + 25.4.1.3.2 Promise Resolve Functions + [...] + 8. Let then be Get(resolution, "then"). + 9. If then is an abrupt completion, then + a. Return RejectPromise(promise, then.[[value]]). +flags: [async] +---*/ + +var value = {}; +var promise; + +try { + Object.defineProperty(Array.prototype, 'then', { + get: function() { + throw value; + }, + configurable: true + }); + + promise = Promise.all([]); +} finally { + delete Array.prototype.then; +} + +promise.then(function() { + $DONE('The promise should not be fulfilled.'); +}, function(val) { + if (val !== value) { + $DONE('The promise should be rejected with the expected value.'); + return; + } + + $DONE(); +}); diff --git a/js/src/tests/test262/built-ins/Promise/all/resolve-thenable.js b/js/src/tests/test262/built-ins/Promise/all/resolve-thenable.js new file mode 100644 index 0000000000..5fd1b42ee0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/resolve-thenable.js @@ -0,0 +1,74 @@ +// |reftest| async +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Resolving with a thenable object value +es6id: 25.4.4.1 +info: | + [...] + 6. Let promiseCapability be NewPromiseCapability(C). + [...] + 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). + [...] + + 25.4.4.1.1 Runtime Semantics: PerformPromiseAll + [...] + 6. Repeat + [...] + d. If next is false, + [...] + iii. If remainingElementsCount.[[value]] is 0, + 1. Let valuesArray be CreateArrayFromList(values). + 2. Let resolveResult be Call(resultCapability.[[Resolve]], + undefined, «valuesArray»). + 3. ReturnIfAbrupt(resolveResult) + iv. Return resultCapability.[[Promise]]. + + 7.3.16 CreateArrayFromList (elements) + [...] + 2. Let array be ArrayCreate(0) (see 9.4.2.2). + + 9.4.2.2 ArrayCreate(length, proto) + [...] + 4. If the proto argument was not passed, let proto be the intrinsic object + %ArrayPrototype%. + 5. Let A be a newly created Array exotic object. + [...] + 8. Set the [[Prototype]] internal slot of A to proto. + + 25.4.1.3.2 Promise Resolve Functions + [...] + 8. Let then be Get(resolution, "then"). + 9. If then is an abrupt completion, then + [...] + 10. Let thenAction be then.[[value]]. + 11. If IsCallable(thenAction) is false, then + [...] + 12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob, + «promise, resolution, thenAction») +flags: [async] +---*/ + +var value = {}; +var promise; + +try { + Array.prototype.then = function(resolve) { + resolve(value); + }; + + promise = Promise.all([]); +} finally { + delete Array.prototype.then; +} + +promise.then(function(val) { + if (val !== value) { + $DONE('The promise should be resolved with the expected value.'); + return; + } + + $DONE(); +}, function() { + $DONE('The promise should not be rejected.'); +}); diff --git a/js/src/tests/test262/built-ins/Promise/all/same-reject-function.js b/js/src/tests/test262/built-ins/Promise/all/same-reject-function.js new file mode 100644 index 0000000000..4112672a03 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/same-reject-function.js @@ -0,0 +1,46 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es6id: 25.4.4.1.1 +description: > + Each Promise.all element is called with the same reject function. +info: | + Runtime Semantics: PerformPromiseAll( iteratorRecord, constructor, resultCapability) + + ... + r. Let result be Invoke(nextPromise, "then", «resolveElement, resultCapability.[[Reject]]»). + ... +---*/ + +function rejectFunction() {} + +function Constructor(executor) { + executor(Test262Error.thrower, rejectFunction); +} +Constructor.resolve = function(v) { + return v; +}; + +var callCount1 = 0, + callCount2 = 0; + +var p1 = { + then: function(onFulfilled, onRejected) { + callCount1 += 1; + assert.sameValue(onRejected, rejectFunction, "p1.then"); + } +}; +var p2 = { + then: function(onFulfilled, onRejected) { + callCount2 += 1; + assert.sameValue(onRejected, rejectFunction, "p2.then"); + } +}; + +Promise.all.call(Constructor, [p1, p2]); + +assert.sameValue(callCount1, 1, "p1.then call count"); +assert.sameValue(callCount2, 1, "p2.then call count"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Promise/all/shell.js b/js/src/tests/test262/built-ins/Promise/all/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/shell.js diff --git a/js/src/tests/test262/built-ins/Promise/all/species-get-error.js b/js/src/tests/test262/built-ins/Promise/all/species-get-error.js new file mode 100644 index 0000000000..2c4597bcab --- /dev/null +++ b/js/src/tests/test262/built-ins/Promise/all/species-get-error.js @@ -0,0 +1,29 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Promise.all() does not retrieve `Symbol.species` property of the `this` value +es6id: 25.4.4.1 +info: | + 1. Let C be the this value. + 2. If Type(C) is not Object, throw a TypeError exception. + 3. Let promiseCapability be ? NewPromiseCapability(C). + ... +features: [Symbol.species] +---*/ + +function C(executor) { + executor(function() {}, function() {}); +} + +C.resolve = function() {}; +Object.defineProperty(C, Symbol.species, { + get: function() { + throw new Test262Error("Getter for Symbol.species called"); + } +}); + +Promise.all.call(C, []); + +reportCompare(0, 0); |