1
0
mirror of https://github.com/tc39/test262.git synced 2025-04-08 19:35:28 +02:00

Test closing async-from-sync iterator when resolving result promise abrupt completes. ()

* Test closing async-from-sync iterator when resolving result promise abrupt completes.

These test new steps 6-6.a of AsyncFromSyncIteratorContinuation
as per normative changes of ecma626 PR 2600
https://github.com/tc39/ecma262/pull/2600

* Apply suggestions from code review

Co-authored-by: Kevin Gibbons <bakkot@gmail.com>

* Apply suggestions from code review

Co-authored-by: Nicolò Ribaudo <hello@nicr.dev>

* Refactoring tests to use the Async Helpers.

---------

Co-authored-by: Kevin Gibbons <bakkot@gmail.com>
Co-authored-by: Nicolò Ribaudo <hello@nicr.dev>
This commit is contained in:
Ioanna M Dimitriou H 2024-01-23 22:26:02 +01:00 committed by GitHub
parent 2c58671789
commit 1f380f3750
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 229 additions and 0 deletions

@ -0,0 +1,67 @@
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-%asyncfromsynciteratorprototype%.next
description: next() will reject promise if resolving result promise abrupt completes.
info: |
%AsyncFromSyncIteratorPrototype%.next ( value )
...
3. Let promiseCapability be ! NewPromiseCapability(%Promise%).
4. Let syncIteratorRecord be O.[[SyncIteratorRecord]].
5. If value is present, then
...
6. Else,
a. Let result be IteratorNext(syncIteratorRecord).
7. IfAbruptRejectPromise(result, promiseCapability).
8. Return ! AsyncFromSyncIteratorContinuation(result, promiseCapability, syncIteratorRecord, true).
AsyncFromSyncIteratorContinuation ( result, promiseCapability, syncIteratorRecord, closeOnRejection )
1. Let done be IteratorComplete(result).
2. IfAbruptRejectPromise(done, promiseCapability).
3. Let value be IteratorValue(result).
4. IfAbruptRejectPromise(value, promiseCapability).
5. Let valueWrapper be PromiseResolve(%Promise%, value).
6. If valueWrapper is an abrupt completion, done is false, and closeOnRejection is true, then
a. Set valueWrapper to IteratorClose(syncIteratorRecord, valueWrapper).
7. IfAbruptRejectPromise(valueWrapper, promiseCapability).
...
IfAbruptRejectPromise ( value, capability )
1. Assert: value is a Completion Record.
2. If value is an abrupt completion, then
a. Perform ? Call(capability.[[Reject]], undefined, « value.[[Value]] »).
b. Return capability.[[Promise]].
...
flags: [async]
features: [async-iteration]
includes: [asyncHelpers.js]
---*/
var finallyCount = 0;
function CatchError() {}
var thrownError = new CatchError();
function* gen() {
try {
const p = Promise.resolve('FAIL');
Object.defineProperty(p, 'constructor', {
get() {
throw thrownError;
}
});
yield p;
} finally {
finallyCount += 1;
}
}
async function* iter() {
yield* gen();
}
asyncTest(async function () {
await assert.throwsAsync(CatchError, async () => iter().next(), "Promise should be rejected");
assert.sameValue(finallyCount, 1, 'iterator closed properly');
})

