Merge pull request #2533 from tc39/promise-any

Promise.any & AggregateError tests (supercedes and closes gh-2437)
This commit is contained in:
Leo Balter 2020-03-27 20:18:57 -07:00 committed by GitHub
commit 4bf836c898
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
61 changed files with 2511 additions and 0 deletions

View File

@ -0,0 +1,106 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: >
Throws a TypeError if capabilities executor already called with non-undefined values.
info: |
Promise.any ( iterable )
...
2. Let promiseCapability be ? NewPromiseCapability(C).
...
GetCapabilitiesExecutor Functions
...
4. If promiseCapability.[[Resolve]] is not undefined, throw a TypeError exception.
5. If promiseCapability.[[Reject]] is not undefined, throw a TypeError exception.
6. Set promiseCapability.[[Resolve]] to resolve.
7. Set promiseCapability.[[Reject]] to reject.
...
features: [Promise.any]
---*/
var checkPoint = '';
function fn1(executor) {
checkPoint += 'a';
executor();
checkPoint += 'b';
executor(function() {}, function() {});
checkPoint += 'c';
}
fn1.resolve = function() {
throw new Test262Error();
};
Promise.any.call(fn1, []);
assert.sameValue(checkPoint, 'abc', 'executor initially called with no arguments');
checkPoint = '';
function fn2(executor) {
checkPoint += 'a';
executor(undefined, undefined);
checkPoint += 'b';
executor(function() {}, function() {});
checkPoint += 'c';
}
fn2.resolve = function() {
throw new Test262Error();
};
Promise.any.call(fn2, []);
assert.sameValue(checkPoint, 'abc', 'executor initially called with (undefined, undefined)');
checkPoint = '';
function fn3(executor) {
checkPoint += 'a';
executor(undefined, function() {});
checkPoint += 'b';
executor(function() {}, function() {});
checkPoint += 'c';
}
Object.defineProperty(fn3, 'resolve', {
get() {
throw new Test262Error();
}
});
assert.throws(TypeError, function() {
Promise.any.call(fn3, []);
}, 'executor initially called with (undefined, function)');
assert.sameValue(checkPoint, 'ab', 'executor initially called with (undefined, function)');
checkPoint = '';
function fn4(executor) {
checkPoint += 'a';
executor(function() {}, undefined);
checkPoint += 'b';
executor(function() {}, function() {});
checkPoint += 'c';
}
Object.defineProperty(fn4, 'resolve', {
get() {
throw new Test262Error();
}
});
assert.throws(TypeError, function() {
Promise.any.call(fn4, []);
}, 'executor initially called with (function, undefined)');
assert.sameValue(checkPoint, 'ab', 'executor initially called with (function, undefined)');
checkPoint = '';
function fn5(executor) {
checkPoint += 'a';
executor('invalid value', 123);
checkPoint += 'b';
executor(function() {}, function() {});
checkPoint += 'c';
}
Object.defineProperty(fn5, 'resolve', {
get() {
throw new Test262Error();
}
});
assert.throws(TypeError, function() {
Promise.any.call(fn5, []);
}, 'executor initially called with (String, Number)');
assert.sameValue(checkPoint, 'ab', 'executor initially called with (String, Number)');

View File

@ -0,0 +1,107 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: >
Throws a TypeError if either resolve or reject capability is not callable.
info: |
Promise.any ( iterable )
...
2. Let promiseCapability be ? NewPromiseCapability(C).
...
NewPromiseCapability ( C )
...
5. Let executor be ! CreateBuiltinFunction(steps, « [[Capability]] »).
6. Set executor.[[Capability]] to promiseCapability.
7. Let promise be ? Construct(C, « executor »).
8. If IsCallable(promiseCapability.[[Resolve]]) is false, throw a TypeError exception.
9. If IsCallable(promiseCapability.[[Reject]]) is false, throw a TypeError exception.
...
features: [Promise.any]
---*/
var checkPoint = '';
function fn1(executor) {
checkPoint += 'a';
}
Object.defineProperty(fn1, 'resolve', {
get() { throw new Test262Error(); }
});
assert.throws(TypeError, function() {
Promise.any.call(fn1, []);
}, 'executor not called at all');
assert.sameValue(checkPoint, 'a', 'executor not called at all');
checkPoint = '';
function fn2(executor) {
checkPoint += 'a';
executor();
checkPoint += 'b';
}
Object.defineProperty(fn2, 'resolve', {
get() { throw new Test262Error(); }
});
assert.throws(TypeError, function() {
Promise.any.call(fn2, []);
}, 'executor called with no arguments');
assert.sameValue(checkPoint, 'ab', 'executor called with no arguments');
checkPoint = '';
function fn3(executor) {
checkPoint += 'a';
executor(undefined, undefined);
checkPoint += 'b';
}
Object.defineProperty(fn3, 'resolve', {
get() { throw new Test262Error(); }
});
assert.throws(TypeError, function() {
Promise.any.call(fn3, []);
}, 'executor called with (undefined, undefined)');
assert.sameValue(checkPoint, 'ab', 'executor called with (undefined, undefined)');
checkPoint = '';
function fn4(executor) {
checkPoint += 'a';
executor(undefined, function() {});
checkPoint += 'b';
}
Object.defineProperty(fn4, 'resolve', {
get() { throw new Test262Error(); }
});
assert.throws(TypeError, function() {
Promise.any.call(fn4, []);
}, 'executor called with (undefined, function)');
assert.sameValue(checkPoint, 'ab', 'executor called with (undefined, function)');
checkPoint = '';
function fn5(executor) {
checkPoint += 'a';
executor(function() {}, undefined);
checkPoint += 'b';
}
Object.defineProperty(fn5, 'resolve', {
get() { throw new Test262Error(); }
});
assert.throws(TypeError, function() {
Promise.any.call(fn5, []);
}, 'executor called with (function, undefined)');
assert.sameValue(checkPoint, 'ab', 'executor called with (function, undefined)');
checkPoint = '';
function fn6(executor) {
checkPoint += 'a';
executor(123, 'invalid value');
checkPoint += 'b';
}
Object.defineProperty(fn6, 'resolve', {
get() { throw new Test262Error(); }
});
assert.throws(TypeError, function() {
Promise.any.call(fn6, []);
}, 'executor called with (Number, String)');
assert.sameValue(checkPoint, 'ab', 'executor called with (Number, String)');

View File

@ -0,0 +1,25 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Promise.any invoked on a constructor value that throws an error
esid: sec-promise.any
info: |
2. Let promiseCapability be ? NewPromiseCapability(C).
NewPromiseCapability
...
7. Let promise be ? Construct(C, « executor »).
features: [Promise.any]
---*/
function CustomPromise() {
throw new Test262Error();
}
assert.throws(Test262Error, function() {
Promise.any.call(CustomPromise);
});

View File

