mirror of
https://github.com/RGBCube/serenity
synced 2025-07-28 20:47:45 +00:00
LibJS: Implement Sets using Maps
This implements ordered sets using Maps with a sentinel value, and includes some extra set tests. Fixes #11004. Co-Authored-By: davidot <davidot@serenityos.org>
This commit is contained in:
parent
4a73ec07c5
commit
3bfcd7b52d
8 changed files with 133 additions and 21 deletions
|
@ -46,3 +46,106 @@ describe("normal behavior", () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("modification during iteration", () => {
|
||||
test("adding items during forEach also get visited", () => {
|
||||
const set = new Set([1, 2]);
|
||||
const visited = [];
|
||||
set.forEach(val => {
|
||||
if (val <= 2) set.add(4 * val);
|
||||
|
||||
visited.push(val);
|
||||
});
|
||||
expect(set).toHaveSize(4);
|
||||
|
||||
expect(visited).toEqual([1, 2, 4, 8]);
|
||||
});
|
||||
|
||||
test("removing an item before it is visited means it doesn't get visited", () => {
|
||||
const set = new Set([1, 2, 3]);
|
||||
const visited = [];
|
||||
set.forEach(val => {
|
||||
visited.push(val);
|
||||
if (val === 1) {
|
||||
expect(set.delete(2)).toBeTrue();
|
||||
} else {
|
||||
expect(val).toBe(3);
|
||||
expect(set.delete(2)).toBeFalse();
|
||||
}
|
||||
});
|
||||
expect(set).toHaveSize(2);
|
||||
expect(visited).toEqual([1, 3]);
|
||||
});
|
||||
|
||||
test("removing an item after it was visited and adding it again means it gets visited twice", () => {
|
||||
const set = new Set([1, 2, 3]);
|
||||
const visited = [];
|
||||
set.forEach(val => {
|
||||
visited.push(val);
|
||||
if (val === 2) {
|
||||
expect(set.delete(1)).toBeTrue();
|
||||
} else if (val === 3) {
|
||||
expect(set).toHaveSize(2);
|
||||
set.add(1);
|
||||
expect(set).toHaveSize(3);
|
||||
}
|
||||
});
|
||||
expect(set).toHaveSize(3);
|
||||
expect(visited).toEqual([1, 2, 3, 1]);
|
||||
});
|
||||
|
||||
test("adding a new item and removing it before it gets visited means it never gets visited", () => {
|
||||
const set = new Set([1, 2]);
|
||||
const visited = [];
|
||||
set.forEach(val => {
|
||||
visited.push(val);
|
||||
if (val === 1) {
|
||||
set.add(3);
|
||||
expect(set).toHaveSize(3);
|
||||
} else if (val === 2) {
|
||||
expect(set).toHaveSize(3);
|
||||
expect(set.delete(3)).toBeTrue();
|
||||
expect(set).toHaveSize(2);
|
||||
}
|
||||
expect(val).not.toBe(3);
|
||||
});
|
||||
expect(set).toHaveSize(2);
|
||||
expect(visited).toEqual([1, 2]);
|
||||
});
|
||||
|
||||
test("removing and adding in the same iterations", () => {
|
||||
const set = new Set([1, 2, 3]);
|
||||
const visited = [];
|
||||
let first = true;
|
||||
set.forEach(val => {
|
||||
visited.push(val);
|
||||
if (val === 1 && first) {
|
||||
expect(set.delete(1)).toBeTrue();
|
||||
set.add(1);
|
||||
}
|
||||
|
||||
first = false;
|
||||
});
|
||||
expect(set).toHaveSize(3);
|
||||
|
||||
expect(visited).toEqual([1, 2, 3, 1]);
|
||||
});
|
||||
|
||||
test("removing and readding the same item means it can get visited n times", () => {
|
||||
let n = 3;
|
||||
|
||||
const set = new Set([1, 2]);
|
||||
|
||||
const visited = [];
|
||||
set.forEach(val => {
|
||||
visited.push(val);
|
||||
if (n-- > 0) {
|
||||
expect(set.delete(val)).toBeTrue();
|
||||
set.add(val);
|
||||
}
|
||||
});
|
||||
|
||||
expect(set).toHaveSize(2);
|
||||
expect(visited).toEqual([1, 2, 1, 2, 1]);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue