154 lines
4.5 KiB
JavaScript
154 lines
4.5 KiB
JavaScript
import assert from "node:assert";
|
|
import { describe, test } from "node:test";
|
|
import BrowserFileTree from "../../src/drivers/BrowserFileTree.js";
|
|
import { Tree } from "../../src/internal.js";
|
|
|
|
// Skip these tests if we're not in a browser.
|
|
const isBrowser = typeof window !== "undefined";
|
|
if (isBrowser) {
|
|
describe("BrowserFileTree", async () => {
|
|
test("can get the keys of the tree", async () => {
|
|
const fixture = await createFixture();
|
|
assert.deepEqual(Array.from(await fixture.keys()), [
|
|
"Alice.md",
|
|
"Bob.md",
|
|
"Carol.md",
|
|
"subfolder/",
|
|
]);
|
|
});
|
|
|
|
test("can get the value for a key", async () => {
|
|
const fixture = await createFixture();
|
|
const buffer = await fixture.get("Alice.md");
|
|
assert.equal(text(buffer), "Hello, **Alice**.");
|
|
});
|
|
|
|
test("getting an unsupported key returns undefined", async () => {
|
|
const fixture = await createFixture();
|
|
assert.equal(await fixture.get("xyz"), undefined);
|
|
});
|
|
|
|
test("getting empty key returns undefined", async () => {
|
|
const fixture = await createFixture();
|
|
assert.equal(await fixture.get(""), undefined);
|
|
});
|
|
|
|
test("getting a null/undefined key throws an exception", async () => {
|
|
const fixture = await createFixture();
|
|
await assert.rejects(async () => {
|
|
await fixture.get(null);
|
|
});
|
|
await assert.rejects(async () => {
|
|
await fixture.get(undefined);
|
|
});
|
|
});
|
|
|
|
test("sets parent on subtrees", async () => {
|
|
const fixture = await createFixture();
|
|
const subfolder = await fixture.get("subfolder");
|
|
assert.equal(subfolder.parent, fixture);
|
|
});
|
|
|
|
test("can retrieve values with optional trailing slash", async () => {
|
|
const fixture = await createFixture();
|
|
assert(await fixture.get("Alice.md"));
|
|
assert(await fixture.get("Alice.md/"));
|
|
assert(await fixture.get("subfolder"));
|
|
assert(await fixture.get("subfolder/"));
|
|
});
|
|
|
|
test("can set a value", async () => {
|
|
const fixture = await createFixture();
|
|
|
|
// Update existing key.
|
|
await fixture.set("Alice.md", "Goodbye, **Alice**.");
|
|
|
|
// New key.
|
|
await fixture.set("David.md", "Hello, **David**.");
|
|
|
|
// Delete key.
|
|
await fixture.set("Bob.md", undefined);
|
|
|
|
// Delete non-existent key.
|
|
await fixture.set("xyz", undefined);
|
|
|
|
assert.deepEqual(await strings(fixture), {
|
|
"Alice.md": "Goodbye, **Alice**.",
|
|
"Carol.md": "Hello, **Carol**.",
|
|
"David.md": "Hello, **David**.",
|
|
subfolder: {},
|
|
});
|
|
});
|
|
|
|
test("can create a subfolder via set", async () => {
|
|
const fixture = await createFixture();
|
|
const tree = {
|
|
async get(key) {
|
|
const name = key.replace(/\.md$/, "");
|
|
return `Hello, **${name}**.`;
|
|
},
|
|
async keys() {
|
|
return ["Ellen.md"];
|
|
},
|
|
};
|
|
await fixture.set("more", tree);
|
|
assert.deepEqual(await strings(fixture), {
|
|
"Alice.md": "Hello, **Alice**.",
|
|
"Bob.md": "Hello, **Bob**.",
|
|
"Carol.md": "Hello, **Carol**.",
|
|
more: {
|
|
"Ellen.md": "Hello, **Ellen**.",
|
|
},
|
|
subfolder: {},
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
async function createFile(directory, name, contents) {
|
|
const file = await directory.getFileHandle(name, { create: true });
|
|
const writable = await file.createWritable();
|
|
await writable.write(contents);
|
|
await writable.close();
|
|
}
|
|
|
|
let count = 0;
|
|
async function createFixture() {
|
|
const root = await navigator.storage.getDirectory();
|
|
const directory = await root.getDirectoryHandle("async-tree", {
|
|
create: true,
|
|
});
|
|
|
|
// Create a new subdirectory for each test.
|
|
const subdirectoryName = `test${count++}`;
|
|
|
|
// Delete any pre-existing subdirectory with that name.
|
|
try {
|
|
await directory.removeEntry(subdirectoryName, { recursive: true });
|
|
} catch (e) {
|
|
// Ignore errors.
|
|
}
|
|
|
|
const subdirectory = await directory.getDirectoryHandle(subdirectoryName, {
|
|
create: true,
|
|
});
|
|
|
|
await createFile(subdirectory, "Alice.md", "Hello, **Alice**.");
|
|
await createFile(subdirectory, "Bob.md", "Hello, **Bob**.");
|
|
await createFile(subdirectory, "Carol.md", "Hello, **Carol**.");
|
|
|
|
await subdirectory.getDirectoryHandle("subfolder", {
|
|
create: true,
|
|
});
|
|
|
|
return new BrowserFileTree(subdirectory);
|
|
}
|
|
|
|
async function strings(tree) {
|
|
return Tree.plain(Tree.map(tree, (value) => text(value)));
|
|
}
|
|
|
|
function text(arrayBuffer) {
|
|
return new TextDecoder().decode(arrayBuffer);
|
|
}
|