Skip to content

Commit

Permalink
Add initial tests for the "iterator-sequencing" proposal
Browse files Browse the repository at this point in the history
  • Loading branch information
anba committed Nov 14, 2024
1 parent 05c45a4 commit a44a64d
Show file tree
Hide file tree
Showing 31 changed files with 1,184 additions and 0 deletions.
4 changes: 4 additions & 0 deletions features.txt
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ Atomics.pause
# https://github.com/tc39/proposal-is-error
Error.isError

# Iterator Sequencing
# https://github.com/tc39/proposal-iterator-sequencing
iterator-sequencing

## Standard language features
#
# Language features that have been included in a published version of the
Expand Down
42 changes: 42 additions & 0 deletions test/built-ins/Iterator/concat/arguments-checked-in-order.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-iterator.concat
description: >
Arguments are validated in order.
info: |
Iterator.concat ( ...items )
1. Let iterables be a new empty List.
2. For each element item of items, do
a. If item is not an Object, throw a TypeError exception.
b. Let method be ? GetMethod(item, %Symbol.iterator%).
...
features: [iterator-sequencing]
---*/

let getIterator = 0;

let iterable1 = {
get [Symbol.iterator]() {
getIterator++;
return function() {
throw new Test262Error();
};
}
};

let iterable2 = {
get [Symbol.iterator]() {
throw new Test262Error();
}
};

assert.sameValue(getIterator, 0);

assert.throws(TypeError, function() {
Iterator.concat(iterable1, null, iterable2);
});

assert.sameValue(getIterator, 1);
49 changes: 49 additions & 0 deletions test/built-ins/Iterator/concat/fresh-iterator-result.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-iterator.concat
description: >
Returns a fresh iterator result object
info: |
Iterator.concat ( ...items )
...
3. Let closure be a new Abstract Closure with no parameters that captures iterables and performs the following steps when called:
a. For each Record iterable of iterables, do
...
v. Repeat, while innerAlive is true,
1. Let innerValue be ? IteratorStepValue(iteratorRecord).
2. If innerValue is done, then
...
3. Else,
a. Let completion be Completion(Yield(innerValue)).
...
features: [iterator-sequencing]
---*/

let oldIterResult = {
done: false,
value: 123,
};

let testIterator = {
next() {
return oldIterResult;
}
};

let iterable = {
[Symbol.iterator]() {
return testIterator;
}
};

let iterator = Iterator.concat(iterable);

let iterResult = iterator.next();

assert.sameValue(iterResult.done, false);
assert.sameValue(iterResult.value, 123);

assert.notSameValue(iterResult, oldIterResult);
52 changes: 52 additions & 0 deletions test/built-ins/Iterator/concat/get-iterator-method-only-once.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-iterator.concat
description: >
Gets the iterator method from the input iterables only once.
info: |
Iterator.concat ( ...items )
1. Let iterables be a new empty List.
2. For each element item of items, do
a. If item is not an Object, throw a TypeError exception.
b. Let method be ? GetMethod(item, %Symbol.iterator%).
c. If method is undefined, throw a TypeError exception.
d. Append the Record { [[OpenMethod]]: method, [[Iterable]]: item } to iterables.
...
features: [iterator-sequencing]
includes: [compareArray.js]
---*/

let iteratorGets = 0;
let iteratorCalls = 0;
let array = [1, 2, 3];

class CountingIterable {
get [Symbol.iterator]() {
++iteratorGets;

return function () {
++iteratorCalls;
return array[Symbol.iterator]();
};
}
}

let iterable = new CountingIterable();

assert.sameValue(iteratorGets, 0);
assert.sameValue(iteratorCalls, 0);

let iter = Iterator.concat(iterable);

assert.sameValue(iteratorGets, 1);
assert.sameValue(iteratorCalls, 0);

let result = [...iter];

assert.sameValue(iteratorGets, 1);
assert.sameValue(iteratorCalls, 1);

assert.compareArray(result, array);
27 changes: 27 additions & 0 deletions test/built-ins/Iterator/concat/get-iterator-method-throws.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-iterator.concat
description: >
Error thrown when retrieving the iterator method.
info: |
Iterator.concat ( ...items )
1. Let iterables be a new empty List.
2. For each element item of items, do
a. If item is not an Object, throw a TypeError exception.
b. Let method be ? GetMethod(item, %Symbol.iterator%).
...
features: [iterator-sequencing]
---*/