@ -0,0 +1,34 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Promise.any invoked on a constructor value
esid: sec-promise.any
info: |
2. Let promiseCapability be ? NewPromiseCapability(C).
...
5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
...
7. Return Completion(result).
features: [Promise.any, class]
---*/
var executor = null;
var callCount = 0;
class SubPromise extends Promise {
constructor(a) {
super(a);
executor = a;
callCount += 1;
}
}
var instance = Promise.any.call(SubPromise, []);
assert.sameValue(instance.constructor, SubPromise);
assert.sameValue(instance instanceof SubPromise, true);
assert.sameValue(callCount, 1);
assert.sameValue(typeof executor, 'function');

View File

@ -0,0 +1,47 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Promise.any invoked on a non-constructor value
esid: sec-promise.any
info: |
...
2. Let promiseCapability be ? NewPromiseCapability(C).
NewPromiseCapability ( C )
1. If IsConstructor(C) is false, throw a TypeError exception.
features: [Promise.any, Symbol]
---*/
assert.sameValue(typeof Promise.any, 'function');
assert.throws(TypeError, function() {
Promise.any.call(eval);
});
assert.throws(TypeError, function() {
Promise.any.call(undefined, []);
});
assert.throws(TypeError, function() {
Promise.any.call(null, []);
});
assert.throws(TypeError, function() {
Promise.any.call(86, []);
});
assert.throws(TypeError, function() {
Promise.any.call('string', []);
});
assert.throws(TypeError, function() {
Promise.any.call(true, []);
});
assert.throws(TypeError, function() {
Promise.any.call(Symbol(), []);
});

View File

@ -0,0 +1,29 @@
// Copyright (C) 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: >
Promise.any.call(Custom, ...) does not derive a constructor via SpeciesConstructor()
info: |
1. Let C be the this value.
2. Let promiseCapability be ? NewPromiseCapability(C).
...
NewPromiseCapability ( C )
1. If IsConstructor(C) is false, throw a TypeError exception.
2. NOTE: C is assumed to be a constructor function that supports the parameter conventions of the Promise constructor (see 25.6.3.1).
...
flags: [async]
features: [Promise.any, Symbol.species, class, computed-property-names, Symbol, arrow-function]
---*/
class Custom extends Promise {
static get [Symbol.species]() {
throw new Test262Error('Erroneous Get(C, @@species) via SpeciesConstructor() occurred.');
}
}
Promise.any.call(Custom, [1]).then(() => $DONE(), $DONE);

View File

@ -0,0 +1,29 @@
// Copyright (C) 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: >
Promise.any() does not derive a constructor via SpeciesConstructor()
info: |
1. Let C be the this value.
2. Let promiseCapability be ? NewPromiseCapability(C).
...
NewPromiseCapability ( C )
1. If IsConstructor(C) is false, throw a TypeError exception.
2. NOTE: C is assumed to be a constructor function that supports the parameter conventions of the Promise constructor (see 25.6.3.1).
...
flags: [async]
features: [Promise.any, Symbol.species, Symbol, arrow-function]
---*/
Object.defineProperty(Promise, Symbol.species, {
get() {
throw new Test262Error('Erroneous Get(C, @@species) via SpeciesConstructor() occurred.');
}
});
Promise.any([1]).then(() => $DONE(), $DONE);

View File

@ -0,0 +1,53 @@
// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Explicit iterator closing in response to error
esid: sec-promise.any
info: |
5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
6. If result is an abrupt completion, then
a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
b. IfAbruptRejectPromise(result, promiseCapability).
Runtime Semantics: PerformPromiseAny
8. Repeat
...
i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
flags: [async]
features: [Promise.any, Symbol.iterator, computed-property-names, Symbol, arrow-function]
---*/
let error = new Test262Error();
let nextCount = 0;
let returnCount = 0;
let iter = {
[Symbol.iterator]() {
return {
next() {
nextCount += 1;
return {
value: null,
done: false
};
},
return() {
returnCount += 1;
}
};
}
};
Promise.resolve = function() {
throw error;
};
Promise.any(iter).then(() => {
$DONE('The promise should be rejected, but was resolved');
}, (reason) => {
assert.sameValue(nextCount, 1);
assert.sameValue(returnCount, 1);
assert.sameValue(reason, error);
}).then($DONE, $DONE);

View File

@ -0,0 +1,32 @@
// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Promise rejection in response to error
esid: sec-promise.any
info: |
5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
6. If result is an abrupt completion, then
a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
b. IfAbruptRejectPromise(result, promiseCapability).
Runtime Semantics: PerformPromiseAny
8. Repeat
...
i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
flags: [async]
features: [Promise.any, arrow-function]
---*/
let error = new Test262Error();
Promise.resolve = function() {
throw error;
};
Promise.any([1]).then(() => {
$DONE('The promise should be rejected, but was resolved');
}, (reason) => {
assert.sameValue(reason, error);
}).then($DONE, $DONE);

View File

@ -0,0 +1,57 @@
// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Error retrieving the constructor's `resolve` method not opening iterator
esid: sec-promise.any
info: |
5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
6. If result is an abrupt completion, then
a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
b. IfAbruptRejectPromise(result, promiseCapability).
Runtime Semantics: PerformPromiseAny
8. Repeat
...
i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
flags: [async]
features: [Promise.any, Symbol.iterator, computed-property-names, Symbol, arrow-function]
---*/
let error = new Test262Error();
let nextCount = 0;
let returnCount = 0;
let iter = {
[Symbol.iterator]() {
return {
next() {
nextCount += 1;
return {
value: null,
done: false
};
},
return() {
returnCount += 1;
}
};
}
};
Object.defineProperty(Promise, 'resolve', {
get() {
throw error;
}
});
Promise.any(iter).then(() => {
$DONE('The promise should be rejected, but was resolved');
}, (reason) => {
assert.sameValue(nextCount, 0);
assert.sameValue(returnCount, 1);
assert.sameValue(reason, error);
}).then($DONE, $DONE);

View File

@ -0,0 +1,35 @@
// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Error retrieving the constructor's `resolve` method (rejecting promise)
esid: sec-promise.any
info: |
5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
6. If result is an abrupt completion, then
a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
b. IfAbruptRejectPromise(result, promiseCapability).
Runtime Semantics: PerformPromiseAny
8. Repeat
...
i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
flags: [async]
features: [Promise.any, arrow-function]
---*/
let error = new Test262Error();
Object.defineProperty(Promise, 'resolve', {
get() {
throw error;
}
});
Promise.any([1]).then(() => {
$DONE('The promise should be rejected, but was resolved');
}, (reason) => {
assert.sameValue(reason, error);
}).then($DONE, $DONE);

View File

@ -0,0 +1,54 @@
// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Gets constructor's `resolve` method once from zero to many invocations.
esid: sec-promise.any
info: |
5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
6. If result is an abrupt completion, then
a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
b. IfAbruptRejectPromise(result, promiseCapability).
Runtime Semantics: PerformPromiseAny
6. Let promiseResolve be ? Get(constructor, "resolve").
7. If ! IsCallable(promiseResolve) is false, throw a TypeError exception.
8. Repeat
...
i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
flags: [async]
features: [Promise.any, arrow-function, destructuring-binding]
---*/
let promises = [
Promise.reject(1),
Promise.reject(1),
Promise.reject(1),
];
let boundPromiseResolve = Promise.resolve.bind(Promise);
let getCount = 0;
let callCount = 0;
Object.defineProperty(Promise, 'resolve', {
configurable: true,
get() {
getCount += 1;
return function(...args) {
callCount += 1;
return boundPromiseResolve(...args);
};
}
});
Promise.any(promises).then(() => {
$DONE('The promise should be rejected, but was resolved');
}, ({errors}) => {
assert.sameValue(getCount, 1);
assert.sameValue(callCount, 3);
assert.sameValue(errors.length, 3);
}).then($DONE, $DONE);

