diff --git a/test/built-ins/Iterator/zip/iterator-zip-iteration-strict-checks-remaining-done.js b/test/built-ins/Iterator/zip/iterator-zip-iteration-strict-checks-remaining-done.js new file mode 100644 index 00000000000..485492ddedf --- /dev/null +++ b/test/built-ins/Iterator/zip/iterator-zip-iteration-strict-checks-remaining-done.js @@ -0,0 +1,67 @@ +// Copyright (C) 2026 Test262 Contributors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-iterator.zip +description: > + In strict mode, when all iterators finish at the same step, the result + iterator completes normally and .next() is called on all of them. +info: | + 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, + ... + d. If result is done, then + i. Remove iter from openIters. + ... + iii. Else if mode is "strict", then + i. If i ≠ 0, then + ... + ii. For each integer k such that 1 ≤ k < iterCount, in ascending order, do + i. Let open be Completion(IteratorStep(iters[k])). + ... + v. If open is false, then + i. Remove iters[k] from openIters. + iii. Return undefined. +includes: [compareArray.js] +features: [joint-iteration] +---*/ + +var log = []; + +function makeIter(name, length) { + var count = 0; + return { + next() { + count++; + log.push("call " + name + " next"); + return { done: count > length }; + }, + return() { + log.push("unexpected call " + name + " return"); + } + }; +} + +var it = Iterator.zip([makeIter("a", 2), makeIter("b", 2), makeIter("c", 2)], { mode: "strict" }); + +it.next(); +it.next(); + +log.length = 0; + +var result = it.next(); +assert.sameValue(result.done, true); + +assert.compareArray(log, [ + "call a next", + "call b next", + "call c next", +]); diff --git a/test/built-ins/Iterator/zip/result-arrays-are-fresh.js b/test/built-ins/Iterator/zip/result-arrays-are-fresh.js new file mode 100644 index 00000000000..c6a81bda808 --- /dev/null +++ b/test/built-ins/Iterator/zip/result-arrays-are-fresh.js @@ -0,0 +1,48 @@ +// Copyright (C) 2026 Test262 Contributors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-iterator.zip +description: > + Each call to next() returns a fresh array, not the same object reused. +info: | + 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, + ... + iv. Let results be finishResults(results). + v. Let completion be Completion(Yield(results)). + ... + + Iterator.zip ( iterables [ , options ] ) + ... + 15. Let finishResults be a new Abstract Closure with parameters (results) + that captures nothing and performs the following steps when called: + a. Return CreateArrayFromList(results). + ... +includes: [compareArray.js] +features: [joint-iteration] +---*/ + +var it = Iterator.zip([[1, 2, 3], [4, 5, 6]]); + +var first = it.next(); +assert.sameValue(first.done, false); + +var second = it.next(); +assert.sameValue(second.done, false); + +var third = it.next(); +assert.sameValue(third.done, false); + +assert.notSameValue(first.value, second.value); +assert.notSameValue(second.value, third.value); +assert.notSameValue(first.value, third.value); + +assert.compareArray(first.value, [1, 4]); +assert.compareArray(second.value, [2, 5]); +assert.compareArray(third.value, [3, 6]); diff --git a/test/built-ins/Iterator/zipKeyed/iterator-zip-iteration-strict-checks-remaining-done.js b/test/built-ins/Iterator/zipKeyed/iterator-zip-iteration-strict-checks-remaining-done.js new file mode 100644 index 00000000000..42c028a44c0 --- /dev/null +++ b/test/built-ins/Iterator/zipKeyed/iterator-zip-iteration-strict-checks-remaining-done.js @@ -0,0 +1,71 @@ +// Copyright (C) 2026 Test262 Contributors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-iterator.zipkeyed +description: > + In strict mode, when all iterators finish at the same step, the result + iterator completes normally and .next() is called on all of them. +info: | + 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, + ... + d. If result is done, then + i. Remove iter from openIters. + ... + iii. Else if mode is "strict", then + i. If i ≠ 0, then + ... + ii. For each integer k such that 1 ≤ k < iterCount, in ascending order, do + i. Let open be Completion(IteratorStep(iters[k])). + ... + v. If open is false, then + i. Remove iters[k] from openIters. + iii. Return undefined. +includes: [compareArray.js] +features: [joint-iteration] +---*/ + +var log = []; + +function makeIter(name, length) { + var count = 0; + return { + next() { + count++; + log.push("call " + name + " next"); + return { done: count > length }; + }, + return() { + log.push("unexpected call " + name + " return"); + } + }; +} + +var it = Iterator.zipKeyed({ + a: makeIter("a", 2), + b: makeIter("b", 2), + c: makeIter("c", 2), +}, { mode: "strict" }); + +it.next(); +it.next(); + +log.length = 0; + +var result = it.next(); +assert.sameValue(result.done, true); + +assert.compareArray(log, [ + "call a next", + "call b next", + "call c next", +]); diff --git a/test/built-ins/Iterator/zipKeyed/result-objects-are-fresh.js b/test/built-ins/Iterator/zipKeyed/result-objects-are-fresh.js new file mode 100644 index 00000000000..da586ea48cb --- /dev/null +++ b/test/built-ins/Iterator/zipKeyed/result-objects-are-fresh.js @@ -0,0 +1,53 @@ +// Copyright (C) 2026 Test262 Contributors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-iterator.zipkeyed +description: > + Each call to next() returns a fresh result object, not the same object reused. +info: | + 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, + ... + iv. Let results be finishResults(results). + v. Let completion be Completion(Yield(results)). + ... + + Iterator.zipKeyed ( iterables [ , options ] ) + ... + 15. Let finishResults be a new Abstract Closure with parameters (results) that captures keys + and iterCount and performs the following steps when called: + a. Let obj be OrdinaryObjectCreate(null). + b. For each integer i such that 0 ≤ i < iterCount, in ascending order, do + i. Perform ! CreateDataPropertyOrThrow(obj, keys[i], results[i]). + c. Return obj. + ... +features: [joint-iteration] +---*/ + +var it = Iterator.zipKeyed({ a: [1, 2, 3], b: [4, 5, 6] }); + +var first = it.next(); +assert.sameValue(first.done, false); + +var second = it.next(); +assert.sameValue(second.done, false); + +var third = it.next(); +assert.sameValue(third.done, false); + +assert.notSameValue(first.value, second.value); +assert.notSameValue(second.value, third.value); +assert.notSameValue(first.value, third.value); + +assert.sameValue(first.value.a, 1); +assert.sameValue(first.value.b, 4); +assert.sameValue(second.value.a, 2); +assert.sameValue(second.value.b, 5); +assert.sameValue(third.value.a, 3); +assert.sameValue(third.value.b, 6);