mirror of
https://github.com/tc39/test262.git
synced 2025-11-28 17:43:19 +01:00
146 lines
3.8 KiB
JavaScript
146 lines
3.8 KiB
JavaScript
// Copyright (C) 2025 André Bargull. All rights reserved.
|
|
// This code is governed by the BSD license found in the LICENSE file.
|
|
|
|
/*---
|
|
esid: sec-iterator.zipkeyed
|
|
description: >
|
|
Handle abrupt completion from IteratorStepValue in IteratorZip.
|
|
info: |
|
|
Iterator.zipKeyed ( iterables [ , options ] )
|
|
...
|
|
16. Return IteratorZip(iters, mode, padding, finishResults).
|
|
|
|
IteratorZip ( iters, mode, padding, finishResults )
|
|
3. Let closure be a new Abstract Closure with no parameters that captures
|
|
iters, iterCount, openIters, mode, padding, and finishResults, and
|
|
performs the following steps when called:
|
|
...
|
|
b. Repeat,
|
|
...
|
|
iii. For each integer i such that 0 ≤ i < iterCount, in ascending order, do
|
|
...
|
|
3. Else,
|
|
a. Let result be Completion(IteratorStepValue(iter)).
|
|
b. If result is an abrupt completion, then
|
|
i. Remove iter from openIters.
|
|
ii. Return ? IteratorCloseAll(openIters, result).
|
|
...
|
|
d. If result is done, then
|
|
i. Remove iter from openIters.
|
|
...
|
|
|
|
IteratorCloseAll ( iters, completion )
|
|
1. For each element iter of iters, in reverse List order, do
|
|
a. Set completion to Completion(IteratorClose(iter, completion)).
|
|
2. Return ? completion.
|
|
|
|
IteratorClose ( iteratorRecord, completion )
|
|
1. Assert: iteratorRecord.[[Iterator]] is an Object.
|
|
2. Let iterator be iteratorRecord.[[Iterator]].
|
|
3. Let innerResult be Completion(GetMethod(iterator, "return")).
|
|
4. If innerResult is a normal completion, then
|
|
a. Let return be innerResult.[[Value]].
|
|
b. If return is undefined, return ? completion.
|
|
c. Set innerResult to Completion(Call(return, iterator)).
|
|
5. If completion is a throw completion, return ? completion.
|
|
...
|
|
includes: [compareArray.js]
|
|
features: [joint-iteration]
|
|
---*/
|
|
|
|
var modes = [
|
|
"shortest",
|
|
"longest",
|
|
"strict",
|
|
];
|
|
|
|
function ExpectedError() {}
|
|
|
|
var log = [];
|
|
|
|
var first = {
|
|
next() {
|
|
log.push("call first next");
|
|
throw new ExpectedError();
|
|
},
|
|
return() {
|
|
log.push("unexpected call first return");
|
|
}
|
|
};
|
|
|
|
var second = {
|
|
next() {
|
|
log.push("unexpected call second next");
|
|
},
|
|
return() {
|
|
// Called with the correct receiver and no arguments.
|
|
assert.sameValue(this, second);
|
|
assert.sameValue(arguments.length, 0);
|
|
|
|
// NB: Log after above asserts, because failures aren't propagated.
|
|
log.push("call second return");
|
|
|
|
// IteratorClose ignores new exceptions when called with a Throw completion.
|
|
throw new Test262Error();
|
|
}
|
|
};
|
|
|
|
var third = {
|
|
next() {
|
|
log.push("unexpected call third next");
|
|
},
|
|
return() {
|
|
// Called with the correct receiver and no arguments.
|
|
assert.sameValue(this, third);
|
|
assert.sameValue(arguments.length, 0);
|
|
|
|
// NB: Log after above asserts, because failures aren't propagated.
|
|
log.push("call third return");
|
|
|
|
// IteratorClose ignores new exceptions when called with a Throw completion.
|
|
throw new Test262Error();
|
|
}
|
|
};
|
|
|
|
// Empty iterator to ensure |return| is not called for closed iterators.
|
|
var empty = {
|
|
next() {
|
|
log.push("call empty next");
|
|
return {done: true};
|
|
},
|
|
return() {
|
|
log.push("unexpected call empty return");
|
|
}
|
|
};
|
|
|
|
for (var mode of modes) {
|
|
var it = Iterator.zipKeyed({first, second, third}, {mode});
|
|
|
|
assert.throws(ExpectedError, function() {
|
|
it.next();
|
|
});
|
|
|
|
assert.compareArray(log, [
|
|
"call first next",
|
|
"call third return",
|
|
"call second return",
|
|
]);
|
|
|
|
// Clear log.
|
|
log.length = 0;
|
|
}
|
|
|
|
// This case applies only when mode is "longest".
|
|
var it = Iterator.zipKeyed({empty, first, second, third}, {mode: "longest"});
|
|
|
|
assert.throws(ExpectedError, function() {
|
|
it.next();
|
|
});
|
|
|
|
assert.compareArray(log, [
|
|
"call empty next",
|
|
"call first next",
|
|
"call third return",
|
|
"call second return",
|
|
]);
|