@ -0,0 +1,72 @@
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-%asyncfromsynciteratorprototype%.next
description: next() will reject promise if resolving result promise abrupt completes.
info: |
%AsyncFromSyncIteratorPrototype%.next ( value )
...
3. Let promiseCapability be ! NewPromiseCapability(%Promise%).
4. Let syncIteratorRecord be O.[[SyncIteratorRecord]].
5. If value is present, then
...
6. Else,
a. Let result be IteratorNext(syncIteratorRecord).
7. IfAbruptRejectPromise(result, promiseCapability).
8. Return ! AsyncFromSyncIteratorContinuation(result, promiseCapability, syncIteratorRecord, true).
AsyncFromSyncIteratorContinuation ( result, promiseCapability, syncIteratorRecord, closeOnRejection )
1. Let done be IteratorComplete(result).
2. IfAbruptRejectPromise(done, promiseCapability).
3. Let value be IteratorValue(result).
4. IfAbruptRejectPromise(value, promiseCapability).
5. Let valueWrapper be PromiseResolve(%Promise%, value).
6. If valueWrapper is an abrupt completion, done is false, and closeOnRejection is true, then
a. Set valueWrapper to IteratorClose(syncIteratorRecord, valueWrapper).
7. IfAbruptRejectPromise(valueWrapper, promiseCapability).
...
IfAbruptRejectPromise ( value, capability )
1. Assert: value is a Completion Record.
2. If value is an abrupt completion, then
a. Perform ? Call(capability.[[Reject]], undefined, « value.[[Value]] »).
b. Return capability.[[Promise]].
...
flags: [async]
features: [async-iteration]
includes: [asyncHelpers.js]
---*/
var returnCount = 0;
function CatchError() {}
var thrownError = new CatchError();
const obj = {
[Symbol.iterator]() {
return {
next() {
const p = Promise.resolve('FAIL');
Object.defineProperty(p, 'constructor', {
get() {
throw thrownError;
}
});
return { value: p, done: false };
},
return() {
returnCount += 1;
}
};
}
};
async function* iter() {
yield* obj;
}
asyncTest(async function () {
await assert.throwsAsync(CatchError, async () => iter().next(), "Promise should be rejected");
assert.sameValue(returnCount, 1, 'iterator closed properly');
})

@ -0,0 +1,90 @@
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-%asyncfromsynciteratorprototype%.throw
description: throw() will reject promise if resolving result promise abrupt completes.
info: |
%AsyncFromSyncIteratorPrototype%.throw ( value )
...
3. Let promiseCapability be ! NewPromiseCapability(%Promise%).
4. Let syncIteratorRecord be O.[[SyncIteratorRecord]].
5. Let syncIterator be syncIteratorRecord.[[Iterator]].
6. Let throw be GetMethod(syncIterator, "throw").
7. IfAbruptRejectPromise(throw, promiseCapability).
8. If throw is undefined, then
...
9. If value is present, then
...
10. Else,
a. Let result be Call(throw, syncIterator).
...
13. Return ! AsyncFromSyncIteratorContinuation(result, promiseCapability, syncIteratorRecord, true).
AsyncFromSyncIteratorContinuation ( result, promiseCapability, syncIteratorRecord, closeOnRejection )
1. Let done be IteratorComplete(result).
2. IfAbruptRejectPromise(done, promiseCapability).
3. Let value be IteratorValue(result).
4. IfAbruptRejectPromise(value, promiseCapability).
5. Let valueWrapper be PromiseResolve(%Promise%, value).
6. If valueWrapper is an abrupt completion, done is false, and closeOnRejection is true, then
a. Set valueWrapper to IteratorClose(syncIteratorRecord, valueWrapper).
7. IfAbruptRejectPromise(valueWrapper, promiseCapability).
...
IfAbruptRejectPromise ( value, capability )
1. Assert: value is a Completion Record.
2. If value is an abrupt completion, then
a. Perform ? Call(capability.[[Reject]], undefined, « value.[[Value]] »).
b. Return capability.[[Promise]].
...
flags: [async]
features: [async-iteration]
includes: [asyncHelpers.js]
---*/
var returnCount = 0;
function CatchError() {}
var thrownError = new CatchError();
var uncaughtError = new Error("Don't catch me");
const obj = {
[Symbol.iterator]() {
return {
next() {
return { value: 1, done: false };
},
throw() {
const p = Promise.resolve('FAIL');
Object.defineProperty(p, 'constructor', {
get() {
throw thrownError;
}
});
return { value: p, done: false };
},
return() {
returnCount += 1;
return { value: undefined, done: true };
}
};
}
};
async function* asyncg() {
return yield* obj;
}
let iter = asyncg();
asyncTest(async function () {
await assert.throwsAsync(CatchError, async () => {
await iter.next();
return iter.throw(uncaughtError);
}, "Promise should be rejected");
assert.sameValue(returnCount, 1, 'iterator closed properly');
const result = await iter.next();
assert(result.done, "the iterator is completed");
assert.sameValue(result.value, undefined, "value is undefined");
})