View File

@ -0,0 +1,49 @@
// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Gets constructor's `resolve` method once from zero to many invocations.
esid: sec-promise.any
info: |
5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
6. If result is an abrupt completion, then
a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
b. IfAbruptRejectPromise(result, promiseCapability).
Runtime Semantics: PerformPromiseAny
6. Let promiseResolve be ? Get(constructor, "resolve").
7. If ! IsCallable(promiseResolve) is false, throw a TypeError exception.
8. Repeat
...
i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
flags: [async]
features: [Promise.any, arrow-function, destructuring-binding]
---*/
let boundPromiseResolve = Promise.resolve.bind(Promise);
let getCount = 0;
let callCount = 0;
Object.defineProperty(Promise, 'resolve', {
configurable: true,
get() {
getCount += 1;
return function(...args) {
callCount += 1;
return boundPromiseResolve(...args);
};
}
});
Promise.any([]).then(() => {
$DONE('The promise should be rejected, but was resolved');
}, ({errors}) => {
assert.sameValue(getCount, 1);
assert.sameValue(callCount, 0);
assert.sameValue(errors.length, 0);
}).then($DONE, $DONE);

View File

@ -0,0 +1,28 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
If the constructor's `resolve` method is not callable, reject with a TypeError.
esid: sec-promise.any
info: |
5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
Runtime Semantics: PerformPromiseAny
6. Let promiseResolve be ? Get(constructor, "resolve").
7. If ! IsCallable(promiseResolve) is false, throw a TypeError exception.
flags: [async]
features: [Promise.any, arrow-function]
---*/
Promise.resolve = null;
Promise.any([1])
.then(
() => $DONE('The promise should not be resolved.'),
error => {
assert(error instanceof TypeError);
}
).then($DONE, $DONE);

View File

@ -0,0 +1,43 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Invocation of the constructor's `resolve` method for iterable with promise values
esid: sec-promise.any
info: |
5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
Runtime Semantics: PerformPromiseAny
8. Repeat
...
i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
flags: [async]
features: [Promise.any, class, arrow-function]
---*/
class Custom extends Promise {}
let values = [1, 1, 1];
let cresolveCallCount = 0;
let presolveCallCount = 0;
let boundCustomResolve = Custom.resolve.bind(Custom);
let boundPromiseResolve = Promise.resolve.bind(Promise);
Custom.resolve = function(...args) {
cresolveCallCount += 1;
return boundCustomResolve(...args);
};
Promise.resolve = function(...args) {
presolveCallCount += 1;
return boundPromiseResolve(...args);
};
Promise.any.call(Custom, values)
.then(() => {
assert.sameValue(presolveCallCount, 0, '`Promise.resolve` is never invoked');
assert.sameValue(cresolveCallCount, 3, '`Custom.resolve` invoked once for every iterated promise');
}, $DONE).then($DONE, $DONE);

View File

@ -0,0 +1,34 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Invocation of the constructor's `resolve` method for iterable with promise values
esid: sec-promise.any
info: |
5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
Runtime Semantics: PerformPromiseAny
8. Repeat
...
i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
flags: [async]
features: [Promise.any, arrow-function]
---*/
let values = [1,1,1];
let callCount = 0;
let boundPromiseResolve = Promise.resolve.bind(Promise);
Promise.resolve = function(...args) {
callCount += 1;
return boundPromiseResolve(...args);
};
Promise.any(values)
.then(() => {
assert.sameValue(callCount, 3, '`then` invoked once for every iterated promise');
}, $DONE).then($DONE, $DONE);

View File

@ -0,0 +1,43 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Invocation of the constructor's `resolve` method for iterable with non-promise values
esid: sec-promise.any
info: |
5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
Runtime Semantics: PerformPromiseAny
8. Repeat
...
i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
flags: [async]
features: [Promise.any, class, arrow-function]
---*/
class Custom extends Promise {}
let values = [1, 2, 3];
let cresolveCallCount = 0;
let presolveCallCount = 0;
let boundCustomResolve = Custom.resolve.bind(Custom);
let boundPromiseResolve = Promise.resolve.bind(Promise);
Custom.resolve = function(...args) {
cresolveCallCount += 1;
return boundCustomResolve(...args);
};
Promise.resolve = function(...args) {
presolveCallCount += 1;
return boundPromiseResolve(...args);
};
Promise.any.call(Custom, values)
.then(() => {
assert.sameValue(presolveCallCount, 0, '`Promise.resolve` is never invoked');
assert.sameValue(cresolveCallCount, 3, '`Custom.resolve` invoked once for every iterated promise');
}, $DONE).then($DONE, $DONE);

View File

@ -0,0 +1,34 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Invocation of the constructor's `resolve` method for iterable with non-promise values
esid: sec-promise.any
info: |
5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
Runtime Semantics: PerformPromiseAny
8. Repeat
...
i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
flags: [async]
features: [Promise.any, arrow-function]
---*/
let values = [1, 2, 3];
let callCount = 0;
let boundPromiseResolve = Promise.resolve.bind(Promise);
Promise.resolve = function(...args) {
callCount += 1;
return boundPromiseResolve(...args);
};
Promise.any(values)
.then(() => {
assert.sameValue(callCount, 3, '`Promise.resolve` invoked once for every iterated value');
}, $DONE).then($DONE, $DONE);

View File

@ -0,0 +1,31 @@
// Copyright (C) 2019 Sergey Rubanov, 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Invocation of the constructor's `resolve` method
esid: sec-promise.any
info: |
5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
Runtime Semantics: PerformPromiseAny
8. Repeat
...
i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
...
r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »).
flags: [async]
features: [Promise.any, arrow-function]
---*/
let boundPromiseResolve = Promise.resolve.bind(Promise);
Promise.resolve = function(...args) {
assert.sameValue(args.length, 1, '`resolve` invoked with a single argument');
assert.sameValue(this, Promise, '`this` value is the constructor');
return boundPromiseResolve(...args);
};
Promise.any([1]).then(() => $DONE(), $DONE);

View File

@ -0,0 +1,50 @@
// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Error thrown when invoking the instance's `then` method (closing iterator)
esid: sec-promise.any
info: |
5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
6. If result is an abrupt completion, then
a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
b. IfAbruptRejectPromise(result, promiseCapability).
Runtime Semantics: PerformPromiseAny
r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »).
flags: [async]
features: [Promise.any, Symbol.iterator, arrow-function, computed-property-names, Symbol]
---*/
let error = new Test262Error();
let promise = Promise.resolve();
let returnCount = 0;
let iter = {
[Symbol.iterator]() {
return {
next() {
return {
done: false,
value: promise
};
},
return() {
returnCount += 1;
return {};
}
};
}
};
promise.then = function() {
throw error;
};
Promise.any(iter).then(() => {
$DONE('The promise should be rejected, but was resolved');
}, (reason) => {
assert.sameValue(returnCount, 1);
assert.sameValue(reason, error);
}).then($DONE, $DONE);

