mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 06:37:43 +00:00
LibJS: Implement basic for..in and for..of loops
This commit is contained in:
parent
c378a1c730
commit
07af2e6b2c
8 changed files with 372 additions and 90 deletions
|
@ -73,67 +73,47 @@ try {
|
|||
const o = { length: 5, 0: "foo", 1: "bar", 3: "baz" };
|
||||
|
||||
{
|
||||
const visited = [];
|
||||
Array.prototype.every.call(o, function (value) {
|
||||
visited.push(value);
|
||||
return true;
|
||||
});
|
||||
assert(visited.length === 3);
|
||||
assert(visited[0] === "foo");
|
||||
assert(visited[1] === "bar");
|
||||
assert(visited[2] === "baz");
|
||||
assertVisitsAll(visit => {
|
||||
Array.prototype.every.call(o, function (value) {
|
||||
visit(value);
|
||||
return true;
|
||||
});
|
||||
}, ["foo", "bar", "baz"]);
|
||||
}
|
||||
|
||||
["find", "findIndex"].forEach(name => {
|
||||
const visited = [];
|
||||
Array.prototype[name].call(o, function (value) {
|
||||
visited.push(value);
|
||||
return false;
|
||||
});
|
||||
assert(visited.length === 5);
|
||||
assert(visited[0] === "foo");
|
||||
assert(visited[1] === "bar");
|
||||
assert(visited[2] === undefined);
|
||||
assert(visited[3] === "baz");
|
||||
assert(visited[4] === undefined);
|
||||
assertVisitsAll(visit => {
|
||||
Array.prototype[name].call(o, function (value) {
|
||||
visit(value);
|
||||
return false;
|
||||
});
|
||||
}, ["foo", "bar", undefined, "baz", undefined]);
|
||||
});
|
||||
|
||||
["filter", "forEach", "map", "some"].forEach(name => {
|
||||
const visited = [];
|
||||
Array.prototype[name].call(o, function (value) {
|
||||
visited.push(value);
|
||||
return false;
|
||||
});
|
||||
assert(visited.length === 3);
|
||||
assert(visited[0] === "foo");
|
||||
assert(visited[1] === "bar");
|
||||
assert(visited[2] === "baz");
|
||||
assertVisitsAll(visit => {
|
||||
Array.prototype[name].call(o, function (value) {
|
||||
visit(value);
|
||||
return false;
|
||||
});
|
||||
}, ["foo", "bar", "baz"]);
|
||||
});
|
||||
|
||||
{
|
||||
const visited = [];
|
||||
Array.prototype.reduce.call(o, function (_, value) {
|
||||
visited.push(value);
|
||||
return false;
|
||||
}, "initial");
|
||||
|
||||
assert(visited.length === 3);
|
||||
assert(visited[0] === "foo");
|
||||
assert(visited[1] === "bar");
|
||||
assert(visited[2] === "baz");
|
||||
assertVisitsAll(visit => {
|
||||
Array.prototype.reduce.call(o, function (_, value) {
|
||||
visit(value);
|
||||
return false;
|
||||
}, "initial");
|
||||
}, ["foo", "bar", "baz"]);
|
||||
}
|
||||
|
||||
{
|
||||
const visited = [];
|
||||
Array.prototype.reduceRight.call(o, function (_, value) {
|
||||
visited.push(value);
|
||||
return false;
|
||||
}, "initial");
|
||||
|
||||
assert(visited.length === 3);
|
||||
assert(visited[2] === "foo");
|
||||
assert(visited[1] === "bar");
|
||||
assert(visited[0] === "baz");
|
||||
assertVisitsAll(visit => {
|
||||
Array.prototype.reduceRight.call(o, function (_, value) {
|
||||
visit(value);
|
||||
return false;
|
||||
}, "initial");
|
||||
}, ["baz", "bar", "foo"]);
|
||||
}
|
||||
|
||||
console.log("PASS");
|
||||
|
|
41
Libraries/LibJS/Tests/for-in-basic.js
Normal file
41
Libraries/LibJS/Tests/for-in-basic.js
Normal file
|
@ -0,0 +1,41 @@
|
|||
load("test-common.js");
|
||||
|
||||
try {
|
||||
assertVisitsAll(visit => {
|
||||
for (const property in "") {
|
||||
visit(property);
|
||||
}
|
||||
}, []);
|
||||
|
||||
assertVisitsAll(visit => {
|
||||
for (const property in 123) {
|
||||
visit(property);
|
||||
}
|
||||
}, []);
|
||||
|
||||
assertVisitsAll(visit => {
|
||||
for (const property in {}) {
|
||||
visit(property);
|
||||
}
|
||||
}, []);
|
||||
|
||||
assertVisitsAll(visit => {
|
||||
for (const property in "hello") {
|
||||
visit(property);
|
||||
}
|
||||
}, ["0", "1", "2", "3", "4"]);
|
||||
|
||||
assertVisitsAll(visit => {
|
||||
for (const property in {a: 1, b: 2, c: 2}) {
|
||||
visit(property);
|
||||
}
|
||||
}, ["a", "b", "c"]);
|
||||
|
||||
var property;
|
||||
for (property in "abc");
|
||||
assert(property === "2");
|
||||
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL: " + e);
|
||||
}
|
43
Libraries/LibJS/Tests/for-of-basic.js
Normal file
43
Libraries/LibJS/Tests/for-of-basic.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
load("test-common.js");
|
||||
|
||||
try {
|
||||
assertThrowsError(() => {
|
||||
for (const _ of 123) {}
|
||||
}, {
|
||||
error: TypeError,
|
||||
message: "for..of right-hand side must be iterable"
|
||||
});
|
||||
|
||||
assertThrowsError(() => {
|
||||
for (const _ of {foo: 1, bar: 2}) {}
|
||||
}, {
|
||||
error: TypeError,
|
||||
message: "for..of right-hand side must be iterable"
|
||||
});
|
||||
|
||||
assertVisitsAll(visit => {
|
||||
for (const num of [1, 2, 3]) {
|
||||
visit(num);
|
||||
}
|
||||
}, [1, 2, 3]);
|
||||
|
||||
assertVisitsAll(visit => {
|
||||
for (const char of "hello") {
|
||||
visit(char);
|
||||
}
|
||||
}, ["h", "e", "l", "l", "o"]);
|
||||
|
||||
assertVisitsAll(visit => {
|
||||
for (const char of new String("hello")) {
|
||||
visit(char);
|
||||
}
|
||||
}, ["h", "e", "l", "l", "o"]);
|
||||
|
||||
var char;
|
||||
for (char of "abc");
|
||||
assert(char === "c");
|
||||
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL: " + e);
|
||||
}
|
|
@ -50,6 +50,13 @@ function assertThrowsError(testFunction, options) {
|
|||
}
|
||||
}
|
||||
|
||||
const assertVisitsAll = (testFunction, expectedOutput) => {
|
||||
const visited = [];
|
||||
testFunction(value => visited.push(value));
|
||||
assert(visited.length === expectedOutput.length);
|
||||
expectedOutput.forEach((value, i) => assert(visited[i] === value));
|
||||
};
|
||||
|
||||
/**
|
||||
* Check whether the difference between two numbers is less than 0.000001.
|
||||
* @param {Number} a First number
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue