mirror of
https://github.com/tc39/test262.git
synced 2025-11-29 18:13:13 +01:00
split basic.js into harness+tests, add some more tests
This commit is contained in:
parent
004b7337af
commit
e0738ee1ca
223
harness/iteratorZipUtils.js
Normal file
223
harness/iteratorZipUtils.js
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
// Copyright (C) 2025 André Bargull. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
/*---
|
||||||
|
description: |
|
||||||
|
Utility functions for testing Iterator.prototype.zip and Iterator.prototype.zipKeyed. Requires inclusion of propertyHelper.js.
|
||||||
|
defines:
|
||||||
|
- forEachSequenceCombination
|
||||||
|
- forEachSequenceCombinationKeyed
|
||||||
|
- assertZipped
|
||||||
|
- assertZippedKeyed
|
||||||
|
- assertIteratorResult
|
||||||
|
- assertIsPackedArray
|
||||||
|
---*/
|
||||||
|
|
||||||
|
// Assert |result| is an object created by CreateIteratorResultObject.
|
||||||
|
function assertIteratorResult(result, value, done, label) {
|
||||||
|
assert.sameValue(
|
||||||
|
Object.getPrototypeOf(result),
|
||||||
|
Object.prototype,
|
||||||
|
label + ": [[Prototype]] of iterator result is Object.prototype"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(Object.isExtensible(result), label + ": iterator result is extensible");
|
||||||
|
|
||||||
|
var ownKeys = Reflect.ownKeys(result);
|
||||||
|
assert.compareArray(ownKeys, ["value", "done"], label + ": iterator result properties");
|
||||||
|
|
||||||
|
verifyProperty(result, "value", {
|
||||||
|
value: value,
|
||||||
|
writable: true,
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
verifyProperty(result, "done", {
|
||||||
|
value: done,
|
||||||
|
writable: true,
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assert |array| is a packed array with default property attributes.
|
||||||
|
function assertIsPackedArray(array, label) {
|
||||||
|
assert(Array.isArray(array), label + ": array is an array exotic object");
|
||||||
|
|
||||||
|
assert.sameValue(
|
||||||
|
Object.getPrototypeOf(array),
|
||||||
|
Array.prototype,
|
||||||
|
label + ": [[Prototype]] of array is Array.prototype"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(Object.isExtensible(array), label + ": array is extensible");
|
||||||
|
|
||||||
|
// Ensure "length" property has its default property attributes.
|
||||||
|
verifyProperty(array, "length", {
|
||||||
|
writable: true,
|
||||||
|
enumerable: false,
|
||||||
|
configurable: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Ensure no holes and all elements have the default property attributes.
|
||||||
|
for (var i = 0; i < array.length; i++) {
|
||||||
|
verifyProperty(array, i, {
|
||||||
|
writable: true,
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assert |array| is an extensible null-prototype object with default property attributes.
|
||||||
|
function _assertIsNullProtoMutableObject(object, label) {
|
||||||
|
assert.sameValue(
|
||||||
|
Object.getPrototypeOf(object),
|
||||||
|
null,
|
||||||
|
label + ": [[Prototype]] of object is null"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(Object.isExtensible(object), label + ": object is extensible");
|
||||||
|
|
||||||
|
// Ensure all properties have the default property attributes.
|
||||||
|
var keys = Object.getOwnPropertyNames(object);
|
||||||
|
for (var i = 0; i < keys.length; i++) {
|
||||||
|
verifyProperty(object, keys[i], {
|
||||||
|
writable: true,
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assert that the `zipped` iterator results as for Iterator.zip for the first `count` elements.
|
||||||
|
// Assumes inputs is an array of arrays of length >= count.
|
||||||
|
// Advances `zipped` by `count` steps.
|
||||||
|
function assertZipped(zipped, inputs, count, label) {
|
||||||
|
// Last returned elements array.
|
||||||
|
var last = null;
|
||||||
|
|
||||||
|
for (var i = 0; i < count; i++) {
|
||||||
|
var itemLabel = label + ", step " + i;
|
||||||
|
|
||||||
|
var result = zipped.next();
|
||||||
|
var value = result.value;
|
||||||
|
|
||||||
|
// Test IteratorResult structure.
|
||||||
|
assertIteratorResult(result, value, false, itemLabel);
|
||||||
|
|
||||||
|
// Ensure value is a new array.
|
||||||
|
assert.notSameValue(value, last, itemLabel + ": returns a new array");
|
||||||
|
last = value;
|
||||||
|
|
||||||
|
// Ensure all array elements have the expected value.
|
||||||
|
var expected = inputs.map(function (array) {
|
||||||
|
return array[i];
|
||||||
|
});
|
||||||
|
assert.compareArray(value, expected, itemLabel + ": values");
|
||||||
|
|
||||||
|
// Ensure value is a packed array with default data properties.
|
||||||
|
//
|
||||||
|
// This operation is destructive, so it has to happen last.
|
||||||
|
assertIsPackedArray(value, itemLabel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assert that the `zipped` iterator results as for Iterator.zipKeyed for the first `count` elements.
|
||||||
|
// Assumes inputs is an object whose values are arrays of length >= count.
|
||||||
|
// Advances `zipped` by `count` steps.
|
||||||
|
function assertZippedKeyed(zipped, inputs, count, label) {
|
||||||
|
// Last returned elements array.
|
||||||
|
var last = null;
|
||||||
|
|
||||||
|
var expectedKeys = Object.keys(inputs);
|
||||||
|
|
||||||
|
for (var i = 0; i < count; i++) {
|
||||||
|
var itemLabel = label + ", step " + i;
|
||||||
|
|
||||||
|
var result = zipped.next();
|
||||||
|
var value = result.value;
|
||||||
|
|
||||||
|
// Test IteratorResult structure.
|
||||||
|
assertIteratorResult(result, value, false, itemLabel);
|
||||||
|
|
||||||
|
// Ensure resulting object is a new object.
|
||||||
|
assert.notSameValue(value, last, itemLabel + ": returns a new object");
|
||||||
|
last = value;
|
||||||
|
|
||||||
|
// Ensure resulting object has the expected keys and values.
|
||||||
|
assert.compareArray(Reflect.ownKeys(value), expectedKeys, itemLabel + ": result object keys");
|
||||||
|
|
||||||
|
var expectedValues = Object.values(inputs).map(function (array) {
|
||||||
|
return array[i];
|
||||||
|
});
|
||||||
|
assert.compareArray(Object.values(value), expectedValues, itemLabel + ": result object values");
|
||||||
|
|
||||||
|
// Ensure resulting object is a null-prototype mutable object with default data properties.
|
||||||
|
//
|
||||||
|
// This operation is destructive, so it has to happen last.
|
||||||
|
_assertIsNullProtoMutableObject(value, itemLabel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function forEachSequenceCombinationKeyed(callback) {
|
||||||
|
return forEachSequenceCombination(function(inputs, inputsLabel, min, max) {
|
||||||
|
var object = {};
|
||||||
|
for (var i = 0; i < inputs.length; ++i) {
|
||||||
|
object["prop_" + i] = inputs[i];
|
||||||
|
}
|
||||||
|
inputsLabel = "inputs = " + JSON.stringify(object);
|
||||||
|
callback(object, inputsLabel, min, max);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function forEachSequenceCombination(callback) {
|
||||||
|
function test(inputs) {
|
||||||
|
if (inputs.length === 0) {
|
||||||
|
callback(inputs, "inputs = []", 0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var lengths = inputs.map(function(array) {
|
||||||
|
return array.length;
|
||||||
|
});
|
||||||
|
|
||||||
|
var min = Math.min.apply(null, lengths);
|
||||||
|
var max = Math.max.apply(null, lengths);
|
||||||
|
|
||||||
|
var inputsLabel = "inputs = " + JSON.stringify(inputs);
|
||||||
|
|
||||||
|
callback(inputs, inputsLabel, min, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Yield all prefixes of the string |s|.
|
||||||
|
function* prefixes(s) {
|
||||||
|
for (var i = 0; i <= s.length; ++i) {
|
||||||
|
yield s.slice(0, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zip an empty iterable.
|
||||||
|
test([]);
|
||||||
|
|
||||||
|
// Zip a single iterator.
|
||||||
|
for (var prefix of prefixes("abcd")) {
|
||||||
|
test([prefix.split("")]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zip two iterators.
|
||||||
|
for (var prefix1 of prefixes("abcd")) {
|
||||||
|
for (var prefix2 of prefixes("efgh")) {
|
||||||
|
test([prefix1.split(""), prefix2.split("")]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zip three iterators.
|
||||||
|
for (var prefix1 of prefixes("abcd")) {
|
||||||
|
for (var prefix2 of prefixes("efgh")) {
|
||||||
|
for (var prefix3 of prefixes("ijkl")) {
|
||||||
|
test([prefix1.split(""), prefix2.split(""), prefix3.split("")]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
85
test/built-ins/Iterator/zip/basic-longest.js
Normal file
85
test/built-ins/Iterator/zip/basic-longest.js
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
// Copyright (C) 2025 André Bargull. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-iterator.zip
|
||||||
|
description: >
|
||||||
|
Basic Iterator.zip test with "longest" mode.
|
||||||
|
includes: [compareArray.js, propertyHelper.js, iteratorZipUtils.js]
|
||||||
|
features: [joint-iteration]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
function testSequence(inputs, inputsLabel, minLength, maxLength) {
|
||||||
|
function test(options, optionsLabel, getPaddingForInput) {
|
||||||
|
var label = optionsLabel + ", " + inputsLabel;
|
||||||
|
var it = Iterator.zip(inputs, options);
|
||||||
|
assertZipped(it, inputs, minLength, label);
|
||||||
|
|
||||||
|
for (var i = minLength; i < maxLength; i++) {
|
||||||
|
var itemLabel = label + ", step " + i;
|
||||||
|
|
||||||
|
var result = it.next();
|
||||||
|
var value = result.value;
|
||||||
|
|
||||||
|
// Test IteratorResult structure.
|
||||||
|
assertIteratorResult(result, value, false, itemLabel);
|
||||||
|
|
||||||
|
var expected = inputs.map(function (input, j) {
|
||||||
|
return i < input.length ? input[i] : getPaddingForInput(j);
|
||||||
|
});
|
||||||
|
assert.compareArray(value, expected, itemLabel + ": values");
|
||||||
|
}
|
||||||
|
assertIteratorResult(it.next(), undefined, true, label + ": after completion");
|
||||||
|
}
|
||||||
|
|
||||||
|
test(
|
||||||
|
{ mode: "longest" },
|
||||||
|
"options = { mode: 'longest' }",
|
||||||
|
function () {
|
||||||
|
return undefined;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
{ mode: "longest", padding: [] },
|
||||||
|
"options = { mode: 'longest', padding: [] }",
|
||||||
|
function () {
|
||||||
|
return undefined;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
{ mode: "longest", padding: ["pad"] },
|
||||||
|
"options = { mode: 'longest', padding: ['pad'] }",
|
||||||
|
function (idx) {
|
||||||
|
return idx === 0 ? "pad" : undefined;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
{ mode: "longest", padding: Array(inputs.length).fill("pad") },
|
||||||
|
"options = { mode: 'longest', padding: ['pad', 'pad', ..., 'pad'] }",
|
||||||
|
function (idx) {
|
||||||
|
return "pad";
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// Yield an infinite amount of numbers.
|
||||||
|
var numbers = {
|
||||||
|
*[Symbol.iterator]() {
|
||||||
|
var i = 0;
|
||||||
|
while (true) {
|
||||||
|
yield 100 + i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
test(
|
||||||
|
{ mode: "longest", padding: numbers },
|
||||||
|
"options = { mode: 'longest', padding: numbers }",
|
||||||
|
function (idx) {
|
||||||
|
return 100 + idx;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
forEachSequenceCombination(testSequence);
|
||||||
29
test/built-ins/Iterator/zip/basic-shortest.js
Normal file
29
test/built-ins/Iterator/zip/basic-shortest.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright (C) 2025 André Bargull. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-iterator.zip
|
||||||
|
description: >
|
||||||
|
Basic Iterator.zip test with "shortest" mode.
|
||||||
|
includes: [compareArray.js, propertyHelper.js, iteratorZipUtils.js]
|
||||||
|
features: [joint-iteration]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
function testSequence(inputs, inputsLabel, minLength, maxLength) {
|
||||||
|
function test(options, optionsLabel) {
|
||||||
|
var label = optionsLabel + ", " + inputsLabel;
|
||||||
|
var it = Iterator.zip(inputs, options);
|
||||||
|
assertZipped(it, inputs, minLength, label);
|
||||||
|
|
||||||
|
// Iterator is closed after `minLength` items.
|
||||||
|
assertIteratorResult(it.next(), undefined, true, label + ": after completion");
|
||||||
|
}
|
||||||
|
|
||||||
|
test(undefined, "options = undefined");
|
||||||
|
|
||||||
|
test({}, "options = {}");
|
||||||
|
|
||||||
|
test({ mode: "shortest" }, "options = { mode: 'shortest' }");
|
||||||
|
}
|
||||||
|
|
||||||
|
forEachSequenceCombination(testSequence);
|
||||||
30
test/built-ins/Iterator/zip/basic-strict.js
Normal file
30
test/built-ins/Iterator/zip/basic-strict.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// Copyright (C) 2025 André Bargull. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-iterator.zip
|
||||||
|
description: >
|
||||||
|
Basic Iterator.zip test with "strict" mode.
|
||||||
|
includes: [compareArray.js, propertyHelper.js, iteratorZipUtils.js]
|
||||||
|
features: [joint-iteration]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
function testSequence(inputs, inputsLabel, minLength, maxLength) {
|
||||||
|
function test(options, optionsLabel) {
|
||||||
|
var label = optionsLabel + ", " + inputsLabel;
|
||||||
|
var it = Iterator.zip(inputs, options);
|
||||||
|
assertZipped(it, inputs, minLength, label);
|
||||||
|
|
||||||
|
if (minLength === maxLength) {
|
||||||
|
assertIteratorResult(it.next(), undefined, true, label + ": after completion");
|
||||||
|
} else {
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
it.next();
|
||||||
|
}, label + " should throw after " + minLength + " items.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test({ mode: "strict" }, "options = { mode: 'strict' }");
|
||||||
|
}
|
||||||
|
|
||||||
|
forEachSequenceCombination(testSequence);
|
||||||
@ -1,236 +0,0 @@
|
|||||||
// Copyright (C) 2025 André Bargull. All rights reserved.
|
|
||||||
// This code is governed by the BSD license found in the LICENSE file.
|
|
||||||
|
|
||||||
/*---
|
|
||||||
esid: sec-iterator.zip
|
|
||||||
description: >
|
|
||||||
Basic Iterator.zip test using all three possible modes.
|
|
||||||
includes: [compareArray.js, propertyHelper.js]
|
|
||||||
features: [joint-iteration]
|
|
||||||
---*/
|
|
||||||
|
|
||||||
// Assert |result| is an object created by CreateIteratorResultObject.
|
|
||||||
function assertIteratorResult(result, value, done) {
|
|
||||||
assert.sameValue(
|
|
||||||
Object.getPrototypeOf(result),
|
|
||||||
Object.prototype,
|
|
||||||
"[[Prototype]] of iterator result is Object.prototype"
|
|
||||||
);
|
|
||||||
|
|
||||||
assert(Object.isExtensible(result), "iterator result is extensible");
|
|
||||||
|
|
||||||
var ownKeys = Reflect.ownKeys(result);
|
|
||||||
assert.sameValue(ownKeys.length, 2, "iterator result has two own properties");
|
|
||||||
assert.sameValue(ownKeys[0], "value", "first property is 'value'");
|
|
||||||
assert.sameValue(ownKeys[1], "done", "second property is 'done'");
|
|
||||||
|
|
||||||
verifyProperty(result, "value", {
|
|
||||||
value: value,
|
|
||||||
writable: true,
|
|
||||||
enumerable: true,
|
|
||||||
configurable: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
verifyProperty(result, "done", {
|
|
||||||
value: done,
|
|
||||||
writable: true,
|
|
||||||
enumerable: true,
|
|
||||||
configurable: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assert |array| is a packed array with default property attributes.
|
|
||||||
function assertIsPackedArray(array) {
|
|
||||||
assert(Array.isArray(array), "array is an array exotic object");
|
|
||||||
|
|
||||||
assert.sameValue(
|
|
||||||
Object.getPrototypeOf(array),
|
|
||||||
Array.prototype,
|
|
||||||
"[[Prototype]] of array is Array.prototype"
|
|
||||||
);
|
|
||||||
|
|
||||||
assert(Object.isExtensible(array), "array is extensible");
|
|
||||||
|
|
||||||
// Ensure "length" property has its default property attributes.
|
|
||||||
verifyProperty(array, "length", {
|
|
||||||
writable: true,
|
|
||||||
enumerable: false,
|
|
||||||
configurable: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Ensure no holes and all elements have the default property attributes.
|
|
||||||
for (var i = 0; i < array.length; i++) {
|
|
||||||
verifyProperty(array, i, {
|
|
||||||
writable: true,
|
|
||||||
enumerable: true,
|
|
||||||
configurable: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Yield all prefixes of the string |s|.
|
|
||||||
function* prefixes(s) {
|
|
||||||
for (var i = 0; i <= s.length; ++i) {
|
|
||||||
yield s.slice(0, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Empty iterable doesn't yield any values.
|
|
||||||
var empty = {
|
|
||||||
*[Symbol.iterator]() {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Yield a single value.
|
|
||||||
var single = {
|
|
||||||
*[Symbol.iterator]() {
|
|
||||||
yield 1000;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Yield an infinite amount of numbers.
|
|
||||||
var numbers = {
|
|
||||||
*[Symbol.iterator]() {
|
|
||||||
var i = 0;
|
|
||||||
while (true) {
|
|
||||||
yield 100 + i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// |iterables| is an array whose elements are array(-like) objects. Pass it as
|
|
||||||
// the "iterables" argument to |Iterator.zip|, using |options| as the "options"
|
|
||||||
// argument.
|
|
||||||
//
|
|
||||||
// Then iterate over the returned |Iterator.zip| iterator and check all
|
|
||||||
// returned iteration values have the expected values.
|
|
||||||
function test(iterables, options) {
|
|
||||||
var mode = (options && options.mode) || "shortest";
|
|
||||||
var padding = options && options.padding;
|
|
||||||
|
|
||||||
var lengths = iterables.map(function(array) {
|
|
||||||
return array.length;
|
|
||||||
});
|
|
||||||
|
|
||||||
var min = Math.min.apply(null, lengths);
|
|
||||||
var max = Math.max.apply(null, lengths);
|
|
||||||
|
|
||||||
// Expected number of iterations.
|
|
||||||
var count;
|
|
||||||
switch (mode) {
|
|
||||||
case "shortest":
|
|
||||||
count = min;
|
|
||||||
break;
|
|
||||||
case "longest":
|
|
||||||
count = max;
|
|
||||||
break;
|
|
||||||
case "strict":
|
|
||||||
count = max;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute padding array when |mode| is "longest".
|
|
||||||
if (mode === "longest") {
|
|
||||||
if (padding) {
|
|
||||||
padding = Iterator.from(padding).take(iterables.length).toArray();
|
|
||||||
} else {
|
|
||||||
padding = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fill with undefined until there are exactly |iterables.length| elements.
|
|
||||||
padding = padding.concat(Array(iterables.length - padding.length).fill(undefined));
|
|
||||||
assert.sameValue(padding.length, iterables.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Last returned elements array.
|
|
||||||
var last = null;
|
|
||||||
|
|
||||||
var it = Iterator.zip(iterables, options);
|
|
||||||
for (var i = 0; i < count; i++) {
|
|
||||||
// "strict" mode throws an error if number of elements don't match.
|
|
||||||
if (mode === "strict" && min < max && i === min) {
|
|
||||||
assert.throws(TypeError, function() {
|
|
||||||
it.next();
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = it.next();
|
|
||||||
var value = result.value;
|
|
||||||
|
|
||||||
// Test IteratorResult structure.
|
|
||||||
assertIteratorResult(result, value, false);
|
|
||||||
|
|
||||||
// Ensure value is a new array.
|
|
||||||
assert.notSameValue(value, last, "returns a new array");
|
|
||||||
last = value;
|
|
||||||
|
|
||||||
// Ensure all array elements have the expected value.
|
|
||||||
var expected = iterables.map(function(array, k) {
|
|
||||||
if (i < array.length) {
|
|
||||||
return array[i];
|
|
||||||
}
|
|
||||||
assert.sameValue(mode, "longest", "padding is only used for 'longest' mode");
|
|
||||||
return padding[k];
|
|
||||||
});
|
|
||||||
assert.compareArray(value, expected);
|
|
||||||
|
|
||||||
// Ensure value is a packed array with default data properties.
|
|
||||||
//
|
|
||||||
// This operation is destructive, so it has to happen last.
|
|
||||||
assertIsPackedArray(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Iterator is closed.
|
|
||||||
assertIteratorResult(it.next(), undefined, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
var validOptions = [
|
|
||||||
undefined,
|
|
||||||
{},
|
|
||||||
{mode: "shortest"},
|
|
||||||
{mode: "longest"},
|
|
||||||
{mode: "longest", padding: empty},
|
|
||||||
{mode: "longest", padding: single},
|
|
||||||
{mode: "longest", padding: numbers},
|
|
||||||
{mode: "strict"},
|
|
||||||
];
|
|
||||||
|
|
||||||
for (var options of validOptions) {
|
|
||||||
// Zip an empty iterable.
|
|
||||||
var it = Iterator.zip([], options);
|
|
||||||
assertIteratorResult(it.next(), undefined, true);
|
|
||||||
|
|
||||||
// Zip a single iterator.
|
|
||||||
for (var prefix of prefixes("abcd")) {
|
|
||||||
// Split prefix into an array.
|
|
||||||
test([prefix.split("")], options);
|
|
||||||
|
|
||||||
// Use String wrapper as the iterable.
|
|
||||||
test([new String(prefix)], options);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Zip two iterators.
|
|
||||||
for (var prefix1 of prefixes("abcd")) {
|
|
||||||
for (var prefix2 of prefixes("efgh")) {
|
|
||||||
// Split prefixes into arrays.
|
|
||||||
test([prefix1.split(""), prefix2.split("")], options);
|
|
||||||
|
|
||||||
// Use String wrappers as the iterables.
|
|
||||||
test([new String(prefix1), new String(prefix2)], options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Zip three iterators.
|
|
||||||
for (var prefix1 of prefixes("abcd")) {
|
|
||||||
for (var prefix2 of prefixes("efgh")) {
|
|
||||||
for (var prefix3 of prefixes("ijkl")) {
|
|
||||||
// Split prefixes into arrays.
|
|
||||||
test([prefix1.split(""), prefix2.split(""), prefix3.split("")], options);
|
|
||||||
|
|
||||||
// Use String wrappers as the iterables.
|
|
||||||
test([new String(prefix1), new String(prefix2), new String(prefix3)], options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright (C) 2025 Kevin Gibbons. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-iterator.zip
|
||||||
|
description: >
|
||||||
|
Accepts String objects as inputs.
|
||||||
|
includes: [compareArray.js]
|
||||||
|
features: [joint-iteration]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var result = Array.from(Iterator.zip([Object("abc"), Object("123")]));
|
||||||
|
|
||||||
|
assert.sameValue(result.length, 3);
|
||||||
|
assert.compareArray(result[0], ["a", "1"]);
|
||||||
|
assert.compareArray(result[1], ["b", "2"]);
|
||||||
|
assert.compareArray(result[2], ["c", "3"]);
|
||||||
22
test/built-ins/Iterator/zip/iterator-non-iterable.js
Normal file
22
test/built-ins/Iterator/zip/iterator-non-iterable.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Copyright (C) 2025 Kevin Gibbons. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-iterator.zip
|
||||||
|
description: >
|
||||||
|
Throws a TypeError when the "iterables" argument is not iterable.
|
||||||
|
features: [joint-iteration]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var invalidIterables = [
|
||||||
|
{},
|
||||||
|
{ next() {}, return() {} },
|
||||||
|
function() {}
|
||||||
|
];
|
||||||
|
|
||||||
|
// Throws a TypeError for invalid iterables values.
|
||||||
|
for (var iterables of invalidIterables) {
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
Iterator.zip(iterables);
|
||||||
|
});
|
||||||
|
}
|
||||||
105
test/built-ins/Iterator/zipKeyed/basic-longest.js
Normal file
105
test/built-ins/Iterator/zipKeyed/basic-longest.js
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
// 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: >
|
||||||
|
Basic Iterator.zipKeyed test with "longest" mode.
|
||||||
|
includes: [compareArray.js, propertyHelper.js, iteratorZipUtils.js]
|
||||||
|
features: [joint-iteration]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
function testSequence(inputs, inputsLabel, minLength, maxLength) {
|
||||||
|
function test(options, optionsLabel, getPaddingForInput) {
|
||||||
|
var label = optionsLabel + ", " + inputsLabel;
|
||||||
|
var it = Iterator.zipKeyed(inputs, options);
|
||||||
|
assertZippedKeyed(it, inputs, minLength, label);
|
||||||
|
|
||||||
|
var expectedKeys = Object.keys(inputs);
|
||||||
|
|
||||||
|
for (var i = minLength; i < maxLength; i++) {
|
||||||
|
var itemLabel = label + ", step " + i;
|
||||||
|
|
||||||
|
var result = it.next();
|
||||||
|
var value = result.value;
|
||||||
|
|
||||||
|
// Test IteratorResult structure.
|
||||||
|
assertIteratorResult(result, value, false, itemLabel);
|
||||||
|
|
||||||
|
// Ensure resulting object has the expected keys and values.
|
||||||
|
assert.compareArray(Object.keys(value), expectedKeys, itemLabel + ": result object keys");
|
||||||
|
|
||||||
|
var expectedValues = Object.values(inputs).map(function (input, j) {
|
||||||
|
return i < input.length ? input[i] : getPaddingForInput(j);
|
||||||
|
});
|
||||||
|
assert.compareArray(Object.values(value), expectedValues, itemLabel + ": result object values");
|
||||||
|
}
|
||||||
|
assertIteratorResult(it.next(), undefined, true, label + ": after completion");
|
||||||
|
}
|
||||||
|
|
||||||
|
test(
|
||||||
|
{ mode: "longest" },
|
||||||
|
"options = { mode: 'longest' }",
|
||||||
|
function () {
|
||||||
|
return undefined;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
{ mode: "longest", padding: {} },
|
||||||
|
"options = { mode: 'longest', padding: {} }",
|
||||||
|
function () {
|
||||||
|
return undefined;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
{ mode: "longest", padding: { prop_0: "pad" } },
|
||||||
|
"options = { mode: 'longest', padding: { prop_0: 'pad' } }",
|
||||||
|
function (idx) {
|
||||||
|
return idx === 0 ? "pad" : undefined;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
{ mode: "longest", padding: { prop_1: "pad" } },
|
||||||
|
"options = { mode: 'longest', padding: { prop_1: 'pad' } }",
|
||||||
|
function (idx) {
|
||||||
|
return idx === 1 ? "pad" : undefined;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
var padding = {};
|
||||||
|
for (var key in inputs) {
|
||||||
|
padding[key] = "pad";
|
||||||
|
}
|
||||||
|
test(
|
||||||
|
{ mode: "longest", padding: padding },
|
||||||
|
"options = { mode: 'longest', padding: { prop_0: 'pad', ..., prop_N: 'pad' } }",
|
||||||
|
function (idx) {
|
||||||
|
return "pad";
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// Object with many properties.
|
||||||
|
padding = new Proxy({}, {
|
||||||
|
has(target, key) {
|
||||||
|
return key.indexOf('_') !== -1;
|
||||||
|
},
|
||||||
|
get(target, key, receiver) {
|
||||||
|
var split = key.split('_');
|
||||||
|
if (split.length !== 2) return undefined;
|
||||||
|
return 'pad_' + split[1];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
test(
|
||||||
|
{ mode: "longest", padding: padding },
|
||||||
|
"options = { mode: 'longest', padding: { prop_0: 'pad_1', ..., prop_N: 'pad_N' } }",
|
||||||
|
function (idx) {
|
||||||
|
return 'pad_' + idx;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
forEachSequenceCombinationKeyed(testSequence);
|
||||||
29
test/built-ins/Iterator/zipKeyed/basic-shortest.js
Normal file
29
test/built-ins/Iterator/zipKeyed/basic-shortest.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// 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: >
|
||||||
|
Basic Iterator.zipkeyed test with "shortest" mode.
|
||||||
|
includes: [compareArray.js, propertyHelper.js, iteratorZipUtils.js]
|
||||||
|
features: [joint-iteration]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
function testSequence(inputs, inputsLabel, minLength, maxLength) {
|
||||||
|
function test(options, optionsLabel) {
|
||||||
|
var label = optionsLabel + ", " + inputsLabel;
|
||||||
|
var it = Iterator.zipKeyed(inputs, options);
|
||||||
|
assertZippedKeyed(it, inputs, minLength, label);
|
||||||
|
|
||||||
|
// Iterator is closed after `minLength` items.
|
||||||
|
assertIteratorResult(it.next(), undefined, true, label + ": after completion");
|
||||||
|
}
|
||||||
|
|
||||||
|
test(undefined, "options = undefined");
|
||||||
|
|
||||||
|
test({}, "options = {}");
|
||||||
|
|
||||||
|
test({ mode: "shortest" }, "options = { mode: 'shortest' }");
|
||||||
|
}
|
||||||
|
|
||||||
|
forEachSequenceCombinationKeyed(testSequence);
|
||||||
30
test/built-ins/Iterator/zipKeyed/basic-strict.js
Normal file
30
test/built-ins/Iterator/zipKeyed/basic-strict.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// 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: >
|
||||||
|
Basic Iterator.zipkeyed test with "strict" mode.
|
||||||
|
includes: [compareArray.js, propertyHelper.js, iteratorZipUtils.js]
|
||||||
|
features: [joint-iteration]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
function testSequence(inputs, inputsLabel, minLength, maxLength) {
|
||||||
|
function test(options, optionsLabel) {
|
||||||
|
var label = optionsLabel + ", " + inputsLabel;
|
||||||
|
var it = Iterator.zipKeyed(inputs, options);
|
||||||
|
assertZippedKeyed(it, inputs, minLength, label);
|
||||||
|
|
||||||
|
if (minLength === maxLength) {
|
||||||
|
assertIteratorResult(it.next(), undefined, true, label + ": after completion");
|
||||||
|
} else {
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
it.next();
|
||||||
|
}, label + " should throw after " + minLength + " items.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test({ mode: "strict" }, "options = { mode: 'strict' }");
|
||||||
|
}
|
||||||
|
|
||||||
|
forEachSequenceCombinationKeyed(testSequence);
|
||||||
@ -1,270 +0,0 @@
|
|||||||
// 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: >
|
|
||||||
Basic Iterator.zipKeyed test using all three possible modes.
|
|
||||||
includes: [compareArray.js, propertyHelper.js]
|
|
||||||
features: [joint-iteration]
|
|
||||||
---*/
|
|
||||||
|
|
||||||
// Assert |result| is an object created by CreateIteratorResultObject.
|
|
||||||
function assertIteratorResult(result, value, done) {
|
|
||||||
assert.sameValue(
|
|
||||||
Object.getPrototypeOf(result),
|
|
||||||
Object.prototype,
|
|
||||||
"[[Prototype]] of iterator result is Object.prototype"
|
|
||||||
);
|
|
||||||
|
|
||||||
assert(Object.isExtensible(result), "iterator result is extensible");
|
|
||||||
|
|
||||||
var ownKeys = Reflect.ownKeys(result);
|
|
||||||
assert.sameValue(ownKeys.length, 2, "iterator result has two own properties");
|
|
||||||
assert.sameValue(ownKeys[0], "value", "first property is 'value'");
|
|
||||||
assert.sameValue(ownKeys[1], "done", "second property is 'done'");
|
|
||||||
|
|
||||||
verifyProperty(result, "value", {
|
|
||||||
value: value,
|
|
||||||
writable: true,
|
|
||||||
enumerable: true,
|
|
||||||
configurable: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
verifyProperty(result, "done", {
|
|
||||||
value: done,
|
|
||||||
writable: true,
|
|
||||||
enumerable: true,
|
|
||||||
configurable: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assert |actual| is a plain object equal to |expected| with default property attributes.
|
|
||||||
function assertPlainObject(actual, expected) {
|
|
||||||
assert.sameValue(
|
|
||||||
Object.getPrototypeOf(actual),
|
|
||||||
null,
|
|
||||||
"[[Prototype]] of actual is null"
|
|
||||||
);
|
|
||||||
|
|
||||||
assert(Object.isExtensible(actual), "actual is extensible");
|
|
||||||
|
|
||||||
var actualKeys = Reflect.ownKeys(actual);
|
|
||||||
var expectedKeys = Reflect.ownKeys(expected);
|
|
||||||
|
|
||||||
// All expected property keys are present.
|
|
||||||
assert.compareArray(actualKeys, expectedKeys);
|
|
||||||
|
|
||||||
// All expected property values are equal.
|
|
||||||
for (var key of expectedKeys) {
|
|
||||||
assert.sameValue(actual[key], expected[key], "with key: " + String(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure all properties have the default property attributes.
|
|
||||||
for (var key of expectedKeys) {
|
|
||||||
verifyProperty(actual, key, {
|
|
||||||
writable: true,
|
|
||||||
enumerable: true,
|
|
||||||
configurable: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Yield all prefixes of the string |s|.
|
|
||||||
function* prefixes(s) {
|
|
||||||
for (var i = 0; i <= s.length; ++i) {
|
|
||||||
yield s.slice(0, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Empty object.
|
|
||||||
var empty = {};
|
|
||||||
|
|
||||||
// Object with a single property.
|
|
||||||
var single = {
|
|
||||||
a: 1000,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Object with many properties.
|
|
||||||
var numbers = new Proxy({}, {
|
|
||||||
has(target, key) {
|
|
||||||
if (typeof key === "symbol") {
|
|
||||||
key = key.description;
|
|
||||||
}
|
|
||||||
assert.sameValue(key.length, 1, "unsupported key length");
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
get(target, key, receiver) {
|
|
||||||
if (typeof key === "symbol") {
|
|
||||||
key = key.description;
|
|
||||||
}
|
|
||||||
assert.sameValue(key.length, 1, "unsupported key length");
|
|
||||||
return key.charCodeAt(0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// |iterables| is an object whose properties are array(-like) objects. Pass it
|
|
||||||
// as the "iterables" argument to |Iterator.zipKeyed|, using |options| as the
|
|
||||||
// "options" argument.
|
|
||||||
//
|
|
||||||
// Then iterate over the returned |Iterator.zipKeyed| iterator and check all
|
|
||||||
// returned iteration values have the expected values.
|
|
||||||
function test(iterables, options) {
|
|
||||||
var mode = (options && options.mode) || "shortest";
|
|
||||||
var padding = options && options.padding;
|
|
||||||
|
|
||||||
// Not Object.entries to allow symbol property keys.
|
|
||||||
var entries = Reflect.ownKeys(iterables).map(function(key) {
|
|
||||||
return [key, iterables[key]];
|
|
||||||
});
|
|
||||||
|
|
||||||
var lengths = entries.map(function([key, array]) {
|
|
||||||
return array.length;
|
|
||||||
});
|
|
||||||
|
|
||||||
var min = Math.min.apply(null, lengths);
|
|
||||||
var max = Math.max.apply(null, lengths);
|
|
||||||
|
|
||||||
// Expected number of iterations.
|
|
||||||
var count;
|
|
||||||
switch (mode) {
|
|
||||||
case "shortest":
|
|
||||||
count = min;
|
|
||||||
break;
|
|
||||||
case "longest":
|
|
||||||
count = max;
|
|
||||||
break;
|
|
||||||
case "strict":
|
|
||||||
count = max;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute padding array when |mode| is "longest".
|
|
||||||
if (mode === "longest") {
|
|
||||||
padding = entries.map(function([key, array]) {
|
|
||||||
if (padding !== undefined && key in padding) {
|
|
||||||
return padding[key];
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Last returned results object.
|
|
||||||
var last = null;
|
|
||||||
|
|
||||||
var it = Iterator.zipKeyed(iterables, options);
|
|
||||||
for (var i = 0; i < count; i++) {
|
|
||||||
// "strict" mode throws an error if number of elements don't match.
|
|
||||||
if (mode === "strict" && min < max && i === min) {
|
|
||||||
assert.throws(TypeError, function() {
|
|
||||||
it.next();
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = it.next();
|
|
||||||
var value = result.value;
|
|
||||||
|
|
||||||
// Test IteratorResult structure.
|
|
||||||
assertIteratorResult(result, value, false);
|
|
||||||
|
|
||||||
// Ensure value is a new object.
|
|
||||||
assert.notSameValue(value, last, "returns a new object");
|
|
||||||
last = value;
|
|
||||||
|
|
||||||
var expected = Object.fromEntries(entries.map(function([key, array], k) {
|
|
||||||
if (i < array.length) {
|
|
||||||
return [key, array[i]];
|
|
||||||
}
|
|
||||||
assert.sameValue(mode, "longest", "padding is only used for 'longest' mode");
|
|
||||||
return [key, padding[k]];
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Ensure all properties have the expected value.
|
|
||||||
// Ensure value is a plain with default data properties.
|
|
||||||
assertPlainObject(value, expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Iterator is closed.
|
|
||||||
assertIteratorResult(it.next(), undefined, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
var validOptions = [
|
|
||||||
undefined,
|
|
||||||
{},
|
|
||||||
{mode: "shortest"},
|
|
||||||
{mode: "longest"},
|
|
||||||
{mode: "longest", padding: empty},
|
|
||||||
{mode: "longest", padding: single},
|
|
||||||
{mode: "longest", padding: numbers},
|
|
||||||
{mode: "strict"},
|
|
||||||
];
|
|
||||||
|
|
||||||
for (var options of validOptions) {
|
|
||||||
// Zip an empty object.
|
|
||||||
var it = Iterator.zipKeyed({}, options);
|
|
||||||
assertIteratorResult(it.next(), undefined, true);
|
|
||||||
|
|
||||||
// Zip a single key.
|
|
||||||
for (var prefix of prefixes("abcd")) {
|
|
||||||
// Split prefix into an array.
|
|
||||||
test({
|
|
||||||
a: prefix.split(""),
|
|
||||||
}, options);
|
|
||||||
test({
|
|
||||||
[Symbol("a")]: prefix.split(""),
|
|
||||||
}, options);
|
|
||||||
|
|
||||||
// Use String wrapper as the iterable.
|
|
||||||
test({
|
|
||||||
a: new String(prefix),
|
|
||||||
}, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Zip two keys.
|
|
||||||
for (var prefix1 of prefixes("abcd")) {
|
|
||||||
for (var prefix2 of prefixes("efgh")) {
|
|
||||||
// Split prefixes into arrays.
|
|
||||||
test({
|
|
||||||
a: prefix1.split(""),
|
|
||||||
b: prefix2.split(""),
|
|
||||||
}, options);
|
|
||||||
test({
|
|
||||||
[Symbol("a")]: prefix1.split(""),
|
|
||||||
[Symbol("b")]: prefix2.split(""),
|
|
||||||
}, options);
|
|
||||||
|
|
||||||
// Use String wrappers as the iterables.
|
|
||||||
test({
|
|
||||||
a: new String(prefix1),
|
|
||||||
b: new String(prefix2),
|
|
||||||
}, options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Zip three keys.
|
|
||||||
for (var prefix1 of prefixes("abcd")) {
|
|
||||||
for (var prefix2 of prefixes("efgh")) {
|
|
||||||
for (var prefix3 of prefixes("ijkl")) {
|
|
||||||
// Split prefixes into arrays.
|
|
||||||
test({
|
|
||||||
a: prefix1.split(""),
|
|
||||||
b: prefix2.split(""),
|
|
||||||
c: prefix3.split(""),
|
|
||||||
}, options);
|
|
||||||
test({
|
|
||||||
[Symbol("a")]: prefix1.split(""),
|
|
||||||
[Symbol("b")]: prefix2.split(""),
|
|
||||||
[Symbol("c")]: prefix3.split(""),
|
|
||||||
}, options);
|
|
||||||
|
|
||||||
// Use String wrappers as the iterables.
|
|
||||||
test({
|
|
||||||
a: new String(prefix1),
|
|
||||||
b: new String(prefix2),
|
|
||||||
c: new String(prefix3),
|
|
||||||
}, options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
// Copyright (C) 2025 Kevin Gibbons. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-iterator.zipKeyed
|
||||||
|
description: >
|
||||||
|
Accepts String objects as inputs.
|
||||||
|
includes: [compareArray.js]
|
||||||
|
features: [joint-iteration]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var result = Array.from(Iterator.zipKeyed({
|
||||||
|
a: Object("abc"),
|
||||||
|
b: Object("123"),
|
||||||
|
}));
|
||||||
|
|
||||||
|
assert.sameValue(result.length, 3);
|
||||||
|
result.forEach(function (object) {
|
||||||
|
assert.compareArray(Object.keys(object), ["a", "b"]);
|
||||||
|
});
|
||||||
|
assert.compareArray(Object.values(result[0]), ["a", "1"]);
|
||||||
|
assert.compareArray(Object.values(result[1]), ["b", "2"]);
|
||||||
|
assert.compareArray(Object.values(result[2]), ["c", "3"]);
|
||||||
@ -38,7 +38,7 @@ var iterables = Object.create(null, {
|
|||||||
enumerable: false,
|
enumerable: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
return [];
|
return ['value for b'];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
c: {
|
c: {
|
||||||
@ -58,7 +58,7 @@ var iterables = Object.create(null, {
|
|||||||
enumerable: true,
|
enumerable: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
return [];
|
return ['value for d'];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
e: {
|
e: {
|
||||||
@ -66,15 +66,19 @@ var iterables = Object.create(null, {
|
|||||||
configurable: true,
|
configurable: true,
|
||||||
get() {
|
get() {
|
||||||
log.push("get e");
|
log.push("get e");
|
||||||
return [];
|
return ['value for e'];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Iterator.zipKeyed(iterables);
|
var result = Array.from(Iterator.zipKeyed(iterables));
|
||||||
|
|
||||||
assert.compareArray(log, [
|
assert.compareArray(log, [
|
||||||
"get b",
|
"get b",
|
||||||
"get d",
|
"get d",
|
||||||
"get e",
|
"get e",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
assert.sameValue(result.length, 1);
|
||||||
|
assert.compareArray(Object.keys(result[0]), ["b", "d", "e"]);
|
||||||
|
assert.compareArray(Object.values(result[0]), ["value for b", "value for d", "value for e"]);
|
||||||
|
|||||||
@ -0,0 +1,27 @@
|
|||||||
|
// Copyright (C) 2025 Kevin Gibbons. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-iterator.zipkeyed
|
||||||
|
description: >
|
||||||
|
Inherited properties are skipped in "iterables" iteration.
|
||||||
|
includes: [compareArray.js]
|
||||||
|
features: [joint-iteration]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var parent = {
|
||||||
|
get a() {
|
||||||
|
throw new Test262Error("inherited properties should not be examined");
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var iterables = {
|
||||||
|
__proto__: parent,
|
||||||
|
b: ['value for b'],
|
||||||
|
};
|
||||||
|
|
||||||
|
var result = Array.from(Iterator.zipKeyed(iterables));
|
||||||
|
|
||||||
|
assert.sameValue(result.length, 1);
|
||||||
|
assert.compareArray(Object.keys(result[0]), ["b"]);
|
||||||
|
assert.compareArray(Object.values(result[0]), ["value for b"]);
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
// Copyright (C) 2025 Kevin Gibbons. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-iterator.zipkeyed
|
||||||
|
description: >
|
||||||
|
Symbol properties are used during "iterables" iteration.
|
||||||
|
includes: [compareArray.js]
|
||||||
|
features: [joint-iteration]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var symbolA = Symbol('a');
|
||||||
|
|
||||||
|
var iterables = {
|
||||||
|
[symbolA]: ['value for a'],
|
||||||
|
b: ['value for b'],
|
||||||
|
};
|
||||||
|
|
||||||
|
var result = Array.from(Iterator.zipKeyed(iterables));
|
||||||
|
|
||||||
|
assert.sameValue(result.length, 1);
|
||||||
|
assert.compareArray(Reflect.ownKeys(result[0]), ["b", symbolA]);
|
||||||
|
assert.sameValue(result[0].b, "value for b");
|
||||||
|
assert.sameValue(result[0][symbolA], "value for a");
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
// Copyright (C) 2025 Kevin Gibbons. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-iterator.zipkeyed
|
||||||
|
description: >
|
||||||
|
undefined-valued properties are skipped in "iterables" iteration.
|
||||||
|
includes: [compareArray.js]
|
||||||
|
features: [joint-iteration]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
|
||||||
|
var iterables = {
|
||||||
|
a: undefined,
|
||||||
|
b: ['value for b'],
|
||||||
|
};
|
||||||
|
|
||||||
|
var result = Array.from(Iterator.zipKeyed(iterables));
|
||||||
|
|
||||||
|
assert.sameValue(result.length, 1);
|
||||||
|
assert.compareArray(Reflect.ownKeys(result[0]), ["b"]);
|
||||||
|
assert.compareArray(Object.values(result[0]), ["value for b"]);
|
||||||
@ -42,11 +42,6 @@ var iterableReturningThrowingIterator = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// |undefined| values are ignored.
|
|
||||||
Iterator.zipKeyed({
|
|
||||||
a: undefined,
|
|
||||||
});
|
|
||||||
|
|
||||||
// GetIteratorFlattenable accepts both iterables and iterators.
|
// GetIteratorFlattenable accepts both iterables and iterators.
|
||||||
Iterator.zipKeyed({
|
Iterator.zipKeyed({
|
||||||
a: throwingIterator,
|
a: throwingIterator,
|
||||||
@ -61,6 +56,7 @@ var badIterators = [
|
|||||||
Symbol(),
|
Symbol(),
|
||||||
0,
|
0,
|
||||||
0n,
|
0n,
|
||||||
|
// undefined is handled separately
|
||||||
];
|
];
|
||||||
|
|
||||||
for (var iterator of badIterators) {
|
for (var iterator of badIterators) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user