View File

@ -0,0 +1,32 @@
// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Error thrown when invoking the instance's `then` method (rejecting Promise)
esid: sec-promise.any
info: |
5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
6. If result is an abrupt completion, then
a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
b. IfAbruptRejectPromise(result, promiseCapability).
Runtime Semantics: PerformPromiseAny
r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »).
flags: [async]
features: [Promise.any, arrow-function]
---*/
let error = new Test262Error();
let promise = Promise.resolve();
promise.then = function() {
throw error;
};
Promise.any([promise]).then(() => {
$DONE('The promise should be rejected, but was resolved');
}, (reason) => {
assert.sameValue(reason, error);
}).then($DONE, $DONE);

View File

@ -0,0 +1,51 @@
// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Error thrown when accesing the instance's `then` method (closing iterator)
esid: sec-promise.any
info: |
5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
6. If result is an abrupt completion, then
a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
b. IfAbruptRejectPromise(result, promiseCapability).
Runtime Semantics: PerformPromiseAny
r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »).
flags: [async]
features: [Promise.any, Symbol.iterator, arrow-function, computed-property-names, Symbol]
---*/
let error = new Test262Error();
let promise = Promise.resolve();
let returnCount = 0;
let iter = {
[Symbol.iterator]() {
return {
next() {
return {
done: false,
value: promise
};
},
return() {
returnCount += 1;
return {};
}
};
}
};
Object.defineProperty(promise, 'then', {
get() {
throw error;
}
});
Promise.any(iter).then(() => {
$DONE('The promise should be rejected, but was resolved');
}, (reason) => {
assert.sameValue(returnCount, 1);
assert.sameValue(reason, error);
}).then($DONE, $DONE);

View File

@ -0,0 +1,33 @@
// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Error thrown when accessing the instance's `then` method (rejecting Promise)
esid: sec-promise.any
info: |
5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
6. If result is an abrupt completion, then
a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
b. IfAbruptRejectPromise(result, promiseCapability).
Runtime Semantics: PerformPromiseAny
r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »).
flags: [async]
features: [Promise.any, arrow-function]
---*/
let error = new Test262Error();
let promise = Promise.resolve();
Object.defineProperty(promise, 'then', {
get() {
throw error;
}
});
Promise.any([promise]).then(() => {
$DONE('The promise should be rejected, but was resolved');
}, (reason) => {
assert.sameValue(reason, error);
}).then($DONE, $DONE);

View File

@ -0,0 +1,41 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Invocation of the instance's `then` method
esid: sec-promise.any
info: |
5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
6. If result is an abrupt completion, then
a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
b. IfAbruptRejectPromise(result, promiseCapability).
Runtime Semantics: PerformPromiseAny
r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »).
flags: [async]
features: [Promise.any, arrow-function]
---*/
let promises = [
Promise.resolve(),
Promise.resolve(),
Promise.resolve(),
];
let callCount = 0;
promises.forEach(promise => {
let boundThen = promise.then.bind(promise);
promise.then = function(...args) {
assert.sameValue(this, promises[callCount]);
callCount += 1;
return boundThen(...args);
};
});
Promise.any(promises)
.then(() => {
assert.sameValue(callCount, 3, '`then` invoked once for every iterated value');
}, $DONE).then($DONE, $DONE);

View File

@ -0,0 +1,34 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Invocation of the instance's `then` method
esid: sec-promise.any
info: |
5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
6. If result is an abrupt completion, then
a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
b. IfAbruptRejectPromise(result, promiseCapability).
Runtime Semantics: PerformPromiseAny
r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »).
flags: [async]
features: [Promise.any, arrow-function]
---*/
let promise = new Promise(() => {});
let boundThen = promise.then.bind(promise);
promise.then = function(resolver, rejectElement) {
assert.sameValue(this, promise);
assert.sameValue(typeof resolver, 'function');
assert.sameValue(resolver.length, 1, 'resolver.length is 1');
assert.sameValue(typeof rejectElement, 'function');
assert.sameValue(rejectElement.length, 1, 'rejectElement.length is 0');
return boundThen(resolver, rejectElement);
};
Promise.any([promise]).then(() => $DONE(), $DONE);

View File

@ -0,0 +1,10 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: Promise.any is callable
features: [Promise.any]
---*/
assert.sameValue(typeof Promise.any, 'function');

View File

@ -0,0 +1,39 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: >
Promise.any([]) rejects with AggregateError, empty errors array.
info: |
Runtime Semantics: PerformPromiseAny ( iteratorRecord, constructor, resultCapability )
...
3. Let errors be a new empty List.
...
8. Repeat,
a. Let next be IteratorStep(iteratorRecord).
b. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
c. ReturnIfAbrupt(next).
d. If next is false, then
i. Set iteratorRecord.[[Done]] to true.
ii. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
iii. If remainingElementsCount.[[Value]] is 0, then
1. Let error be a newly created AggregateError object.
2. Set error.[[AggregateErrors]] to errors.
3. Return ThrowCompletion(error).
...
flags: [async]
features: [AggregateError, Promise.any, arrow-function]
---*/
Promise.any([])
.then(
() => $DONE('The promise should be rejected, but was resolved'),
error => {
assert.sameValue(Object.getPrototypeOf(error), AggregateError.prototype);
assert(error instanceof AggregateError);
assert.sameValue(error.errors.length, 0);
}
).then($DONE, $DONE);

View File

@ -0,0 +1,39 @@
// Copyright (C) 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: >
Promise.any('') rejects with AggregateError, empty errors array.
info: |
Runtime Semantics: PerformPromiseAny ( iteratorRecord, constructor, resultCapability )
...
3. Let errors be a new empty List.
...
8. Repeat,
a. Let next be IteratorStep(iteratorRecord).
b. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
c. ReturnIfAbrupt(next).
d. If next is false, then
i. Set iteratorRecord.[[Done]] to true.
ii. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
iii. If remainingElementsCount.[[Value]] is 0, then
1. Let error be a newly created AggregateError object.
2. Set error.[[AggregateErrors]] to errors.
3. Return ThrowCompletion(error).
...
features: [AggregateError, Promise.any, arrow-function]
flags: [async]
---*/
Promise.any('')
.then(
() => $DONE('The promise should be rejected, but was resolved'),
error => {
assert.sameValue(Object.getPrototypeOf(error), AggregateError.prototype);
assert(error instanceof AggregateError);
assert.sameValue(error.errors.length, 0);
}
).then($DONE, $DONE);

View File

@ -0,0 +1,36 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: >
Promise.any(false) rejects with TypeError.
info: |
Promise.any ( iterable )
...
3. Let iteratorRecord be GetIterator(iterable).
4. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
...
#sec-getiterator
GetIterator ( obj [ , hint [ , method ] ] )
...
Let iterator be ? Call(method, obj).
If Type(iterator) is not Object, throw a TypeError exception.
...
features: [Promise.any]
flags: [async]
---*/
try {
Promise.any(false).then(function() {
$DONE('The promise should be rejected, but was resolved');
}, function(error) {
assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
assert(error instanceof TypeError);
}).then($DONE, $DONE);
} catch (error) {
$DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
}

