mirror of
https://github.com/tc39/test262.git
synced 2025-07-21 21:14:45 +02:00
Promise.any: updates, corrections and new tests.
This commit is contained in:
parent
e0f0c7860b
commit
6edaba378e
@ -12,6 +12,7 @@ info: |
|
|||||||
|
|
||||||
...
|
...
|
||||||
7. Let promise be ? Construct(C, « executor »).
|
7. Let promise be ? Construct(C, « executor »).
|
||||||
|
|
||||||
features: [Promise.any]
|
features: [Promise.any]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
|
@ -12,9 +12,34 @@ info: |
|
|||||||
NewPromiseCapability ( C )
|
NewPromiseCapability ( C )
|
||||||
|
|
||||||
1. If IsConstructor(C) is false, throw a TypeError exception.
|
1. If IsConstructor(C) is false, throw a TypeError exception.
|
||||||
|
|
||||||
features: [Promise.any]
|
features: [Promise.any]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
assert.throws(TypeError, function() {
|
assert.throws(TypeError, function() {
|
||||||
Promise.any.call(eval);
|
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(), []);
|
||||||
|
});
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
// 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-object value
|
|
||||||
esid: sec-promise.any
|
|
||||||
info: |
|
|
||||||
1. Let C be the this value.
|
|
||||||
2. If Type(C) is not Object, throw a TypeError exception.
|
|
||||||
features: [Promise.any, Symbol]
|
|
||||||
---*/
|
|
||||||
|
|
||||||
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(), []);
|
|
||||||
});
|
|
@ -0,0 +1,32 @@
|
|||||||
|
// 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 retrieve `Symbol.species` property of the "`this` value"
|
||||||
|
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 C extends Promise {
|
||||||
|
static get [Symbol.species]() {
|
||||||
|
throw new Test262Error('Getter for Symbol.species called');
|
||||||
|
}
|
||||||
|
static resolve() {
|
||||||
|
throw new Test262Error('C.resolve was reached');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Promise.any.call(C, [1]).then(() => $DONE(), $DONE);
|
@ -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 retrieve `Symbol.species` property of the "`this` value".
|
||||||
|
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]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
Object.defineProperty(Promise, Symbol.species, {
|
||||||
|
get() {
|
||||||
|
throw new Test262Error('Getter for Symbol.species called');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Promise.any([1]).then(() => $DONE(), $DONE);
|
@ -1,20 +0,0 @@
|
|||||||
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
|
|
||||||
// This code is governed by the BSD license found in the LICENSE file.
|
|
||||||
|
|
||||||
/*---
|
|
||||||
description: Promise.any([]) rejects immediately
|
|
||||||
esid: sec-promise.any
|
|
||||||
flags: [async]
|
|
||||||
includes: [promiseHelper.js]
|
|
||||||
features: [AggregateError, Promise.any]
|
|
||||||
---*/
|
|
||||||
|
|
||||||
Promise.any([])
|
|
||||||
.then(
|
|
||||||
() => $DONE('The promise should be rejected, but was resolved'),
|
|
||||||
error => {
|
|
||||||
assert(error instanceof AggregateError);
|
|
||||||
assert.sameValue(error.errors.length, 0);
|
|
||||||
$DONE()
|
|
||||||
}
|
|
||||||
);
|
|
@ -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]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
Promise.resolve = null;
|
||||||
|
|
||||||
|
Promise.any([1])
|
||||||
|
.then(
|
||||||
|
() => $DONE('The promise should not be resolved.'),
|
||||||
|
error => {
|
||||||
|
assert(error instanceof TypeError);
|
||||||
|
}
|
||||||
|
).then($DONE, $DONE);
|
@ -0,0 +1,50 @@
|
|||||||
|
// 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 Custom extends Promise {}
|
||||||
|
|
||||||
|
let customs = [
|
||||||
|
new Custom(resolve => resolve()),
|
||||||
|
new Custom(resolve => resolve()),
|
||||||
|
new Custom(resolve => resolve()),
|
||||||
|
];
|
||||||
|
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, customs)
|
||||||
|
.then(() => {
|
||||||
|
assert.sameValue(presolveCallCount, 0, '`Promise.resolve` is never invoked');
|
||||||
|
assert.sameValue(cresolveCallCount, 3, '`Custom.resolve` invoked once for every iterated promise');
|
||||||
|
}, (error) => {
|
||||||
|
$DONE(error);
|
||||||
|
}
|
||||||
|
).then($DONE, $DONE);
|
||||||
|
|
@ -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 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]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
let promises = [
|
||||||
|
new Promise(resolve => resolve()),
|
||||||
|
new Promise(resolve => resolve()),
|
||||||
|
new Promise(resolve => resolve()),
|
||||||
|
];
|
||||||
|
let callCount = 0;
|
||||||
|
let boundPromiseResolve = Promise.resolve.bind(Promise);
|
||||||
|
|
||||||
|
Promise.resolve = function(...args) {
|
||||||
|
callCount += 1;
|
||||||
|
return boundPromiseResolve(...args);
|
||||||
|
};
|
||||||
|
|
||||||
|
Promise.any(promises)
|
||||||
|
.then(() => {
|
||||||
|
assert.sameValue(callCount, 3, '`then` invoked once for every iterated promise');
|
||||||
|
}, (error) => {
|
||||||
|
$DONE(error);
|
||||||
|
}
|
||||||
|
).then($DONE, $DONE);
|
||||||
|
|
@ -0,0 +1,46 @@
|
|||||||
|
// 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 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');
|
||||||
|
}, (error) => {
|
||||||
|
$DONE(error);
|
||||||
|
}
|
||||||
|
).then($DONE, $DONE);
|
||||||
|
|
@ -0,0 +1,37 @@
|
|||||||
|
// 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]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
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');
|
||||||
|
}, (error) => {
|
||||||
|
$DONE(error);
|
||||||
|
}
|
||||||
|
).then($DONE, $DONE);
|
||||||
|
|
@ -10,46 +10,22 @@ info: |
|
|||||||
|
|
||||||
Runtime Semantics: PerformPromiseAny
|
Runtime Semantics: PerformPromiseAny
|
||||||
|
|
||||||
6. Repeat
|
8. Repeat
|
||||||
...
|
...
|
||||||
i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
|
i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
|
||||||
...
|
...
|
||||||
z. Perform ? Invoke(nextPromise, "then", « resolveElement, rejectElement »).
|
r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »).
|
||||||
|
|
||||||
flags: [async]
|
flags: [async]
|
||||||
features: [Promise.any]
|
features: [Promise.any]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
var p1 = new Promise(function() {});
|
let boundPromiseResolve = Promise.resolve.bind(Promise);
|
||||||
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) {
|
Promise.resolve = function(...args) {
|
||||||
assert.sameValue(
|
assert.sameValue(args.length, 1, '`resolve` invoked with a single argument');
|
||||||
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');
|
assert.sameValue(this, Promise, '`this` value is the constructor');
|
||||||
|
return boundPromiseResolve(...args);
|
||||||
current = next;
|
|
||||||
next = afterNext;
|
|
||||||
afterNext = null;
|
|
||||||
|
|
||||||
callCount += 1;
|
|
||||||
|
|
||||||
return resolve.apply(Promise, arguments);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Promise.any([p1, p2, p3])
|
Promise.any([1]).then(() => $DONE(), $DONE);
|
||||||
.then(function() {
|
|
||||||
assert.sameValue(
|
|
||||||
callCount, 3, '`resolve` invoked once for each iterated value'
|
|
||||||
);
|
|
||||||
$DONE();
|
|
||||||
}, $DONE);
|
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
// 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]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
let promises = [
|
||||||
|
new Promise(resolve => resolve()),
|
||||||
|
new Promise(resolve => resolve()),
|
||||||
|
new Promise(resolve => 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');
|
||||||
|
}, (error) => {
|
||||||
|
$DONE(error);
|
||||||
|
// $DONE('The promise should not be rejected');
|
||||||
|
}
|
||||||
|
).then($DONE, $DONE);
|
@ -19,39 +19,16 @@ flags: [async]
|
|||||||
features: [Promise.any]
|
features: [Promise.any]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
var p1 = new Promise(function() {});
|
let promise = new Promise(() => {});
|
||||||
var p2 = new Promise(function() {});
|
let boundThen = promise.then.bind(promise);
|
||||||
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) {
|
promise.then = function(resolver, rejectElement) {
|
||||||
assert.sameValue(typeof a, 'function', 'type of first argument');
|
assert.sameValue(this, promise);
|
||||||
assert.sameValue(
|
assert.sameValue(typeof resolver, 'function');
|
||||||
a.length,
|
assert.sameValue(resolver.length, 1, 'resolver.length is 1');
|
||||||
1,
|
assert.sameValue(typeof rejectElement, 'function');
|
||||||
'The length property of a promise resolve function is 1.'
|
assert.sameValue(rejectElement.length, 1, 'rejectElement.length is 0');
|
||||||
);
|
return boundThen(resolver, rejectElement);
|
||||||
assert.sameValue(typeof b, 'function', 'type of second argument');
|
|
||||||
assert.sameValue(
|
|
||||||
b.length,
|
|
||||||
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.any([p1, p2, p3])
|
Promise.any([promise]).then(() => $DONE(), $DONE);
|
||||||
.then(function() {
|
|
||||||
assert.sameValue(callCount, 3, '`then` invoked once for every iterated value');
|
|
||||||
$DONE();
|
|
||||||
}, $DONE);
|
|
||||||
|
@ -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]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
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);
|
@ -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]
|
||||||
|
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);
|
@ -4,13 +4,13 @@
|
|||||||
/*---
|
/*---
|
||||||
esid: sec-promise.any
|
esid: sec-promise.any
|
||||||
description: >
|
description: >
|
||||||
Reject when argument is `false`
|
Promise.any(false) rejects with TypeError.
|
||||||
info: |
|
info: |
|
||||||
Promise.any ( iterable )
|
Promise.any ( iterable )
|
||||||
|
|
||||||
...
|
...
|
||||||
4. Let iteratorRecord be GetIterator(iterable).
|
3. Let iteratorRecord be GetIterator(iterable).
|
||||||
5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
|
4. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
|
||||||
...
|
...
|
||||||
|
|
||||||
#sec-getiterator
|
#sec-getiterator
|
||||||
|
@ -4,13 +4,13 @@
|
|||||||
/*---
|
/*---
|
||||||
esid: sec-promise.any
|
esid: sec-promise.any
|
||||||
description: >
|
description: >
|
||||||
Reject when argument is `null`
|
Promise.any(null) rejects with TypeError.
|
||||||
info: |
|
info: |
|
||||||
Promise.any ( iterable )
|
Promise.any ( iterable )
|
||||||
|
|
||||||
...
|
...
|
||||||
4. Let iteratorRecord be GetIterator(iterable).
|
3. Let iteratorRecord be GetIterator(iterable).
|
||||||
5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
|
4. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
|
||||||
...
|
...
|
||||||
|
|
||||||
#sec-getiterator
|
#sec-getiterator
|
||||||
|
@ -4,13 +4,13 @@
|
|||||||
/*---
|
/*---
|
||||||
esid: sec-promise.any
|
esid: sec-promise.any
|
||||||
description: >
|
description: >
|
||||||
Reject when argument is a number
|
Promise.any(number) rejects with TypeError.
|
||||||
info: |
|
info: |
|
||||||
Promise.any ( iterable )
|
Promise.any ( iterable )
|
||||||
|
|
||||||
...
|
...
|
||||||
4. Let iteratorRecord be GetIterator(iterable).
|
3. Let iteratorRecord be GetIterator(iterable).
|
||||||
5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
|
4. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
|
||||||
...
|
...
|
||||||
|
|
||||||
#sec-getiterator
|
#sec-getiterator
|
||||||
|
@ -4,13 +4,13 @@
|
|||||||
/*---
|
/*---
|
||||||
esid: sec-promise.any
|
esid: sec-promise.any
|
||||||
description: >
|
description: >
|
||||||
Reject with abrupt completion from GetIterator
|
Promise.any(poisoned iterable) rejects with whatever error is thrown.
|
||||||
info: |
|
info: |
|
||||||
Promise.any ( iterable )
|
Promise.any ( iterable )
|
||||||
|
|
||||||
...
|
...
|
||||||
4. Let iteratorRecord be GetIterator(iterable).
|
3. Let iteratorRecord be GetIterator(iterable).
|
||||||
5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
|
4. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
|
||||||
...
|
...
|
||||||
|
|
||||||
#sec-getiterator
|
#sec-getiterator
|
||||||
@ -24,18 +24,18 @@ flags: [async]
|
|||||||
---*/
|
---*/
|
||||||
|
|
||||||
var poison = [];
|
var poison = [];
|
||||||
var error = new Test262Error();
|
|
||||||
Object.defineProperty(poison, Symbol.iterator, {
|
Object.defineProperty(poison, Symbol.iterator, {
|
||||||
get() {
|
get() {
|
||||||
throw error;
|
throw new Test262Error();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Promise.any(poison).then(function() {
|
Promise.any(poison).then(() => {
|
||||||
$DONE('The promise should be rejected, but was resolved');
|
$DONE('The promise should be rejected, but was resolved');
|
||||||
}, function(err) {
|
}, (error) => {
|
||||||
assert.sameValue(err, error);
|
assert.sameValue(Object.getPrototypeOf(error), Test262Error.prototype);
|
||||||
|
assert(error instanceof Test262Error);
|
||||||
}).then($DONE, $DONE);
|
}).then($DONE, $DONE);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
$DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
|
$DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
|
||||||
|
@ -4,13 +4,13 @@
|
|||||||
/*---
|
/*---
|
||||||
esid: sec-promise.any
|
esid: sec-promise.any
|
||||||
description: >
|
description: >
|
||||||
Resolve when argument is a string
|
Promise.any('non-empty-string') resolves with the first character in the non-empty string
|
||||||
info: |
|
info: |
|
||||||
Promise.any ( iterable )
|
Promise.any ( iterable )
|
||||||
|
|
||||||
...
|
...
|
||||||
4. Let iteratorRecord be GetIterator(iterable).
|
3. Let iteratorRecord be GetIterator(iterable).
|
||||||
5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
|
4. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
|
||||||
...
|
...
|
||||||
|
|
||||||
#sec-getiterator
|
#sec-getiterator
|
||||||
@ -25,9 +25,10 @@ flags: [async]
|
|||||||
---*/
|
---*/
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Promise.any('').then(function(v) {
|
Promise.any('xyz').then(v => {
|
||||||
assert.sameValue(v.length, 0);
|
assert.sameValue(v, 'x');
|
||||||
}, function(error) {
|
assert.sameValue(v.length, 1);
|
||||||
|
}, error => {
|
||||||
$DONE(`The promise should be resolved, but was rejected with error: ${error.message}`);
|
$DONE(`The promise should be resolved, but was rejected with error: ${error.message}`);
|
||||||
}).then($DONE, $DONE);
|
}).then($DONE, $DONE);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -4,13 +4,13 @@
|
|||||||
/*---
|
/*---
|
||||||
esid: sec-promise.any
|
esid: sec-promise.any
|
||||||
description: >
|
description: >
|
||||||
Reject when argument is a symbol
|
Promise.any(Symbol()) rejects with TypeError.
|
||||||
info: |
|
info: |
|
||||||
Promise.any ( iterable )
|
Promise.any ( iterable )
|
||||||
|
|
||||||
...
|
...
|
||||||
4. Let iteratorRecord be GetIterator(iterable).
|
3. Let iteratorRecord be GetIterator(iterable).
|
||||||
5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
|
4. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
|
||||||
...
|
...
|
||||||
|
|
||||||
GetIterator ( obj [ , hint [ , method ] ] )
|
GetIterator ( obj [ , hint [ , method ] ] )
|
||||||
|
@ -4,13 +4,13 @@
|
|||||||
/*---
|
/*---
|
||||||
esid: sec-promise.any
|
esid: sec-promise.any
|
||||||
description: >
|
description: >
|
||||||
Reject when argument is `true`
|
Promise.any(true) rejects with TypeError.
|
||||||
info: |
|
info: |
|
||||||
Promise.any ( iterable )
|
Promise.any ( iterable )
|
||||||
|
|
||||||
...
|
...
|
||||||
4. Let iteratorRecord be GetIterator(iterable).
|
3. Let iteratorRecord be GetIterator(iterable).
|
||||||
5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
|
4. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
|
||||||
...
|
...
|
||||||
|
|
||||||
GetIterator ( obj [ , hint [ , method ] ] )
|
GetIterator ( obj [ , hint [ , method ] ] )
|
||||||
|
@ -4,13 +4,13 @@
|
|||||||
/*---
|
/*---
|
||||||
esid: sec-promise.any
|
esid: sec-promise.any
|
||||||
description: >
|
description: >
|
||||||
Reject when argument is `undefined`
|
Promise.any(undefined) rejects with TypeError.
|
||||||
info: |
|
info: |
|
||||||
Promise.any ( iterable )
|
Promise.any ( iterable )
|
||||||
|
|
||||||
...
|
...
|
||||||
4. Let iteratorRecord be GetIterator(iterable).
|
3. Let iteratorRecord be GetIterator(iterable).
|
||||||
5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
|
4. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
|
||||||
...
|
...
|
||||||
|
|
||||||
GetIterator ( obj [ , hint [ , method ] ] )
|
GetIterator ( obj [ , hint [ , method ] ] )
|
||||||
|
60
test/built-ins/Promise/any/iter-step-err-no-close.js
Normal file
60
test/built-ins/Promise/any/iter-step-err-no-close.js
Normal 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]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
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);
|
56
test/built-ins/Promise/any/iter-step-err-reject.js
Normal file
56
test/built-ins/Promise/any/iter-step-err-reject.js
Normal 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]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
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);
|
51
test/built-ins/Promise/any/new-reject-function.js
Normal file
51
test/built-ins/Promise/any/new-reject-function.js
Normal 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');
|
||||||
|
|
26
test/built-ins/Promise/any/reject-all-mixed.js
Normal file
26
test/built-ins/Promise/any/reject-all-mixed.js
Normal 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]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
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);
|
31
test/built-ins/Promise/any/reject-deferred.js
Normal file
31
test/built-ins/Promise/any/reject-deferred.js
Normal 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]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
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);
|
@ -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));
|
40
test/built-ins/Promise/any/reject-element-function-length.js
Normal file
40
test/built-ins/Promise/any/reject-element-function-length.js
Normal 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,
|
||||||
|
});
|
39
test/built-ins/Promise/any/reject-element-function-name.js
Normal file
39
test/built-ins/Promise/any/reject-element-function-name.js
Normal 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
|
||||||
|
});
|
@ -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();
|
||||||
|
});
|
@ -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);
|
@ -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]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
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);
|
37
test/built-ins/Promise/any/resolve-ignores-late-rejection.js
Normal file
37
test/built-ins/Promise/any/resolve-ignores-late-rejection.js
Normal 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]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
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);
|
22
test/built-ins/Promise/any/resolve-one-mixed.js
Normal file
22
test/built-ins/Promise/any/resolve-one-mixed.js
Normal 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]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
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);
|
@ -1,29 +0,0 @@
|
|||||||
// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
|
|
||||||
// This code is governed by the BSD license found in the LICENSE file.
|
|
||||||
|
|
||||||
/*---
|
|
||||||
description: >
|
|
||||||
Promise.any() does not retrieve `Symbol.species` property of the `this` value
|
|
||||||
esid: sec-promise.any
|
|
||||||
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: [Promise.any, Symbol.species]
|
|
||||||
---*/
|
|
||||||
|
|
||||||
function C(executor) {
|
|
||||||
executor(function() {}, function() {});
|
|
||||||
}
|
|
||||||
Object.defineProperty(C, Symbol.species, {
|
|
||||||
get() {
|
|
||||||
throw new Test262Error('Getter for Symbol.species called');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
C.resolve = function() {
|
|
||||||
throw new Test262Error();
|
|
||||||
};
|
|
||||||
|
|
||||||
Promise.any.call(C, []);
|
|
Loading…
x
Reference in New Issue
Block a user