Files
sashinexists/node_modules/@weborigami/async-tree/test/drivers/ObjectTree.test.js
2024-12-07 13:18:31 +11:00

157 lines
3.8 KiB
JavaScript

import assert from "node:assert";
import { describe, test } from "node:test";
import { ObjectTree, Tree } from "../../src/internal.js";
import * as symbols from "../../src/symbols.js";
describe("ObjectTree", () => {
test("can get the keys of the tree", async () => {
const fixture = createFixture();
assert.deepEqual(Array.from(await fixture.keys()), [
"Alice.md",
"Bob.md",
"Carol.md",
]);
});
test("can get the value for a key", async () => {
const fixture = createFixture();
const alice = await fixture.get("Alice.md");
assert.equal(alice, "Hello, **Alice**.");
});
test("getting an unsupported key returns undefined", async () => {
const fixture = createFixture();
assert.equal(await fixture.get("xyz"), undefined);
});
test("getting a null/undefined key throws an exception", async () => {
const fixture = createFixture();
await assert.rejects(async () => {
await fixture.get(null);
});
await assert.rejects(async () => {
await fixture.get(undefined);
});
});
test("can set a value", async () => {
const tree = new ObjectTree({
a: 1,
b: 2,
c: 3,
});
// Update existing key
await tree.set("a", 4);
// Delete key
await tree.set("b", undefined);
// Overwrite key with trailing slash
await tree.set("c/", {});
// New key
await tree.set("d", 5);
assert.deepEqual(await Tree.entries(tree), [
["a", 4],
["c/", {}],
["d", 5],
]);
});
test("can wrap a class instance", async () => {
class Foo {
constructor() {
this.a = 1;
}
get prop() {
return this._prop;
}
set prop(prop) {
this._prop = prop;
}
}
class Bar extends Foo {
method() {}
}
const bar = new Bar();
/** @type {any} */ (bar).extra = "Hello";
const fixture = new ObjectTree(bar);
assert.deepEqual(await Tree.entries(fixture), [
["a", 1],
["extra", "Hello"],
["prop", undefined],
]);
assert.equal(await fixture.get("a"), 1);
await fixture.set("prop", "Goodbye");
assert.equal(bar.prop, "Goodbye");
assert.equal(await fixture.get("prop"), "Goodbye");
});
test("sets parent symbol on subobjects", async () => {
const fixture = new ObjectTree({
sub: {},
});
const sub = await fixture.get("sub");
assert.equal(sub[symbols.parent], fixture);
});
test("sets parent on subtrees", async () => {
const fixture = new ObjectTree({
a: 1,
more: new ObjectTree({
b: 2,
}),
});
const more = await fixture.get("more");
assert.equal(more.parent, fixture);
});
test("adds trailing slashes to keys for subtrees", async () => {
const tree = new ObjectTree({
a1: 1,
a2: new ObjectTree({
b1: 2,
}),
a3: 3,
a4: new ObjectTree({
b2: 4,
}),
});
const keys = Array.from(await tree.keys());
assert.deepEqual(keys, ["a1", "a2/", "a3", "a4/"]);
});
test("can retrieve values with optional trailing slash", async () => {
const subtree = {
async get(key) {},
async keys() {},
};
const tree = new ObjectTree({
a: 1,
subtree,
});
assert.equal(await tree.get("a"), 1);
assert.equal(await tree.get("a/"), 1);
assert.equal(await tree.get("subtree"), subtree);
assert.equal(await tree.get("subtree/"), subtree);
});
test("method on an object is bound to the object", async () => {
const n = new Number(123);
const tree = new ObjectTree(n);
const method = await tree.get("toString");
assert.equal(method(), "123");
});
});
function createFixture() {
return new ObjectTree({
"Alice.md": "Hello, **Alice**.",
"Bob.md": "Hello, **Bob**.",
"Carol.md": "Hello, **Carol**.",
});
}