View File

@ -0,0 +1,36 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: >
Promise.any(null) rejects with TypeError.
info: |
Promise.any ( iterable )
...
3. Let iteratorRecord be GetIterator(iterable).
4. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
...
#sec-getiterator
GetIterator ( obj [ , hint [ , method ] ] )
...
Let iterator be ? Call(method, obj).
If Type(iterator) is not Object, throw a TypeError exception.
...
features: [Promise.any]
flags: [async]
---*/
try {
Promise.any(null).then(function() {
$DONE('The promise should be rejected, but was resolved');
}, function(error) {
assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
assert(error instanceof TypeError);
}).then($DONE, $DONE);
} catch (error) {
$DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
}

View File

@ -0,0 +1,36 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: >
Promise.any(number) rejects with TypeError.
info: |
Promise.any ( iterable )
...
3. Let iteratorRecord be GetIterator(iterable).
4. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
...
#sec-getiterator
GetIterator ( obj [ , hint [ , method ] ] )
...
Let iterator be ? Call(method, obj).
If Type(iterator) is not Object, throw a TypeError exception.
...
features: [Promise.any]
flags: [async]
---*/
try {
Promise.any(1).then(function() {
$DONE('The promise should be rejected, but was resolved');
}, function(error) {
assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
assert(error instanceof TypeError);
}).then($DONE, $DONE);
} catch (error) {
$DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
}

View File

@ -0,0 +1,42 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: >
Promise.any(poisoned iterable) rejects with whatever error is thrown.
info: |
Promise.any ( iterable )
...
3. Let iteratorRecord be GetIterator(iterable).
4. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
...
#sec-getiterator
GetIterator ( obj [ , hint [ , method ] ] )
...
Let iterator be ? Call(method, obj).
...
features: [Promise.any, Symbol, Symbol.iterator, arrow-function]
flags: [async]
---*/
var poison = [];
Object.defineProperty(poison, Symbol.iterator, {
get() {
throw new Test262Error();
}
});
try {
Promise.any(poison).then(() => {
$DONE('The promise should be rejected, but was resolved');
}, (error) => {
assert.sameValue(Object.getPrototypeOf(error), Test262Error.prototype);
assert(error instanceof Test262Error);
}).then($DONE, $DONE);
} catch (error) {
$DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
}

View File

@ -0,0 +1,36 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: >
Promise.any('non-empty-string') resolves with the first character in the non-empty string
info: |
Promise.any ( iterable )
...
3. Let iteratorRecord be GetIterator(iterable).
4. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
...
#sec-getiterator
GetIterator ( obj [ , hint [ , method ] ] )
...
Let iterator be ? Call(method, obj).
If Type(iterator) is not Object, throw a TypeError exception.
...
features: [Promise.any, arrow-function]
flags: [async]
---*/
try {
Promise.any('xyz').then(v => {
assert.sameValue(v, 'x');
assert.sameValue(v.length, 1);
}, error => {
$DONE(`The promise should be resolved, but was rejected with error: ${error.message}`);
}).then($DONE, $DONE);
} catch (error) {
$DONE(`The promise should be resolved, but threw an exception: ${error.message}`);
}

View File

@ -0,0 +1,49 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: >
Promise.any(Symbol()) rejects with TypeError.
info: |
Promise.any ( iterable )
...
3. Let iteratorRecord be GetIterator(iterable).
4. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
...
GetIterator ( obj [ , hint [ , method ] ] )
...
3. If method is not present, then
a. If hint is async, then
...
b. Otherwise, set method to ? GetMethod(obj, @@iterator).
4. Let iterator be ? Call(method, obj).
5. If Type(iterator) is not Object, throw a TypeError exception.
...
GetMethod
2. Let func be ? GetV(V, P).
3. If func is either undefined or null, return undefined.
4. If IsCallable(func) is false, throw a TypeError exception.
Call ( F, V [ , argumentsList ] )
2. If IsCallable(F) is false, throw a TypeError exception.
features: [Promise.any, Symbol]
flags: [async]
---*/
try {
Promise.any(Symbol()).then(function() {
$DONE('The promise should be rejected, but was resolved');
}, function(error) {
assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
assert(error instanceof TypeError);
}).then($DONE, $DONE);
} catch (error) {
$DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
}

View File

@ -0,0 +1,49 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: >
Promise.any(true) rejects with TypeError.
info: |
Promise.any ( iterable )
...
3. Let iteratorRecord be GetIterator(iterable).
4. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
...
GetIterator ( obj [ , hint [ , method ] ] )
...
3. If method is not present, then
a. If hint is async, then
...
b. Otherwise, set method to ? GetMethod(obj, @@iterator).
4. Let iterator be ? Call(method, obj).
5. If Type(iterator) is not Object, throw a TypeError exception.
...
GetMethod
2. Let func be ? GetV(V, P).
3. If func is either undefined or null, return undefined.
4. If IsCallable(func) is false, throw a TypeError exception.
Call ( F, V [ , argumentsList ] )
2. If IsCallable(F) is false, throw a TypeError exception.
features: [Promise.any]
flags: [async]
---*/
try {
Promise.any(true).then(function() {
$DONE('The promise should be rejected, but was resolved');
}, function(error) {
assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
assert(error instanceof TypeError);
}).then($DONE, $DONE);
} catch (error) {
$DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
}

View File

@ -0,0 +1,49 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: >
Promise.any(undefined) rejects with TypeError.
info: |
Promise.any ( iterable )
...
3. Let iteratorRecord be GetIterator(iterable).
4. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
...
GetIterator ( obj [ , hint [ , method ] ] )
...
3. If method is not present, then
a. If hint is async, then
...
b. Otherwise, set method to ? GetMethod(obj, @@iterator).
4. Let iterator be ? Call(method, obj).
5. If Type(iterator) is not Object, throw a TypeError exception.
...
GetMethod
2. Let func be ? GetV(V, P).
3. If func is either undefined or null, return undefined.
4. If IsCallable(func) is false, throw a TypeError exception.
Call ( F, V [ , argumentsList ] )
2. If IsCallable(F) is false, throw a TypeError exception.
features: [Promise.any]
flags: [async]
---*/
try {
Promise.any(undefined).then(function() {
$DONE('The promise should be rejected, but was resolved');
}, function(error) {
assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
assert(error instanceof TypeError);
}).then($DONE, $DONE);
} catch (error) {
$DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
}

View File