var iterable = {
get [Symbol.iterator]() {
throw new Test262Error();
}
};

assert.throws(Test262Error, function() {
Iterator.concat(iterable);
});
52 changes: 52 additions & 0 deletions test/built-ins/Iterator/concat/inner-iterator-created-in-order.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-iterator.concat
description: >
Inner iterators created in order
info: |
Iterator.concat ( ...items )
...
3. Let closure be a new Abstract Closure with no parameters that captures iterables and performs the following steps when called:
a. For each Record iterable of iterables, do
i. Let iter be ? Call(iterable.[[OpenMethod]], iterable.[[Iterable]]).
...
v. Repeat, while innerAlive is true,
...
features: [iterator-sequencing]
includes: [compareArray.js]
---*/

let calledIterator = [];

let iterable1 = {
[Symbol.iterator]() {
calledIterator.push("iterable1");
return [1][Symbol.iterator]();
}
};

let iterable2 = {
[Symbol.iterator]() {
calledIterator.push("iterable2");
return [2][Symbol.iterator]();
}
};

let iterator = Iterator.concat(iterable1, iterable2);

assert.compareArray(calledIterator, []);

let iterResult = iterator.next();
assert.sameValue(iterResult.done, false);
assert.sameValue(iterResult.value, 1);

assert.compareArray(calledIterator, ["iterable1"]);

iterResult = iterator.next();
assert.sameValue(iterResult.done, false);
assert.sameValue(iterResult.value, 2);

assert.compareArray(calledIterator, ["iterable1", "iterable2"]);
15 changes: 15 additions & 0 deletions test/built-ins/Iterator/concat/is-function.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-iterator.concat
description: >
Iterator.concat is a built-in function
features: [iterator-sequencing]
---*/

assert.sameValue(
typeof Iterator.concat,
"function",
"The value of `typeof Iterator.concat` is 'function'"
);
23 changes: 23 additions & 0 deletions test/built-ins/Iterator/concat/length.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-iterator.concat
description: >
Iterator.concat has a "length" property whose value is 0.
info: |
ECMAScript Standard Built-in Objects
Unless otherwise specified, the length property of a built-in
Function object has the attributes { [[Writable]]: false, [[Enumerable]]:
false, [[Configurable]]: true }.
features: [iterator-sequencing]
includes: [propertyHelper.js]
---*/

verifyProperty(Iterator.concat, "length", {
value: 0,
writable: false,
enumerable: false,
configurable: true,
});
45 changes: 45 additions & 0 deletions test/built-ins/Iterator/concat/many-arguments.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-iterator.concat
description: >
Iterator.concat when called with many arguments.
info: |
Iterator.concat ( ...items )
1. Let iterables be a new empty List.
2. For each element item of items, do
...
3. Let closure be a new Abstract Closure with no parameters that captures iterables and performs the following steps when called:
a. For each Record iterable of iterables, do
...
b. Return ReturnCompletion(undefined).
...
6. Return gen.
features: [iterator-sequencing]
---*/

let iterables = [
[/* empty */],
[1],
[2, 3],
[4, 5, 6],
[7, 8, 9, 10],
];

let iterator = Iterator.concat(...iterables);

let array = [].concat(...iterables);

for (let i = 0; i < array.length; i++) {
let iterResult = iterator.next();

assert.sameValue(iterResult.done, false);
assert.sameValue(iterResult.value, array[i]);
}

let iterResult = iterator.next();

assert.sameValue(iterResult.done, true);
assert.sameValue(iterResult.value, undefined);
30 changes: 30 additions & 0 deletions test/built-ins/Iterator/concat/name.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-iterator.concat
description: >
The "name" property of Iterator.concat
info: |
17 ECMAScript Standard Built-in Objects
Every built-in Function object, including constructors, that is not
identified as an anonymous function has a name property whose value is a
String. Unless otherwise specified, this value is the name that is given to
the function in this specification.
...
Unless otherwise specified, the name property of a built-in Function
object, if it exists, has the attributes { [[Writable]]: false,
[[Enumerable]]: false, [[Configurable]]: true }.
features: [iterator-sequencing]
includes: [propertyHelper.js]
---*/

verifyProperty(Iterator.concat, "name", {
value: "concat",
writable: false,
enumerable: false,
configurable: true,
});
Loading

0 comments on commit a44a64d

Please sign in to comment.