mirror of
https://github.com/tc39/test262.git
synced 2025-07-24 22:45:10 +02:00
parent
729fa02951
commit
9dbaa95aed
@ -0,0 +1,43 @@
|
|||||||
|
// Copyright (C) 2020 Rick Waldron. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
description: >
|
||||||
|
Invocation of the constructor's `resolve` method for iterable with promise values
|
||||||
|
esid: sec-promise.race
|
||||||
|
info: |
|
||||||
|
Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability, promiseResolve).
|
||||||
|
|
||||||
|
PerformPromiseRace
|
||||||
|
|
||||||
|
Repeat
|
||||||
|
...
|
||||||
|
i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
|
||||||
|
|
||||||
|
flags: [async]
|
||||||
|
features: [class, arrow-function]
|
||||||
|
---*/
|
||||||
|
class Custom extends Promise {}
|
||||||
|
|
||||||
|
let values = [1, 1, 1];
|
||||||
|
let cresolveCallCount = 0;
|
||||||
|
let presolveCallCount = 0;
|
||||||
|
let boundCustomResolve = Custom.resolve.bind(Custom);
|
||||||
|
let boundPromiseResolve = Promise.resolve.bind(Promise);
|
||||||
|
|
||||||
|
Custom.resolve = function(...args) {
|
||||||
|
cresolveCallCount += 1;
|
||||||
|
return boundCustomResolve(...args);
|
||||||
|
};
|
||||||
|
|
||||||
|
Promise.resolve = function(...args) {
|
||||||
|
presolveCallCount += 1;
|
||||||
|
return boundPromiseResolve(...args);
|
||||||
|
};
|
||||||
|
|
||||||
|
Promise.race.call(Custom, values)
|
||||||
|
.then(() => {
|
||||||
|
assert.sameValue(presolveCallCount, 0, '`Promise.resolve` is never invoked');
|
||||||
|
assert.sameValue(cresolveCallCount, 3, '`Custom.resolve` invoked once for every item in iterable arg');
|
||||||
|
}, $DONE).then($DONE, $DONE);
|
||||||
|
|
@ -0,0 +1,34 @@
|
|||||||
|
// Copyright (C) 2020 Rick Waldron. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
description: >
|
||||||
|
Invocation of the constructor's `resolve` method for iterable with promise values
|
||||||
|
esid: sec-promise.race
|
||||||
|
info: |
|
||||||
|
Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability, promiseResolve).
|
||||||
|
|
||||||
|
PerformPromiseRace
|
||||||
|
|
||||||
|
Repeat
|
||||||
|
...
|
||||||
|
i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
|
||||||
|
|
||||||
|
flags: [async]
|
||||||
|
features: [arrow-function]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
let values = [1, 1, 1];
|
||||||
|
let callCount = 0;
|
||||||
|
let boundPromiseResolve = Promise.resolve.bind(Promise);
|
||||||
|
|
||||||
|
Promise.resolve = function(...args) {
|
||||||
|
callCount += 1;
|
||||||
|
return boundPromiseResolve(...args);
|
||||||
|
};
|
||||||
|
|
||||||
|
Promise.race(values)
|
||||||
|
.then(() => {
|
||||||
|
assert.sameValue(callCount, 3, '`then` invoked once for every item in iterable arg');
|
||||||
|
}, $DONE).then($DONE, $DONE);
|
||||||
|
|
@ -0,0 +1,34 @@
|
|||||||
|
// Copyright (C) 2020 Rick Waldron. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
description: >
|
||||||
|
Invocation of the constructor's `resolve` method for iterable with non-promise values
|
||||||
|
esid: sec-promise.race
|
||||||
|
info: |
|
||||||
|
Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability, promiseResolve).
|
||||||
|
|
||||||
|
PerformPromiseRace
|
||||||
|
|
||||||
|
Repeat
|
||||||
|
...
|
||||||
|
i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
|
||||||
|
|
||||||
|
flags: [async]
|
||||||
|
features: [arrow-function]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
let values = [1, 2, 3];
|
||||||
|
let callCount = 0;
|
||||||
|
let boundPromiseResolve = Promise.resolve.bind(Promise);
|
||||||
|
|
||||||
|
Promise.resolve = function(...args) {
|
||||||
|
callCount += 1;
|
||||||
|
return boundPromiseResolve(...args);
|
||||||
|
};
|
||||||
|
|
||||||
|
Promise.race(values)
|
||||||
|
.then(() => {
|
||||||
|
assert.sameValue(callCount, 3, '`Promise.resolve` invoked once for every item in iterable arg');
|
||||||
|
}, $DONE).then($DONE, $DONE);
|
||||||
|
|
62
test/built-ins/Promise/race/reject-from-same-thenable.js
Normal file
62
test/built-ins/Promise/race/reject-from-same-thenable.js
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
// Copyright (C) 2020 Rick Waldron. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-performpromiserace
|
||||||
|
description: >
|
||||||
|
Promise.race does not prevent resolve from being called multiple times.
|
||||||
|
info: |
|
||||||
|
PerformPromiseRace
|
||||||
|
|
||||||
|
Repeat,
|
||||||
|
Let next be IteratorStep(iteratorRecord).
|
||||||
|
If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
|
||||||
|
ReturnIfAbrupt(next).
|
||||||
|
If next is false, then
|
||||||
|
Set iteratorRecord.[[Done]] to true.
|
||||||
|
Return resultCapability.[[Promise]].
|
||||||
|
Let nextValue be IteratorValue(next).
|
||||||
|
If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
|
||||||
|
ReturnIfAbrupt(nextValue).
|
||||||
|
Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
|
||||||
|
Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], resultCapability.[[Reject]] »).
|
||||||
|
|
||||||
|
includes: [promiseHelper.js]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
let callCount = 0;
|
||||||
|
let values = [];
|
||||||
|
|
||||||
|
function Constructor(executor) {
|
||||||
|
function reject(value) {
|
||||||
|
callCount += 1;
|
||||||
|
values.push(value);
|
||||||
|
}
|
||||||
|
executor(() => {
|
||||||
|
throw new Test262Error();
|
||||||
|
}, reject);
|
||||||
|
}
|
||||||
|
Constructor.resolve = function(v) {
|
||||||
|
return v;
|
||||||
|
};
|
||||||
|
|
||||||
|
let pReject;
|
||||||
|
|
||||||
|
let a = {
|
||||||
|
then(_, rejecter) {
|
||||||
|
pReject = rejecter;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.sameValue(callCount, 0, 'callCount before call to race()');
|
||||||
|
|
||||||
|
Promise.race.call(Constructor, [a]);
|
||||||
|
|
||||||
|
assert.sameValue(callCount, 0, 'callCount after call to race()');
|
||||||
|
|
||||||
|
pReject(1);
|
||||||
|
pReject(2);
|
||||||
|
pReject(3);
|
||||||
|
|
||||||
|
assert.sameValue(callCount, 3, 'callCount after resolving a');
|
||||||
|
checkSequence(values);
|
@ -0,0 +1,28 @@
|
|||||||
|
// Copyright (C) 2020 Rick Waldron. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-promise.race-resolve-element-functions
|
||||||
|
description: The [[Extensible]] slot of Promise.race Resolve Element functions
|
||||||
|
info: |
|
||||||
|
17 ECMAScript Standard Built-in Objects:
|
||||||
|
Unless specified otherwise, the [[Extensible]] internal slot
|
||||||
|
of a built-in object initially has the value true.
|
||||||
|
---*/
|
||||||
|
|
||||||
|
let resolveElementFunction;
|
||||||
|
let thenable = {
|
||||||
|
then(fulfill) {
|
||||||
|
resolveElementFunction = fulfill;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function NotPromise(executor) {
|
||||||
|
executor(() => {}, () => {});
|
||||||
|
}
|
||||||
|
NotPromise.resolve = function(v) {
|
||||||
|
return v;
|
||||||
|
};
|
||||||
|
Promise.race.call(NotPromise, [thenable]);
|
||||||
|
|
||||||
|
assert(Object.isExtensible(resolveElementFunction));
|
38
test/built-ins/Promise/race/resolve-element-function-name.js
Normal file
38
test/built-ins/Promise/race/resolve-element-function-name.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Copyright (C) 2020 Rick Waldron. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-promise.race-resolve-element-functions
|
||||||
|
description: The `name` property of Promise.race Resolve Element functions
|
||||||
|
info: |
|
||||||
|
A promise resolve function is an anonymous built-in function.
|
||||||
|
|
||||||
|
17 ECMAScript Standard Built-in Objects:
|
||||||
|
Every built-in function object, including constructors, has a `name`
|
||||||
|
property whose value is a String. Functions that are identified as
|
||||||
|
anonymous functions use the empty string as the value of the `name`
|
||||||
|
property.
|
||||||
|
Unless otherwise specified, the `name` property of a built-in function
|
||||||
|
object has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*,
|
||||||
|
[[Configurable]]: *true* }.
|
||||||
|
includes: [propertyHelper.js]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
let resolveElementFunction;
|
||||||
|
let thenable = {
|
||||||
|
then(fulfill) {
|
||||||
|
resolveElementFunction = fulfill;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function NotPromise(executor) {
|
||||||
|
executor(() => {}, () => {});
|
||||||
|
}
|
||||||
|
NotPromise.resolve = function(v) {
|
||||||
|
return v;
|
||||||
|
};
|
||||||
|
Promise.race.call(NotPromise, [thenable]);
|
||||||
|
|
||||||
|
verifyProperty(resolveElementFunction, "name", {
|
||||||
|
value: "", writable: false, enumerable: false, configurable: true
|
||||||
|
});
|
@ -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.race-resolve-element-functions
|
||||||
|
description: Promise.race Resolve Element functions are not constructors
|
||||||
|
info: |
|
||||||
|
17 ECMAScript Standard Built-in Objects:
|
||||||
|
Built-in function objects that are not identified as constructors do not
|
||||||
|
implement the [[Construct]] internal method unless otherwise specified
|
||||||
|
in the description of a particular function.
|
||||||
|
---*/
|
||||||
|
|
||||||
|
let resolveElementFunction;
|
||||||
|
let thenable = {
|
||||||
|
then(fulfill) {
|
||||||
|
resolveElementFunction = fulfill;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function NotPromise(executor) {
|
||||||
|
executor(() => {}, () => {});
|
||||||
|
}
|
||||||
|
NotPromise.resolve = function(v) {
|
||||||
|
return v;
|
||||||
|
};
|
||||||
|
Promise.race.call(NotPromise, [thenable]);
|
||||||
|
|
||||||
|
assert.sameValue(Object.prototype.hasOwnProperty.call(resolveElementFunction, 'prototype'), false);
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
new resolveElementFunction();
|
||||||
|
});
|
@ -0,0 +1,30 @@
|
|||||||
|
// Copyright (C) 2020 Rick Waldron. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-promise.race-resolve-element-functions
|
||||||
|
description: The [[Prototype]] of Promise.race Resolve Element functions
|
||||||
|
info: |
|
||||||
|
17 ECMAScript Standard Built-in Objects:
|
||||||
|
Unless otherwise specified every built-in function and every built-in
|
||||||
|
constructor has the Function prototype object, which is the initial
|
||||||
|
value of the expression Function.prototype (19.2.3), as the value of
|
||||||
|
its [[Prototype]] internal slot.
|
||||||
|
---*/
|
||||||
|
|
||||||
|
let resolveElementFunction;
|
||||||
|
let thenable = {
|
||||||
|
then(fulfill) {
|
||||||
|
resolveElementFunction = fulfill;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function NotPromise(executor) {
|
||||||
|
executor(() => {}, () => {});
|
||||||
|
}
|
||||||
|
NotPromise.resolve = function(v) {
|
||||||
|
return v;
|
||||||
|
};
|
||||||
|
Promise.race.call(NotPromise, [thenable]);
|
||||||
|
|
||||||
|
assert.sameValue(Object.getPrototypeOf(resolveElementFunction), Function.prototype);
|
59
test/built-ins/Promise/race/resolve-from-same-thenable.js
Normal file
59
test/built-ins/Promise/race/resolve-from-same-thenable.js
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
// Copyright (C) 2020 Rick Waldron. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-performpromiserace
|
||||||
|
description: >
|
||||||
|
Promise.race does not prevent resolve from being called multiple times.
|
||||||
|
info: |
|
||||||
|
PerformPromiseRace
|
||||||
|
|
||||||
|
Repeat,
|
||||||
|
Let next be IteratorStep(iteratorRecord).
|
||||||
|
If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
|
||||||
|
ReturnIfAbrupt(next).
|
||||||
|
If next is false, then
|
||||||
|
Set iteratorRecord.[[Done]] to true.
|
||||||
|
Return resultCapability.[[Promise]].
|
||||||
|
Let nextValue be IteratorValue(next).
|
||||||
|
If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
|
||||||
|
ReturnIfAbrupt(nextValue).
|
||||||
|
Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
|
||||||
|
Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], resultCapability.[[Reject]] »).
|
||||||
|
|
||||||
|
includes: [promiseHelper.js]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
let callCount = 0;
|
||||||
|
let values = [];
|
||||||
|
|
||||||
|
function Constructor(executor) {
|
||||||
|
function resolve(value) {
|
||||||
|
callCount += 1;
|
||||||
|
values.push(value);
|
||||||
|
}
|
||||||
|
executor(resolve, $ERROR);
|
||||||
|
}
|
||||||
|
Constructor.resolve = function(v) {
|
||||||
|
return v;
|
||||||
|
};
|
||||||
|
|
||||||
|
let pResolve;
|
||||||
|
let a = {
|
||||||
|
then(resolver, rejector) {
|
||||||
|
pResolve = resolver;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.sameValue(callCount, 0, 'callCount before call to race()');
|
||||||
|
|
||||||
|
Promise.race.call(Constructor, [a]);
|
||||||
|
|
||||||
|
assert.sameValue(callCount, 0, 'callCount after call to race()');
|
||||||
|
|
||||||
|
pResolve(1);
|
||||||
|
pResolve(2);
|
||||||
|
pResolve(3);
|
||||||
|
|
||||||
|
assert.sameValue(callCount, 3, 'callCount after resolving a');
|
||||||
|
checkSequence(values);
|
@ -0,0 +1,46 @@
|
|||||||
|
// Copyright (C) 2020 Rick Waldron, 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.race
|
||||||
|
info: |
|
||||||
|
Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability, promiseResolve).
|
||||||
|
|
||||||
|
PerformPromiseRace
|
||||||
|
|
||||||
|
Repeat
|
||||||
|
...
|
||||||
|
Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], resultCapability.[[Reject]] »).
|
||||||
|
|
||||||
|
flags: [async]
|
||||||
|
features: [arrow-function]
|
||||||
|
includes: [promiseHelper.js]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
let sequence = [1];
|
||||||
|
let lateRejector = {
|
||||||
|
then(resolve, reject) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
sequence.push(3);
|
||||||
|
resolve();
|
||||||
|
sequence.push(4);
|
||||||
|
}).then(() => {
|
||||||
|
sequence.push(5);
|
||||||
|
resolve(9);
|
||||||
|
sequence.push(6);
|
||||||
|
reject();
|
||||||
|
sequence.push(7);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
sequence.push(2);
|
||||||
|
|
||||||
|
Promise.race([lateRejector])
|
||||||
|
.then(resolution => {
|
||||||
|
assert.sameValue(resolution, 9);
|
||||||
|
assert.sameValue(sequence.length, 7);
|
||||||
|
checkSequence(sequence);
|
||||||
|
}).then($DONE, $DONE);
|
@ -0,0 +1,37 @@
|
|||||||
|
// Copyright (C) 2020 Rick Waldron, 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.race
|
||||||
|
info: |
|
||||||
|
Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability, promiseResolve).
|
||||||
|
|
||||||
|
PerformPromiseRace
|
||||||
|
|
||||||
|
Repeat
|
||||||
|
...
|
||||||
|
Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], resultCapability.[[Reject]] »).
|
||||||
|
|
||||||
|
flags: [async]
|
||||||
|
features: [arrow-function]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
let resolver = {
|
||||||
|
then(resolve) {
|
||||||
|
resolve(42);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let lateRejector = {
|
||||||
|
then(resolve, reject) {
|
||||||
|
resolve(33);
|
||||||
|
reject();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Promise.race([resolver, lateRejector])
|
||||||
|
.then(resolution => {
|
||||||
|
assert.sameValue(resolution, 42);
|
||||||
|
}).then($DONE, $DONE);
|
42
test/built-ins/Promise/race/resolved-sequence-extra-ticks.js
Normal file
42
test/built-ins/Promise/race/resolved-sequence-extra-ticks.js
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// Copyright (C) 2020 Rick Waldron. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-promise.race
|
||||||
|
description: Resolution ticks are set in a predictable sequence with extra then calls
|
||||||
|
info: |
|
||||||
|
PerformPromiseRace
|
||||||
|
|
||||||
|
Repeat,
|
||||||
|
Let next be IteratorStep(iteratorRecord).
|
||||||
|
If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
|
||||||
|
ReturnIfAbrupt(next).
|
||||||
|
If next is false, then
|
||||||
|
Set iteratorRecord.[[Done]] to true.
|
||||||
|
Return resultCapability.[[Promise]].
|
||||||
|
Let nextValue be IteratorValue(next).
|
||||||
|
If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
|
||||||
|
ReturnIfAbrupt(nextValue).
|
||||||
|
Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
|
||||||
|
Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], resultCapability.[[Reject]] »).
|
||||||
|
|
||||||
|
flags: [async]
|
||||||
|
includes: [promiseHelper.js]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
let a = new Promise(resolve => resolve({}));
|
||||||
|
let sequence = [1];
|
||||||
|
Promise.all([
|
||||||
|
Promise.race([a]).then(resolved => {
|
||||||
|
sequence.push(4);
|
||||||
|
}),
|
||||||
|
a.then(() => {
|
||||||
|
sequence.push(3);
|
||||||
|
}).then(() => {
|
||||||
|
sequence.push(5);
|
||||||
|
}),
|
||||||
|
]).then(() => {
|
||||||
|
assert.sameValue(sequence.length, 5);
|
||||||
|
checkSequence(sequence);
|
||||||
|
}).then($DONE, $DONE);
|
||||||
|
sequence.push(2);
|
48
test/built-ins/Promise/race/resolved-sequence-mixed.js
Normal file
48
test/built-ins/Promise/race/resolved-sequence-mixed.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// Copyright (C) 2020 Rick Waldron. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-promise.race
|
||||||
|
description: >
|
||||||
|
Resolution ticks are set in a predictable sequence of mixed fulfilled and rejected promises
|
||||||
|
info: |
|
||||||
|
PerformPromiseRace
|
||||||
|
|
||||||
|
Repeat,
|
||||||
|
Let next be IteratorStep(iteratorRecord).
|
||||||
|
If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
|
||||||
|
ReturnIfAbrupt(next).
|
||||||
|
If next is false, then
|
||||||
|
Set iteratorRecord.[[Done]] to true.
|
||||||
|
Return resultCapability.[[Promise]].
|
||||||
|
Let nextValue be IteratorValue(next).
|
||||||
|
If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
|
||||||
|
ReturnIfAbrupt(nextValue).
|
||||||
|
Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
|
||||||
|
Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], resultCapability.[[Reject]] »).
|
||||||
|
|
||||||
|
flags: [async]
|
||||||
|
includes: [promiseHelper.js]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
let a = Promise.reject('');
|
||||||
|
let b = new Promise(resolve => resolve(''));
|
||||||
|
let c = new Promise((_, reject) => reject(''));
|
||||||
|
let sequence = [1];
|
||||||
|
Promise.all([
|
||||||
|
a.catch(() => {
|
||||||
|
sequence.push(3);
|
||||||
|
}),
|
||||||
|
Promise.race([a, b, c]).then(() => {
|
||||||
|
// This should not be present when the final
|
||||||
|
// sequence is evaluated.
|
||||||
|
sequence.push(5);
|
||||||
|
}),
|
||||||
|
b.then(() => {
|
||||||
|
sequence.push(4);
|
||||||
|
}),
|
||||||
|
]).catch(() => {
|
||||||
|
assert.sameValue(sequence.length, 4);
|
||||||
|
checkSequence(sequence);
|
||||||
|
}).then($DONE, $DONE);
|
||||||
|
sequence.push(2);
|
@ -0,0 +1,47 @@
|
|||||||
|
// Copyright (C) 2020 Rick Waldron. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-promise.race
|
||||||
|
description: Resolution ticks are set in a predictable sequence
|
||||||
|
info: |
|
||||||
|
PerformPromiseRace
|
||||||
|
|
||||||
|
Repeat,
|
||||||
|
Let next be IteratorStep(iteratorRecord).
|
||||||
|
If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
|
||||||
|
ReturnIfAbrupt(next).
|
||||||
|
If next is false, then
|
||||||
|
Set iteratorRecord.[[Done]] to true.
|
||||||
|
Return resultCapability.[[Promise]].
|
||||||
|
Let nextValue be IteratorValue(next).
|
||||||
|
If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
|
||||||
|
ReturnIfAbrupt(nextValue).
|
||||||
|
Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
|
||||||
|
Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], resultCapability.[[Reject]] »).
|
||||||
|
|
||||||
|
flags: [async]
|
||||||
|
includes: [compareArray.js,promiseHelper.js]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
let a = new Promise((_, reject) => reject('a'));
|
||||||
|
let b = new Promise((_, reject) => reject('b'));
|
||||||
|
let sequence = [1];
|
||||||
|
Promise.all([
|
||||||
|
a.catch(() => {
|
||||||
|
sequence.push(3);
|
||||||
|
return checkSequence(sequence, 'Expected to be called first.');
|
||||||
|
}),
|
||||||
|
Promise.race([a, b]).catch(() => {
|
||||||
|
sequence.push(5);
|
||||||
|
return checkSequence(sequence, 'Expected to be called third.');
|
||||||
|
}),
|
||||||
|
b.catch(() => {
|
||||||
|
sequence.push(4);
|
||||||
|
return checkSequence(sequence, 'Expected to be called second.');
|
||||||
|
})
|
||||||
|
]).then(result => {
|
||||||
|
compareArray(result, [true, true, true]);
|
||||||
|
}).then($DONE, $DONE);
|
||||||
|
|
||||||
|
sequence.push(2);
|
46
test/built-ins/Promise/race/resolved-sequence.js
Normal file
46
test/built-ins/Promise/race/resolved-sequence.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// Copyright (C) 2020 Rick Waldron. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-promise.race
|
||||||
|
description: Resolution ticks are set in a predictable sequence
|
||||||
|
info: |
|
||||||
|
PerformPromiseRace
|
||||||
|
|
||||||
|
Repeat,
|
||||||
|
Let next be IteratorStep(iteratorRecord).
|
||||||
|
If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
|
||||||
|
ReturnIfAbrupt(next).
|
||||||
|
If next is false, then
|
||||||
|
Set iteratorRecord.[[Done]] to true.
|
||||||
|
Return resultCapability.[[Promise]].
|
||||||
|
Let nextValue be IteratorValue(next).
|
||||||
|
If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
|
||||||
|
ReturnIfAbrupt(nextValue).
|
||||||
|
Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
|
||||||
|
Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], resultCapability.[[Reject]] »).
|
||||||
|
|
||||||
|
flags: [async]
|
||||||
|
includes: [compareArray.js,promiseHelper.js]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
let a = new Promise(resolve => resolve('a'));
|
||||||
|
let b = new Promise(resolve => resolve('b'));
|
||||||
|
let sequence = [1];
|
||||||
|
Promise.all([
|
||||||
|
a.then(() => {
|
||||||
|
sequence.push(3);
|
||||||
|
return checkSequence(sequence, 'Expected to be called first.');
|
||||||
|
}),
|
||||||
|
Promise.race([a, b]).then(() => {
|
||||||
|
sequence.push(5);
|
||||||
|
return checkSequence(sequence, 'Expected to be called third.');
|
||||||
|
}),
|
||||||
|
b.then(() => {
|
||||||
|
sequence.push(4);
|
||||||
|
return checkSequence(sequence, 'Expected to be called second.');
|
||||||
|
})
|
||||||
|
]).then(result => {
|
||||||
|
compareArray(result, [true, true, true]);
|
||||||
|
}).then($DONE, $DONE);
|
||||||
|
sequence.push(2);
|
39
test/built-ins/Promise/race/resolved-then-catch-finally.js
Normal file
39
test/built-ins/Promise/race/resolved-then-catch-finally.js
Normal 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.race
|
||||||
|
description: >
|
||||||
|
Resolution the first resolved promise
|
||||||
|
info: |
|
||||||
|
PerformPromiseRace
|
||||||
|
|
||||||
|
Repeat,
|
||||||
|
Let next be IteratorStep(iteratorRecord).
|
||||||
|
If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
|
||||||
|
ReturnIfAbrupt(next).
|
||||||
|
If next is false, then
|
||||||
|
Set iteratorRecord.[[Done]] to true.
|
||||||
|
Return resultCapability.[[Promise]].
|
||||||
|
Let nextValue be IteratorValue(next).
|
||||||
|
If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
|
||||||
|
ReturnIfAbrupt(nextValue).
|
||||||
|
Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
|
||||||
|
Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], resultCapability.[[Reject]] »).
|
||||||
|
|
||||||
|
flags: [async]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
let a = Promise.reject('a').catch((v) => v);
|
||||||
|
let b = Promise.resolve('b').then((v) => { throw v });
|
||||||
|
let c = Promise.reject('c').then((v) => { throw v; });
|
||||||
|
let d = Promise.resolve('d').finally((v) => v);
|
||||||
|
let e = Promise.reject('e').finally((v) => v);
|
||||||
|
let f = Promise.resolve('f').finally((v) => { throw v; });
|
||||||
|
let g = Promise.reject('g').finally((v) => { throw v; });
|
||||||
|
let h = Promise.reject('h').then((v) => v, () => 'j');
|
||||||
|
let i = Promise.resolve('i').then(v => v);
|
||||||
|
|
||||||
|
Promise.race([a, b, c, d, e, f, g, h, i]).then(winner => {
|
||||||
|
assert.sameValue(winner, 'a');
|
||||||
|
}).then($DONE, $DONE);
|
Loading…
x
Reference in New Issue
Block a user