@ -0,0 +1,53 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: >
Reject when argument's Symbol.iterator property has the value false
info: |
Promise.any ( iterable )
...
4. Let iteratorRecord be GetIterator(iterable).
5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
...
GetIterator ( obj [ , hint [ , method ] ] )
...
3. If method is not present, then
a. If hint is async, then
i. Set method to ? GetMethod(obj, @@asyncIterator).
ii. If method is undefined, then
1. Let syncMethod be ? GetMethod(obj, @@iterator).
2. Let syncIteratorRecord be ? GetIterator(obj, sync, syncMethod).
...
4. Let iterator be ? Call(method, obj).
...
GetMethod
2. Let func be ? GetV(V, P).
3. If func is either undefined or null, return undefined.
4. If IsCallable(func) is false, throw a TypeError exception.
Call ( F, V [ , argumentsList ] )
2. If IsCallable(F) is false, throw a TypeError exception.
features: [Promise.any, Symbol.iterator, Symbol, computed-property-names]
flags: [async]
---*/
try {
Promise.any({
[Symbol.iterator]: false
}).then(function() {
$DONE('The promise should be rejected, but was resolved');
}, function(error) {
assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
assert(error instanceof TypeError);
}).then($DONE, $DONE);
} catch (error) {
$DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
}

View File

@ -0,0 +1,51 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: >
Reject when argument's Symbol.iterator property has the value null
info: |
Promise.any ( iterable )
...
4. Let iteratorRecord be GetIterator(iterable).
5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
...
GetIterator ( obj [ , hint [ , method ] ] )
...
3. If method is not present, then
a. If hint is async, then
...
b. Otherwise, set method to ? GetMethod(obj, @@iterator).
4. Let iterator be ? Call(method, obj).
5. If Type(iterator) is not Object, throw a TypeError exception.
...
GetMethod
2. Let func be ? GetV(V, P).
3. If func is either undefined or null, return undefined.
4. If IsCallable(func) is false, throw a TypeError exception.
Call ( F, V [ , argumentsList ] )
2. If IsCallable(F) is false, throw a TypeError exception.
features: [Promise.any, Symbol.iterator, Symbol, computed-property-names]
flags: [async]
---*/
try {
Promise.any({
[Symbol.iterator]: null
}).then(function() {
$DONE('The promise should be rejected, but was resolved');
}, function(error) {
assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
assert(error instanceof TypeError);
}).then($DONE, $DONE);
} catch (error) {
$DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
}

View File

@ -0,0 +1,51 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: >
Reject when argument's Symbol.iterator property has the value 1
info: |
Promise.any ( iterable )
...
4. Let iteratorRecord be GetIterator(iterable).
5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
...
GetIterator ( obj [ , hint [ , method ] ] )
...
3. If method is not present, then
a. If hint is async, then
...
b. Otherwise, set method to ? GetMethod(obj, @@iterator).
4. Let iterator be ? Call(method, obj).
5. If Type(iterator) is not Object, throw a TypeError exception.
...
GetMethod
2. Let func be ? GetV(V, P).
3. If func is either undefined or null, return undefined.
4. If IsCallable(func) is false, throw a TypeError exception.
Call ( F, V [ , argumentsList ] )
2. If IsCallable(F) is false, throw a TypeError exception.
features: [Promise.any, Symbol.iterator, Symbol, computed-property-names]
flags: [async]
---*/
try {
Promise.any({
[Symbol.iterator]: 1
}).then(function() {
$DONE('The promise should be rejected, but was resolved');
}, function(error) {
assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
assert(error instanceof TypeError);
}).then($DONE, $DONE);
} catch (error) {
$DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
}

View File

@ -0,0 +1,51 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: >
Reject when argument's Symbol.iterator property has the value ""
info: |
Promise.any ( iterable )
...
4. Let iteratorRecord be GetIterator(iterable).
5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
...
GetIterator ( obj [ , hint [ , method ] ] )
...
3. If method is not present, then
a. If hint is async, then
...
b. Otherwise, set method to ? GetMethod(obj, @@iterator).
4. Let iterator be ? Call(method, obj).
5. If Type(iterator) is not Object, throw a TypeError exception.
...
GetMethod
2. Let func be ? GetV(V, P).
3. If func is either undefined or null, return undefined.
4. If IsCallable(func) is false, throw a TypeError exception.
Call ( F, V [ , argumentsList ] )
2. If IsCallable(F) is false, throw a TypeError exception.
features: [Promise.any, Symbol.iterator, Symbol, computed-property-names]
flags: [async]
---*/
try {
Promise.any({
[Symbol.iterator]: ''
}).then(function() {
$DONE('The promise should be rejected, but was resolved');
}, function(error) {
assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
assert(error instanceof TypeError);
}).then($DONE, $DONE);
} catch (error) {
$DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
}

View File

@ -0,0 +1,51 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: >
Reject when argument's Symbol.iterator property has the value Symbol()
info: |
Promise.any ( iterable )
...
4. Let iteratorRecord be GetIterator(iterable).
5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
...
GetIterator ( obj [ , hint [ , method ] ] )
...
3. If method is not present, then
a. If hint is async, then
...
b. Otherwise, set method to ? GetMethod(obj, @@iterator).
4. Let iterator be ? Call(method, obj).
5. If Type(iterator) is not Object, throw a TypeError exception.
...
GetMethod
2. Let func be ? GetV(V, P).
3. If func is either undefined or null, return undefined.
4. If IsCallable(func) is false, throw a TypeError exception.
Call ( F, V [ , argumentsList ] )
2. If IsCallable(F) is false, throw a TypeError exception.
features: [Promise.any, Symbol, Symbol.iterator, computed-property-names]
flags: [async]
---*/
try {
Promise.any({
[Symbol.iterator]: Symbol()
}).then(function() {
$DONE('The promise should be rejected, but was resolved');
}, function(error) {
assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
assert(error instanceof TypeError);
}).then($DONE, $DONE);
} catch (error) {
$DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
}

View File

@ -0,0 +1,51 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: >
Reject when argument's Symbol.iterator property has the value true
info: |
Promise.any ( iterable )
...
4. Let iteratorRecord be GetIterator(iterable).
5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
...
GetIterator ( obj [ , hint [ , method ] ] )
...
3. If method is not present, then
a. If hint is async, then
...
b. Otherwise, set method to ? GetMethod(obj, @@iterator).
4. Let iterator be ? Call(method, obj).
5. If Type(iterator) is not Object, throw a TypeError exception.
...
GetMethod
2. Let func be ? GetV(V, P).
3. If func is either undefined or null, return undefined.
4. If IsCallable(func) is false, throw a TypeError exception.
Call ( F, V [ , argumentsList ] )
2. If IsCallable(F) is false, throw a TypeError exception.
features: [Promise.any, Symbol.iterator, Symbol, computed-property-names]
flags: [async]
---*/
try {
Promise.any({
[Symbol.iterator]: true
}).then(function() {
$DONE('The promise should be rejected, but was resolved');
}, function(error) {
assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
assert(error instanceof TypeError);
}).then($DONE, $DONE);
} catch (error) {
$DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
}

View File

@ -0,0 +1,51 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: >
Reject when argument's Symbol.iterator property has the value undefined
info: |
Promise.any ( iterable )
...
4. Let iteratorRecord be GetIterator(iterable).
5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
...
GetIterator ( obj [ , hint [ , method ] ] )
...
3. If method is not present, then
a. If hint is async, then
...
b. Otherwise, set method to ? GetMethod(obj, @@iterator).
4. Let iterator be ? Call(method, obj).
5. If Type(iterator) is not Object, throw a TypeError exception.
...
GetMethod
2. Let func be ? GetV(V, P).
3. If func is either undefined or null, return undefined.
4. If IsCallable(func) is false, throw a TypeError exception.
Call ( F, V [ , argumentsList ] )
2. If IsCallable(F) is false, throw a TypeError exception.
features: [Promise.any, Symbol.iterator, Symbol, computed-property-names]
flags: [async]
---*/
try {
Promise.any({
[Symbol.iterator]: undefined
}).then(function() {
$DONE('The promise should be rejected, but was resolved');
}, function(error) {
assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
assert(error instanceof TypeError);
}).then($DONE, $DONE);
} catch (error) {
$DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
}

View File

@ -0,0 +1,60 @@
// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: >
Error when advancing the provided iterable (not closing iterator)
info: |
Promise.any ( iterable )
5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
6. If result is an abrupt completion, then
a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
b. IfAbruptRejectPromise(result, promiseCapability).
Runtime Semantics: PerformPromiseAny
8. Repeat
a. Let next be IteratorStep(iteratorRecord).
b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
c. ReturnIfAbrupt(next).
flags: [async]
features: [Promise.any, Symbol.iterator, computed-property-names, Symbol, arrow-function]
---*/
let returnCount = 0;
let poisonedDone = {};
let error = new Test262Error();
Object.defineProperties(poisonedDone, {
done: {
get() {
throw error;
}
},
value: {
get() {}
}
});
let iterStepThrows = {
[Symbol.iterator]() {
return {
next() {
return poisonedDone;
},
return() {
returnCount += 1;
return {};
}
};
}
};
Promise.any(iterStepThrows).then(
() => {
$DONE('The promise should be rejected.');
}, (reason) => {
assert.sameValue(reason, error);
assert.sameValue(returnCount, 0);
}).then($DONE, $DONE);

View File

@ -0,0 +1,56 @@
// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: >
Error when advancing the provided iterable (rejecting promise)
info: |
Promise.any ( iterable )
5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
6. If result is an abrupt completion, then
a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
b. IfAbruptRejectPromise(result, promiseCapability).
Runtime Semantics: PerformPromiseAny
8. Repeat
a. Let next be IteratorStep(iteratorRecord).
b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
c. ReturnIfAbrupt(next).
flags: [async]
features: [Promise.any, Symbol.iterator, computed-property-names, Symbol, arrow-function]
---*/
let poisonedDone = {};
let error = new Test262Error();
Object.defineProperties(poisonedDone, {
done: {
get() {
throw error;
}
},
value: {
get() {
$DONE('The `value` property should not be accessed.');
}
}
});
let iterStepThrows = {
[Symbol.iterator]() {
return {
next() {
return poisonedDone;
}
};
}
};
Promise.any(iterStepThrows).then(
() => {
$DONE('The promise should be rejected.');
}, (reason) => {
assert.sameValue(reason, error);
}).then($DONE, $DONE);

View File

@ -0,0 +1,28 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: Promise.any `length` property
info: |
ES Section 17:
Every built-in Function object, including constructors, has a length
property whose value is an integer. Unless otherwise specified, this value
is equal to the largest number of named arguments shown in the subclause
headings for the function description, including optional parameters.
[...]
Unless otherwise specified, the length property of a built-in Function
object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
[[Configurable]]: true }.
includes: [propertyHelper.js]
features: [Promise.any]
---*/
verifyProperty(Promise.any, 'length', {
configurable: true,
writable: false,
enumerable: false,
value: 1,
});

View File

@ -0,0 +1,29 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: Promise.any `name` property
info: |
ES Section 17:
Every built-in Function object, including constructors, that is not
identified as an anonymous function has a name property whose value is a
String. Unless otherwise specified, this value is the name that is given to
the function in this specification.
[...]
Unless otherwise specified, the name property of a built-in Function
object, if it exists, has the attributes { [[Writable]]: false,
[[Enumerable]]: false, [[Configurable]]: true }.
includes: [propertyHelper.js]
features: [Promise.any]
---*/
verifyProperty(Promise.any, 'name', {
configurable: true,
writable: false,
enumerable: false,
value: 'any',
});

View File

@ -0,0 +1,51 @@
// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-performpromiseany
description: >
Each Promise.any element is called with a new Promise.any Reject Element function.
info: |
Runtime Semantics: PerformPromiseAny ( iteratorRecord, constructor, resultCapability )
...
k. Let rejectElement be ! CreateBuiltinFunction(steps, « [[AlreadyCalled]], [[Index]], [[Errors]], [[Capability]], [[RemainingElements]] »).
...
r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »).
...
features: [Promise.any]
---*/
function rejectFunction() {}
function Constructor(executor) {
executor(rejectFunction, $ERROR);
}
Constructor.resolve = function(v) {
return v;
};
var callCount1 = 0;
var callCount2 = 0;
var p1OnRejected;
var p1 = {
then(_, onRejected) {
callCount1 += 1;
p1OnRejected = onRejected;
assert.notSameValue(onRejected, rejectFunction, 'p1.then');
}
};
var p2 = {
then(_, onRejected) {
callCount2 += 1;
assert.notSameValue(onRejected, rejectFunction, 'p2.then');
assert.notSameValue(onRejected, p1OnRejected, 'p1.onRejected != p2.onRejected');
}
};
Promise.any.call(Constructor, [p1, p2]);
assert.sameValue(callCount1, 1, 'p1.then call count');
assert.sameValue(callCount2, 1, 'p2.then call count');

View File

@ -0,0 +1,21 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: Promise.any property descriptor
info: |
ES Section 17
Every other data property described in clauses 18 through 26 and in Annex
B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false,
[[Configurable]]: true } unless otherwise specified.
includes: [propertyHelper.js]
features: [Promise.any]
---*/
verifyProperty(Promise, 'any', {
configurable: true,
writable: true,
enumerable: false,
});

View File

@ -0,0 +1,26 @@
// Copyright (C) 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: >
Promise.any rejection reasons from various rejections are all present
flags: [async]
features: [Promise.any, arrow-function]
---*/
let rejections = [
Promise.reject('a'),
new Promise((_, reject) => reject('b')),
Promise.all([Promise.reject('c')]),
Promise.resolve(Promise.reject('d')),
];
Promise.any(rejections)
.then(
() => $DONE('The promise should be rejected, but was resolved'),
error => {
assert.sameValue(error.errors.length, rejections.length);
assert.sameValue(error.errors.join(''), 'abcd');
}
).then($DONE, $DONE);

View File

@ -0,0 +1,31 @@
// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: Rejecting through deferred invocation of the provided resolving function
info: |
...
5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
...
flags: [async]
features: [AggregateError, Promise.any, arrow-function]
---*/
var rejection = {};
var thenable = {
then(_, reject) {
new Promise((resolve) => resolve())
.then(() => reject(rejection));
}
};
Promise.any([thenable])
.then(() => {
$DONE('The promise should be rejected.');
}, (aggregate) => {
assert(aggregate instanceof AggregateError);
assert.sameValue(aggregate.errors.length, 1);
assert.sameValue(aggregate.errors[0], rejection);
}).then($DONE, $DONE);

View File

@ -0,0 +1,29 @@
// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any-reject-element-functions
description: The [[Extensible]] slot of Promise.any Reject Element functions
info: |
17 ECMAScript Standard Built-in Objects:
Unless specified otherwise, the [[Extensible]] internal slot
of a built-in object initially has the value true.
features: [Promise.any]
---*/
var rejectElementFunction;
var thenable = {
then(_, reject) {
rejectElementFunction = reject;
}
};
function NotPromise(executor) {
executor(function() {}, function() {});
}
NotPromise.resolve = function(v) {
return v;
};
Promise.any.call(NotPromise, [thenable]);
assert(Object.isExtensible(rejectElementFunction));

View File

@ -0,0 +1,40 @@
// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any-reject-element-functions
description: The `length` property of Promise.any Reject Element functions
info: |
The length property of a Promise.any Reject Element function is 1.
17 ECMAScript Standard Built-in Objects:
Unless otherwise specified, the length property of a built-in Function
object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
[[Configurable]]: true }.
includes: [propertyHelper.js]
features: [Promise.any]
---*/
var rejectElementFunction;
var thenable = {
then(_, reject) {
rejectElementFunction = reject;
}
};
function NotPromise(executor) {
executor(function() {}, function() {});
}
NotPromise.resolve = function(v) {
return v;
};
Promise.any.call(NotPromise, [thenable]);
assert.sameValue(rejectElementFunction.length, 1);
verifyProperty(rejectElementFunction, 'length', {
value: 1,
enumerable: false,
writable: false,
configurable: true,
});

View File

@ -0,0 +1,39 @@
// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any-reject-element-functions
description: The `name` property of Promise.any Reject Element functions
info: |
A promise resolve function is an anonymous built-in function.
17 ECMAScript Standard Built-in Objects:
Every built-in function object, including constructors, has a `name`
property whose value is a String. Functions that are identified as
anonymous functions use the empty string as the value of the `name`
property.
Unless otherwise specified, the `name` property of a built-in function
object has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*,
[[Configurable]]: *true* }.
includes: [propertyHelper.js]
features: [Promise.any]
---*/
var rejectElementFunction;
var thenable = {
then(_, reject) {
rejectElementFunction = reject;
}
};
function NotPromise(executor) {
executor(function() {}, function() {});
}
NotPromise.resolve = function(v) {
return v;
};
Promise.any.call(NotPromise, [thenable]);
verifyProperty(rejectElementFunction, "name", {
value: "", writable: false, enumerable: false, configurable: true
});

View File

@ -0,0 +1,33 @@
// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any-reject-element-functions
description: Promise.any Reject Element functions are not constructors
info: |
17 ECMAScript Standard Built-in Objects:
Built-in function objects that are not identified as constructors do not
implement the [[Construct]] internal method unless otherwise specified
in the description of a particular function.
features: [Promise.any]
---*/
var rejectElementFunction;
var thenable = {
then(_, reject) {
rejectElementFunction = reject;
}
};
function NotPromise(executor) {
executor(function() {}, function() {});
}
NotPromise.resolve = function(v) {
return v;
};
Promise.any.call(NotPromise, [thenable]);
assert.sameValue(Object.prototype.hasOwnProperty.call(rejectElementFunction, 'prototype'), false);
assert.throws(TypeError, function() {
new rejectElementFunction();
});

View File

@ -0,0 +1,31 @@
// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any-reject-element-functions
description: The [[Prototype]] of Promise.any Reject Element functions
info: |
17 ECMAScript Standard Built-in Objects:
Unless otherwise specified every built-in function and every built-in
constructor has the Function prototype object, which is the initial
value of the expression Function.prototype (19.2.3), as the value of
its [[Prototype]] internal slot.
features: [Promise.any]
---*/
var rejectElementFunction;
var thenable = {
then(_, reject) {
rejectElementFunction = reject;
}
};
function NotPromise(executor) {
executor(function() {}, function() {});
}
NotPromise.resolve = function(v) {
return v;
};
Promise.any.call(NotPromise, [thenable]);
assert.sameValue(Object.getPrototypeOf(rejectElementFunction), Function.prototype);

View File

@ -0,0 +1,22 @@
// Copyright (C) 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: >
Promise.any resolves with the first item that does not reject.
flags: [async]
features: [Promise.any, arrow-function]
---*/
let fulfillables = [
Promise.reject('a'),
new Promise((resolve, reject) => reject('b')),
Promise.all([Promise.reject('c')]),
Promise.reject('d').catch(v => v),
];
Promise.any(fulfillables)
.then((resolution) => {
assert.sameValue(resolution, 'd');
}).then($DONE, $DONE);

View File

@ -0,0 +1,22 @@
// Copyright (C) 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: >
Promise.any resolves with the first item that does not reject.
flags: [async]
features: [Promise.any, arrow-function]
---*/
let fulfillables = [
Promise.reject('a'),
new Promise((resolve, reject) => reject('b')),
Promise.all([Promise.reject('c')]),
Promise.resolve(Promise.reject('d').catch(v => v)),
];
Promise.any(fulfillables)
.then((resolution) => {
assert.sameValue(resolution, 'd');
}).then($DONE, $DONE);

View File

@ -0,0 +1,41 @@
// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Resolved promises ignore rejections through deferred invocation of the
provided resolving function
esid: sec-promise.any
info: |
5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
Runtime Semantics: PerformPromiseAny
8. Repeat
...
r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »).
flags: [async]
features: [Promise.any, arrow-function]
---*/
var resolver = {
then(resolve) {
new Promise((resolve) => resolve())
.then(() => resolve(42));
}
};
var lateRejector = {
then(resolve, reject) {
new Promise((resolve) => resolve())
.then(() => {
resolve(9);
reject();
});
}
};
Promise.any([resolver, lateRejector])
.then(resolution => {
assert.sameValue(resolution, 42);
}).then($DONE, $DONE);

View File

@ -0,0 +1,37 @@
// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Resolved promises ignore rejections through immediate invocation of the
provided resolving function
esid: sec-promise.any
info: |
5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
Runtime Semantics: PerformPromiseAny
8. Repeat
...
r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »).
flags: [async]
features: [Promise.any, arrow-function]
---*/
var resolver = {
then(resolve) {
resolve(42);
}
};
var lateRejector = {
then(resolve, reject) {
resolve(33);
reject();
}
};
Promise.any([resolver, lateRejector])
.then(resolution => {
assert.sameValue(resolution, 42);
}).then($DONE, $DONE);

View File

@ -0,0 +1,24 @@
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-promise.any
description: Promise.any returns a Promise
info: |
Promise.any ( iterable )
2. Let promiseCapability be ? NewPromiseCapability(C).
3. Let iteratorRecord be GetIterator(iterable).
4. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
6. If result is an abrupt completion, then
a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
b. IfAbruptRejectPromise(result, promiseCapability).
7. Return Completion(result).
features: [Promise.any]
---*/
var p = Promise.any([]);
assert(p instanceof Promise);
assert.sameValue(Object.getPrototypeOf(p), Promise.prototype);