run npm install to generate a package lock
This commit is contained in:
63
node_modules/@weborigami/async-tree/test/operations/cache.test.js
generated
vendored
Normal file
63
node_modules/@weborigami/async-tree/test/operations/cache.test.js
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
import assert from "node:assert";
|
||||
import { describe, test } from "node:test";
|
||||
import { DeepObjectTree, ObjectTree, Tree } from "../../src/internal.js";
|
||||
import cache from "../../src/operations/cache.js";
|
||||
|
||||
describe("cache", () => {
|
||||
test("caches reads of values from one tree into another", async () => {
|
||||
const objectCache = new ObjectTree({});
|
||||
const fixture = cache(
|
||||
new DeepObjectTree({
|
||||
a: 1,
|
||||
b: 2,
|
||||
c: 3,
|
||||
more: {
|
||||
d: 4,
|
||||
},
|
||||
}),
|
||||
objectCache
|
||||
);
|
||||
|
||||
const keys = [...(await fixture.keys())];
|
||||
assert.deepEqual(keys, ["a", "b", "c", "more/"]);
|
||||
|
||||
assert.equal(await objectCache.get("a"), undefined);
|
||||
assert.equal(await fixture.get("a"), 1);
|
||||
assert.equal(await objectCache.get("a"), 1); // Now in cache
|
||||
|
||||
assert.equal(await objectCache.get("b"), undefined);
|
||||
assert.equal(await fixture.get("b"), 2);
|
||||
assert.equal(await objectCache.get("b"), 2);
|
||||
|
||||
assert.equal(await objectCache.get("more"), undefined);
|
||||
const more = await fixture.get("more");
|
||||
assert.deepEqual([...(await more.keys())], ["d"]);
|
||||
assert.equal(await more.get("d"), 4);
|
||||
const moreCache = await objectCache.get("more");
|
||||
assert.equal(await moreCache.get("d"), 4);
|
||||
});
|
||||
|
||||
test("if a cache filter is supplied, it only caches values whose keys match the filter", async () => {
|
||||
const objectCache = new ObjectTree({});
|
||||
const fixture = cache(
|
||||
Tree.from({
|
||||
"a.txt": "a",
|
||||
"b.txt": "b",
|
||||
}),
|
||||
objectCache,
|
||||
Tree.from({
|
||||
"a.txt": true,
|
||||
})
|
||||
);
|
||||
|
||||
// Access some values to populate the cache.
|
||||
assert.equal(await fixture.get("a.txt"), "a");
|
||||
assert.equal(await fixture.get("b.txt"), "b");
|
||||
|
||||
// The a.txt value should be cached because it matches the filter.
|
||||
assert.equal(await objectCache.get("a.txt"), "a");
|
||||
|
||||
// The b.txt value should not be cached because it does not match the filter.
|
||||
assert.equal(await objectCache.get("b.txt"), undefined);
|
||||
});
|
||||
});
|
||||
90
node_modules/@weborigami/async-tree/test/operations/cachedKeyFunctions.test.js
generated
vendored
Normal file
90
node_modules/@weborigami/async-tree/test/operations/cachedKeyFunctions.test.js
generated
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
import assert from "node:assert";
|
||||
import { describe, test } from "node:test";
|
||||
import { DeepObjectTree, ObjectTree } from "../../src/internal.js";
|
||||
import cachedKeyFunctions from "../../src/operations/cachedKeyFunctions.js";
|
||||
|
||||
describe("cachedKeyFunctions", () => {
|
||||
test("maps keys with caching", async () => {
|
||||
const tree = new ObjectTree({
|
||||
a: "letter a",
|
||||
b: "letter b",
|
||||
});
|
||||
|
||||
let callCount = 0;
|
||||
const addUnderscore = async (sourceKey, tree) => {
|
||||
callCount++;
|
||||
return `_${sourceKey}`;
|
||||
};
|
||||
|
||||
const { inverseKey, key } = cachedKeyFunctions(addUnderscore);
|
||||
|
||||
assert.equal(await inverseKey("_a", tree), "a"); // Cache miss
|
||||
assert.equal(callCount, 1);
|
||||
assert.equal(await inverseKey("_a", tree), "a");
|
||||
assert.equal(callCount, 1);
|
||||
assert.equal(await inverseKey("_b", tree), "b"); // Cache miss
|
||||
assert.equal(callCount, 2);
|
||||
|
||||
assert.equal(await key("a", tree), "_a");
|
||||
assert.equal(await key("a", tree), "_a");
|
||||
assert.equal(await key("b", tree), "_b");
|
||||
assert.equal(callCount, 2);
|
||||
|
||||
// `c` isn't in tree, so we should get undefined.
|
||||
assert.equal(await inverseKey("_c", tree), undefined);
|
||||
// But key mapping is still possible.
|
||||
assert.equal(await key("c", tree), "_c");
|
||||
// And now we have a cache hit.
|
||||
assert.equal(await inverseKey("_c", tree), "c");
|
||||
assert.equal(callCount, 3);
|
||||
});
|
||||
|
||||
test("maps keys with caching and deep option", async () => {
|
||||
const tree = new DeepObjectTree({
|
||||
a: "letter a",
|
||||
b: {
|
||||
c: "letter c",
|
||||
},
|
||||
});
|
||||
|
||||
let callCount = 0;
|
||||
const addUnderscore = async (sourceKey, tree) => {
|
||||
callCount++;
|
||||
return `_${sourceKey}`;
|
||||
};
|
||||
|
||||
const { inverseKey, key } = cachedKeyFunctions(addUnderscore, true);
|
||||
|
||||
assert.equal(await inverseKey("_a", tree), "a"); // Cache miss
|
||||
assert.equal(await inverseKey("_a", tree), "a");
|
||||
assert.equal(callCount, 1);
|
||||
|
||||
// Subtree key left alone
|
||||
assert.equal(await inverseKey("_b", tree), undefined);
|
||||
assert.equal(await inverseKey("b", tree), "b");
|
||||
assert.equal(await inverseKey("b/", tree), "b/");
|
||||
assert.equal(callCount, 1);
|
||||
|
||||
assert.equal(await key("a", tree), "_a");
|
||||
assert.equal(await key("a", tree), "_a");
|
||||
assert.equal(callCount, 1);
|
||||
|
||||
assert.equal(await key("b/", tree), "b/");
|
||||
assert.equal(await key("b", tree), "b");
|
||||
assert.equal(callCount, 1);
|
||||
});
|
||||
|
||||
test("preserves trailing slashes", async () => {
|
||||
const tree = new ObjectTree({
|
||||
a: "letter a",
|
||||
});
|
||||
const addUnderscore = async (sourceKey) => `_${sourceKey}`;
|
||||
const { inverseKey, key } = cachedKeyFunctions(addUnderscore);
|
||||
|
||||
assert.equal(await key("a/", tree), "_a/");
|
||||
assert.equal(await key("a", tree), "_a");
|
||||
|
||||
assert.equal(await inverseKey("_a/", tree), "a/");
|
||||
assert.equal(await inverseKey("_a", tree), "a");
|
||||
});
|
||||
});
|
||||
34
node_modules/@weborigami/async-tree/test/operations/concat.test.js
generated
vendored
Normal file
34
node_modules/@weborigami/async-tree/test/operations/concat.test.js
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
import assert from "node:assert";
|
||||
import { describe, test } from "node:test";
|
||||
import FunctionTree from "../../src/drivers/FunctionTree.js";
|
||||
import { Tree } from "../../src/internal.js";
|
||||
import concat from "../../src/operations/concat.js";
|
||||
|
||||
describe("concat", () => {
|
||||
test("concatenates deep tree values", async () => {
|
||||
const tree = Tree.from({
|
||||
a: "A",
|
||||
b: "B",
|
||||
c: "C",
|
||||
more: {
|
||||
d: "D",
|
||||
e: "E",
|
||||
},
|
||||
});
|
||||
const result = await concat.call(null, tree);
|
||||
assert.equal(result, "ABCDE");
|
||||
});
|
||||
|
||||
test("concatenates deep tree-like values", async () => {
|
||||
const letters = ["a", "b", "c"];
|
||||
const specimens = new FunctionTree(
|
||||
(letter) => ({
|
||||
lowercase: letter,
|
||||
uppercase: letter.toUpperCase(),
|
||||
}),
|
||||
letters
|
||||
);
|
||||
const result = await concat.call(null, specimens);
|
||||
assert.equal(result, "aAbBcC");
|
||||
});
|
||||
});
|
||||
42
node_modules/@weborigami/async-tree/test/operations/deepMerge.test.js
generated
vendored
Normal file
42
node_modules/@weborigami/async-tree/test/operations/deepMerge.test.js
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
import assert from "node:assert";
|
||||
import { describe, test } from "node:test";
|
||||
import { DeepObjectTree, Tree } from "../../src/internal.js";
|
||||
import mergeDeep from "../../src/operations/deepMerge.js";
|
||||
|
||||
describe("mergeDeep", () => {
|
||||
test("can merge deep", async () => {
|
||||
const fixture = mergeDeep(
|
||||
new DeepObjectTree({
|
||||
a: {
|
||||
b: 0, // Will be obscured by `b` below
|
||||
c: {
|
||||
d: 2,
|
||||
},
|
||||
},
|
||||
}),
|
||||
new DeepObjectTree({
|
||||
a: {
|
||||
b: 1,
|
||||
c: {
|
||||
e: 3,
|
||||
},
|
||||
f: 4,
|
||||
},
|
||||
})
|
||||
);
|
||||
assert.deepEqual(await Tree.plain(fixture), {
|
||||
a: {
|
||||
b: 1,
|
||||
c: {
|
||||
d: 2,
|
||||
e: 3,
|
||||
},
|
||||
f: 4,
|
||||
},
|
||||
});
|
||||
|
||||
// Parent of a subvalue is the merged tree
|
||||
const a = await fixture.get("a");
|
||||
assert.equal(a.parent, fixture);
|
||||
});
|
||||
});
|
||||
24
node_modules/@weborigami/async-tree/test/operations/deepReverse.test.js
generated
vendored
Normal file
24
node_modules/@weborigami/async-tree/test/operations/deepReverse.test.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
import assert from "node:assert";
|
||||
import { describe, test } from "node:test";
|
||||
import { Tree } from "../../src/internal.js";
|
||||
import deepReverse from "../../src/operations/deepReverse.js";
|
||||
|
||||
describe("deepReverse", () => {
|
||||
test("reverses keys at all levels of a tree", async () => {
|
||||
const tree = {
|
||||
a: 1,
|
||||
b: {
|
||||
c: 2,
|
||||
d: 3,
|
||||
},
|
||||
};
|
||||
const reversed = deepReverse.call(null, tree);
|
||||
assert.deepEqual(await Tree.plain(reversed), {
|
||||
b: {
|
||||
d: 3,
|
||||
c: 2,
|
||||
},
|
||||
a: 1,
|
||||
});
|
||||
});
|
||||
});
|
||||
22
node_modules/@weborigami/async-tree/test/operations/deepTake.test.js
generated
vendored
Normal file
22
node_modules/@weborigami/async-tree/test/operations/deepTake.test.js
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
import assert from "node:assert";
|
||||
import { describe, test } from "node:test";
|
||||
import { Tree } from "../../src/internal.js";
|
||||
import deepTake from "../../src/operations/deepTake.js";
|
||||
|
||||
describe("deepTake", () => {
|
||||
test("traverses deeply and returns a limited number of items", async () => {
|
||||
const tree = {
|
||||
a: 1,
|
||||
b: {
|
||||
c: 2,
|
||||
d: {
|
||||
e: 3,
|
||||
},
|
||||
f: 4,
|
||||
},
|
||||
g: 5,
|
||||
};
|
||||
const result = await deepTake(tree, 4);
|
||||
assert.deepEqual(await Tree.plain(result), [1, 2, 3, 4]);
|
||||
});
|
||||
});
|
||||
28
node_modules/@weborigami/async-tree/test/operations/deepValues.test.js
generated
vendored
Normal file
28
node_modules/@weborigami/async-tree/test/operations/deepValues.test.js
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
import assert from "node:assert";
|
||||
import { describe, test } from "node:test";
|
||||
import deepValues from "../../src/operations/deepValues.js";
|
||||
|
||||
describe("deepValues", () => {
|
||||
test("returns in-order array of a tree's values", async () => {
|
||||
const tree = {
|
||||
a: 1,
|
||||
b: {
|
||||
c: 2,
|
||||
d: {
|
||||
e: 3,
|
||||
},
|
||||
},
|
||||
f: {
|
||||
g: 4,
|
||||
},
|
||||
};
|
||||
const values = await deepValues(tree);
|
||||
assert.deepEqual(values, [1, 2, 3, 4]);
|
||||
});
|
||||
|
||||
test("returns in-order array of values in nested arrays", async () => {
|
||||
const tree = [1, [2, 3], 4];
|
||||
const values = await deepValues(tree);
|
||||
assert.deepEqual(values, [1, 2, 3, 4]);
|
||||
});
|
||||
});
|
||||
23
node_modules/@weborigami/async-tree/test/operations/deepValuesIterator.test.js
generated
vendored
Normal file
23
node_modules/@weborigami/async-tree/test/operations/deepValuesIterator.test.js
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
import assert from "node:assert";
|
||||
import { describe, test } from "node:test";
|
||||
import { ObjectTree } from "../../src/internal.js";
|
||||
import deepValuesIterator from "../../src/operations/deepValuesIterator.js";
|
||||
|
||||
describe("deepValuesIterator", () => {
|
||||
test("returns an iterator of a tree's deep values", async () => {
|
||||
const tree = new ObjectTree({
|
||||
a: 1,
|
||||
b: 2,
|
||||
more: {
|
||||
c: 3,
|
||||
d: 4,
|
||||
},
|
||||
});
|
||||
const values = [];
|
||||
// The tree will be shallow, but we'll ask to expand the values.
|
||||
for await (const value of deepValuesIterator(tree, { expand: true })) {
|
||||
values.push(value);
|
||||
}
|
||||
assert.deepEqual(values, [1, 2, 3, 4]);
|
||||
});
|
||||
});
|
||||
54
node_modules/@weborigami/async-tree/test/operations/group.test.js
generated
vendored
Normal file
54
node_modules/@weborigami/async-tree/test/operations/group.test.js
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
import assert from "node:assert";
|
||||
import { describe, test } from "node:test";
|
||||
import { Tree } from "../../src/internal.js";
|
||||
import group from "../../src/operations/group.js";
|
||||
|
||||
describe("group transform", () => {
|
||||
test("groups an array using a group key function", async () => {
|
||||
const fonts = [
|
||||
{ name: "Aboreto", tags: ["Sans Serif"] },
|
||||
{ name: "Albert Sans", tags: ["Geometric", "Sans Serif"] },
|
||||
{ name: "Alegreya", tags: ["Serif"] },
|
||||
{ name: "Work Sans", tags: ["Grotesque", "Sans Serif"] },
|
||||
];
|
||||
const tree = Tree.from(fonts);
|
||||
const grouped = await group(tree, (value, key, tree) => value.tags);
|
||||
assert.deepEqual(await Tree.plain(grouped), {
|
||||
Geometric: [{ name: "Albert Sans", tags: ["Geometric", "Sans Serif"] }],
|
||||
Grotesque: [{ name: "Work Sans", tags: ["Grotesque", "Sans Serif"] }],
|
||||
"Sans Serif": [
|
||||
{ name: "Aboreto", tags: ["Sans Serif"] },
|
||||
{ name: "Albert Sans", tags: ["Geometric", "Sans Serif"] },
|
||||
{ name: "Work Sans", tags: ["Grotesque", "Sans Serif"] },
|
||||
],
|
||||
Serif: [{ name: "Alegreya", tags: ["Serif"] }],
|
||||
});
|
||||
});
|
||||
|
||||
test("groups an object using a group key function", async () => {
|
||||
const fonts = {
|
||||
Aboreto: { tags: ["Sans Serif"] },
|
||||
"Albert Sans": { tags: ["Geometric", "Sans Serif"] },
|
||||
Alegreya: { tags: ["Serif"] },
|
||||
"Work Sans": { tags: ["Grotesque", "Sans Serif"] },
|
||||
};
|
||||
const tree = Tree.from(fonts);
|
||||
const grouped = await group(tree, (value, key, tree) => value.tags);
|
||||
assert.deepEqual(await Tree.plain(grouped), {
|
||||
Geometric: {
|
||||
"Albert Sans": { tags: ["Geometric", "Sans Serif"] },
|
||||
},
|
||||
Grotesque: {
|
||||
"Work Sans": { tags: ["Grotesque", "Sans Serif"] },
|
||||
},
|
||||
"Sans Serif": {
|
||||
Aboreto: { tags: ["Sans Serif"] },
|
||||
"Albert Sans": { tags: ["Geometric", "Sans Serif"] },
|
||||
"Work Sans": { tags: ["Grotesque", "Sans Serif"] },
|
||||
},
|
||||
Serif: {
|
||||
Alegreya: { tags: ["Serif"] },
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
17
node_modules/@weborigami/async-tree/test/operations/invokeFunctions.test.js
generated
vendored
Normal file
17
node_modules/@weborigami/async-tree/test/operations/invokeFunctions.test.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
import assert from "node:assert";
|
||||
import { describe, test } from "node:test";
|
||||
import { Tree } from "../../src/internal.js";
|
||||
import invokeFunctions from "../../src/operations/invokeFunctions.js";
|
||||
|
||||
describe("invokeFunctions", () => {
|
||||
test("invokes function values, leaves other values as is", async () => {
|
||||
const fixture = invokeFunctions({
|
||||
a: 1,
|
||||
b: () => 2,
|
||||
});
|
||||
assert.deepEqual(await Tree.plain(fixture), {
|
||||
a: 1,
|
||||
b: 2,
|
||||
});
|
||||
});
|
||||
});
|
||||
82
node_modules/@weborigami/async-tree/test/operations/keyFunctionsForExtensions.test.js
generated
vendored
Normal file
82
node_modules/@weborigami/async-tree/test/operations/keyFunctionsForExtensions.test.js
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
import assert from "node:assert";
|
||||
import { describe, test } from "node:test";
|
||||
import { ObjectTree, Tree } from "../../src/internal.js";
|
||||
import keyFunctionsForExtensions from "../../src/operations/keyFunctionsForExtensions.js";
|
||||
import map from "../../src/operations/map.js";
|
||||
|
||||
describe("keyMapsForExtensions", () => {
|
||||
test("returns key functions that pass a matching key through", async () => {
|
||||
const { inverseKey, key } = keyFunctionsForExtensions({
|
||||
sourceExtension: ".txt",
|
||||
});
|
||||
assert.equal(await inverseKey("file.txt"), "file.txt");
|
||||
assert.equal(await inverseKey("file.txt/"), "file.txt");
|
||||
assert.equal(await key("file.txt"), "file.txt");
|
||||
assert.equal(await key("file.txt/"), "file.txt/");
|
||||
assert.equal(await inverseKey("file.foo"), undefined);
|
||||
assert.equal(await key("file.foo"), undefined);
|
||||
});
|
||||
|
||||
test("returns key functions that can map extensions", async () => {
|
||||
const { inverseKey, key } = keyFunctionsForExtensions({
|
||||
resultExtension: ".json",
|
||||
sourceExtension: ".md",
|
||||
});
|
||||
assert.equal(await inverseKey("file.json"), "file.md");
|
||||
assert.equal(await inverseKey("file.json/"), "file.md");
|
||||
assert.equal(await key("file.md"), "file.json");
|
||||
assert.equal(await key("file.md/"), "file.json/");
|
||||
assert.equal(await inverseKey("file.foo"), undefined);
|
||||
assert.equal(await key("file.foo"), undefined);
|
||||
});
|
||||
|
||||
test("key functions can handle a slash as an explicit extension", async () => {
|
||||
const { inverseKey, key } = keyFunctionsForExtensions({
|
||||
resultExtension: ".html",
|
||||
sourceExtension: "/",
|
||||
});
|
||||
assert.equal(await inverseKey("file.html"), "file/");
|
||||
assert.equal(await inverseKey("file.html/"), "file/");
|
||||
assert.equal(await key("file"), undefined);
|
||||
assert.equal(await key("file/"), "file.html");
|
||||
});
|
||||
|
||||
test("works with map to handle keys that end in a given resultExtension", async () => {
|
||||
const files = new ObjectTree({
|
||||
"file1.txt": "will be mapped",
|
||||
file2: "won't be mapped",
|
||||
"file3.foo": "won't be mapped",
|
||||
});
|
||||
const { inverseKey, key } = keyFunctionsForExtensions({
|
||||
sourceExtension: ".txt",
|
||||
});
|
||||
const fixture = map(files, {
|
||||
inverseKey,
|
||||
key,
|
||||
value: (sourceValue, sourceKey, tree) => sourceValue.toUpperCase(),
|
||||
});
|
||||
assert.deepEqual(await Tree.plain(fixture), {
|
||||
"file1.txt": "WILL BE MAPPED",
|
||||
});
|
||||
});
|
||||
|
||||
test("works with map to change a key's resultExtension", async () => {
|
||||
const files = new ObjectTree({
|
||||
"file1.txt": "will be mapped",
|
||||
file2: "won't be mapped",
|
||||
"file3.foo": "won't be mapped",
|
||||
});
|
||||
const { inverseKey, key } = keyFunctionsForExtensions({
|
||||
resultExtension: ".upper",
|
||||
sourceExtension: ".txt",
|
||||
});
|
||||
const fixture = map(files, {
|
||||
inverseKey,
|
||||
key,
|
||||
value: (sourceValue, sourceKey, tree) => sourceValue.toUpperCase(),
|
||||
});
|
||||
assert.deepEqual(await Tree.plain(fixture), {
|
||||
"file1.upper": "WILL BE MAPPED",
|
||||
});
|
||||
});
|
||||
});
|
||||
204
node_modules/@weborigami/async-tree/test/operations/map.test.js
generated
vendored
Normal file
204
node_modules/@weborigami/async-tree/test/operations/map.test.js
generated
vendored
Normal file
@@ -0,0 +1,204 @@
|
||||
import assert from "node:assert";
|
||||
import { describe, test } from "node:test";
|
||||
import FunctionTree from "../../src/drivers/FunctionTree.js";
|
||||
import { DeepObjectTree, ObjectTree, Tree } from "../../src/internal.js";
|
||||
import map from "../../src/operations/map.js";
|
||||
import * as trailingSlash from "../../src/trailingSlash.js";
|
||||
|
||||
describe("map", () => {
|
||||
test("returns identity graph if no key or value function is supplied", async () => {
|
||||
const tree = {
|
||||
a: "letter a",
|
||||
b: "letter b",
|
||||
};
|
||||
const mapped = map(tree, {});
|
||||
assert.deepEqual(await Tree.plain(mapped), {
|
||||
a: "letter a",
|
||||
b: "letter b",
|
||||
});
|
||||
});
|
||||
|
||||
test("maps values", async () => {
|
||||
const tree = new ObjectTree({
|
||||
a: "letter a",
|
||||
b: "letter b",
|
||||
c: undefined, // Won't be mapped
|
||||
});
|
||||
const mapped = map(tree, {
|
||||
value: (sourceValue, sourceKey, innerTree) => {
|
||||
assert(sourceKey === "a" || sourceKey === "b");
|
||||
assert.equal(innerTree, tree);
|
||||
return sourceValue.toUpperCase();
|
||||
},
|
||||
});
|
||||
assert.deepEqual(await Tree.plain(mapped), {
|
||||
a: "LETTER A",
|
||||
b: "LETTER B",
|
||||
c: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
test("interprets a single function argument as the value function", async () => {
|
||||
const tree = {
|
||||
a: "letter a",
|
||||
b: "letter b",
|
||||
};
|
||||
const uppercaseValues = map(tree, (sourceValue, sourceKey, tree) => {
|
||||
assert(sourceKey === "a" || sourceKey === "b");
|
||||
return sourceValue.toUpperCase();
|
||||
});
|
||||
assert.deepEqual(await Tree.plain(uppercaseValues), {
|
||||
a: "LETTER A",
|
||||
b: "LETTER B",
|
||||
});
|
||||
});
|
||||
|
||||
test("maps keys using key and inverseKey", async () => {
|
||||
const tree = {
|
||||
a: "letter a",
|
||||
b: "letter b",
|
||||
};
|
||||
const underscoreKeys = map(tree, {
|
||||
key: addUnderscore,
|
||||
inverseKey: removeUnderscore,
|
||||
});
|
||||
assert.deepEqual(await Tree.plain(underscoreKeys), {
|
||||
_a: "letter a",
|
||||
_b: "letter b",
|
||||
});
|
||||
});
|
||||
|
||||
test("maps keys and values", async () => {
|
||||
const tree = {
|
||||
a: "letter a",
|
||||
b: "letter b",
|
||||
};
|
||||
const underscoreKeysUppercaseValues = map(tree, {
|
||||
key: addUnderscore,
|
||||
inverseKey: removeUnderscore,
|
||||
value: async (sourceValue, sourceKey, tree) => sourceValue.toUpperCase(),
|
||||
});
|
||||
assert.deepEqual(await Tree.plain(underscoreKeysUppercaseValues), {
|
||||
_a: "LETTER A",
|
||||
_b: "LETTER B",
|
||||
});
|
||||
});
|
||||
|
||||
test("a shallow map is applied to async subtrees too", async () => {
|
||||
const tree = {
|
||||
a: "letter a",
|
||||
more: {
|
||||
b: "letter b",
|
||||
},
|
||||
};
|
||||
const underscoreKeys = map(tree, {
|
||||
key: async (sourceKey, tree) => `_${sourceKey}`,
|
||||
inverseKey: async (resultKey, tree) => resultKey.slice(1),
|
||||
value: async (sourceValue, sourceKey, tree) => sourceKey,
|
||||
});
|
||||
assert.deepEqual(await Tree.plain(underscoreKeys), {
|
||||
_a: "a",
|
||||
_more: "more",
|
||||
});
|
||||
});
|
||||
|
||||
test("value can provide a default key and inverse key functions", async () => {
|
||||
const uppercase = (s) => s.toUpperCase();
|
||||
uppercase.key = addUnderscore;
|
||||
uppercase.inverseKey = removeUnderscore;
|
||||
const tree = {
|
||||
a: "letter a",
|
||||
b: "letter b",
|
||||
};
|
||||
const mapped = map(tree, uppercase);
|
||||
assert.deepEqual(await Tree.plain(mapped), {
|
||||
_a: "LETTER A",
|
||||
_b: "LETTER B",
|
||||
});
|
||||
});
|
||||
|
||||
test("deep maps values", async () => {
|
||||
const tree = new DeepObjectTree({
|
||||
a: "letter a",
|
||||
more: {
|
||||
b: "letter b",
|
||||
},
|
||||
});
|
||||
const uppercaseValues = map(tree, {
|
||||
deep: true,
|
||||
value: (sourceValue, sourceKey, tree) => sourceValue.toUpperCase(),
|
||||
});
|
||||
assert.deepEqual(await Tree.plain(uppercaseValues), {
|
||||
a: "LETTER A",
|
||||
more: {
|
||||
b: "LETTER B",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test("deep maps leaf keys", async () => {
|
||||
const tree = new DeepObjectTree({
|
||||
a: "letter a",
|
||||
more: {
|
||||
b: "letter b",
|
||||
},
|
||||
});
|
||||
const underscoreKeys = map(tree, {
|
||||
deep: true,
|
||||
key: addUnderscore,
|
||||
inverseKey: removeUnderscore,
|
||||
});
|
||||
assert.deepEqual(await Tree.plain(underscoreKeys), {
|
||||
_a: "letter a",
|
||||
more: {
|
||||
_b: "letter b",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test("deep maps leaf keys and values", async () => {
|
||||
const tree = new DeepObjectTree({
|
||||
a: "letter a",
|
||||
more: {
|
||||
b: "letter b",
|
||||
},
|
||||
});
|
||||
const underscoreKeysUppercaseValues = map(tree, {
|
||||
deep: true,
|
||||
key: addUnderscore,
|
||||
inverseKey: removeUnderscore,
|
||||
value: async (sourceValue, sourceKey, tree) => sourceValue.toUpperCase(),
|
||||
});
|
||||
assert.deepEqual(await Tree.plain(underscoreKeysUppercaseValues), {
|
||||
_a: "LETTER A",
|
||||
more: {
|
||||
_b: "LETTER B",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test("needsSourceValue can be set to false in cases where the value isn't necessary", async () => {
|
||||
let flag = false;
|
||||
const tree = new FunctionTree(() => {
|
||||
flag = true;
|
||||
}, ["a", "b", "c"]);
|
||||
const mapped = map(tree, {
|
||||
needsSourceValue: false,
|
||||
value: () => "X",
|
||||
});
|
||||
assert.deepEqual(await Tree.plain(mapped), {
|
||||
a: "X",
|
||||
b: "X",
|
||||
c: "X",
|
||||
});
|
||||
assert(!flag);
|
||||
});
|
||||
});
|
||||
|
||||
function addUnderscore(key) {
|
||||
return `_${key}`;
|
||||
}
|
||||
|
||||
function removeUnderscore(key) {
|
||||
return trailingSlash.has(key) ? key : key.slice(1);
|
||||
}
|
||||
64
node_modules/@weborigami/async-tree/test/operations/merge.test.js
generated
vendored
Normal file
64
node_modules/@weborigami/async-tree/test/operations/merge.test.js
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
import assert from "node:assert";
|
||||
import { describe, test } from "node:test";
|
||||
import { DeepObjectTree, ObjectTree, Tree } from "../../src/internal.js";
|
||||
import merge from "../../src/operations/merge.js";
|
||||
import * as symbols from "../../src/symbols.js";
|
||||
|
||||
describe("merge", () => {
|
||||
test("performs a shallow merge", async () => {
|
||||
const fixture = merge(
|
||||
{
|
||||
a: 1,
|
||||
// Will be obscured by `b` that follows
|
||||
b: {
|
||||
c: 2,
|
||||
},
|
||||
},
|
||||
{
|
||||
b: {
|
||||
d: 3,
|
||||
},
|
||||
e: {
|
||||
f: 4,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
assert.deepEqual(await Tree.plain(fixture), {
|
||||
a: 1,
|
||||
b: {
|
||||
d: 3,
|
||||
},
|
||||
e: {
|
||||
f: 4,
|
||||
},
|
||||
});
|
||||
|
||||
// Merge is shallow, and last tree wins, so `b/c` doesn't exist
|
||||
const c = await Tree.traverse(fixture, "b", "c");
|
||||
assert.equal(c, undefined);
|
||||
|
||||
// Parent of a subvalue is the merged tree
|
||||
const b = await fixture.get("b");
|
||||
assert.equal(b[symbols.parent], fixture);
|
||||
});
|
||||
|
||||
test("subtree can overwrite a leaf node", async () => {
|
||||
const fixture = merge(
|
||||
new ObjectTree({
|
||||
a: 1,
|
||||
}),
|
||||
new DeepObjectTree({
|
||||
a: {
|
||||
b: 2,
|
||||
},
|
||||
})
|
||||
);
|
||||
assert.deepEqual([...(await fixture.keys())], ["a/"]);
|
||||
assert.deepEqual(await Tree.plain(fixture), {
|
||||
a: {
|
||||
b: 2,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
25
node_modules/@weborigami/async-tree/test/operations/regExpKeys.test.js
generated
vendored
Normal file
25
node_modules/@weborigami/async-tree/test/operations/regExpKeys.test.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
import assert from "node:assert";
|
||||
import { describe, test } from "node:test";
|
||||
import { DeepObjectTree, Tree } from "../../src/internal.js";
|
||||
import regExpKeys from "../../src/operations/regExpKeys.js";
|
||||
|
||||
describe("regExpKeys", () => {
|
||||
test("matches keys using regular expressions", async () => {
|
||||
const fixture = await regExpKeys(
|
||||
new DeepObjectTree({
|
||||
a: true,
|
||||
"b.*": true,
|
||||
c: {
|
||||
d: true,
|
||||
"e*": true,
|
||||
},
|
||||
})
|
||||
);
|
||||
assert(await Tree.traverse(fixture, "a"));
|
||||
assert(!(await Tree.traverse(fixture, "alice")));
|
||||
assert(await Tree.traverse(fixture, "bob"));
|
||||
assert(await Tree.traverse(fixture, "brenda"));
|
||||
assert(await Tree.traverse(fixture, "c", "d"));
|
||||
assert(await Tree.traverse(fixture, "c", "eee"));
|
||||
});
|
||||
});
|
||||
23
node_modules/@weborigami/async-tree/test/operations/reverse.test.js
generated
vendored
Normal file
23
node_modules/@weborigami/async-tree/test/operations/reverse.test.js
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
import assert from "node:assert";
|
||||
import { describe, test } from "node:test";
|
||||
import { Tree } from "../../src/internal.js";
|
||||
import reverse from "../../src/operations/reverse.js";
|
||||
|
||||
describe("reverse", () => {
|
||||
test("reverses a tree's top-level keys", async () => {
|
||||
const tree = {
|
||||
a: "A",
|
||||
b: "B",
|
||||
c: "C",
|
||||
};
|
||||
const reversed = reverse.call(null, tree);
|
||||
// @ts-ignore
|
||||
assert.deepEqual(Array.from(await reversed.keys()), ["c", "b", "a"]);
|
||||
// @ts-ignore
|
||||
assert.deepEqual(await Tree.plain(reversed), {
|
||||
c: "C",
|
||||
b: "B",
|
||||
a: "A",
|
||||
});
|
||||
});
|
||||
});
|
||||
25
node_modules/@weborigami/async-tree/test/operations/scope.test.js
generated
vendored
Normal file
25
node_modules/@weborigami/async-tree/test/operations/scope.test.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
import assert from "node:assert";
|
||||
import { describe, test } from "node:test";
|
||||
import { ObjectTree } from "../../src/internal.js";
|
||||
import scope from "../../src/operations/scope.js";
|
||||
|
||||
describe("scope", () => {
|
||||
test("gets the first defined value from the scope trees", async () => {
|
||||
const outer = new ObjectTree({
|
||||
a: 1,
|
||||
b: 2,
|
||||
});
|
||||
const inner = new ObjectTree({
|
||||
a: 3,
|
||||
});
|
||||
inner.parent = outer;
|
||||
const innerScope = scope(inner);
|
||||
assert.deepEqual([...(await innerScope.keys())], ["a", "b"]);
|
||||
// Inner tree has precedence
|
||||
assert.equal(await innerScope.get("a"), 3);
|
||||
// If tree doesn't have value, finds value from parent
|
||||
assert.equal(await innerScope.get("b"), 2);
|
||||
assert.equal(await innerScope.get("c"), undefined);
|
||||
assert.deepEqual(innerScope.trees, [inner, outer]);
|
||||
});
|
||||
});
|
||||
48
node_modules/@weborigami/async-tree/test/operations/sort.test.js
generated
vendored
Normal file
48
node_modules/@weborigami/async-tree/test/operations/sort.test.js
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
import assert from "node:assert";
|
||||
import { describe, test } from "node:test";
|
||||
import { Tree } from "../../src/internal.js";
|
||||
import sort from "../../src/operations/sort.js";
|
||||
|
||||
describe("sort", () => {
|
||||
test("sorts keys using default sort order", async () => {
|
||||
const tree = Tree.from({
|
||||
file10: null,
|
||||
file1: null,
|
||||
file9: null,
|
||||
});
|
||||
const sorted = sort(tree);
|
||||
assert.deepEqual(Array.from(await sorted.keys()), [
|
||||
"file1",
|
||||
"file10",
|
||||
"file9",
|
||||
]);
|
||||
});
|
||||
|
||||
test("invokes a comparison function", async () => {
|
||||
const tree = Tree.from({
|
||||
b: 2,
|
||||
c: 3,
|
||||
a: 1,
|
||||
});
|
||||
// Reverse order
|
||||
const compare = (a, b) => (a > b ? -1 : a < b ? 1 : 0);
|
||||
const sorted = sort(tree, { compare });
|
||||
assert.deepEqual(Array.from(await sorted.keys()), ["c", "b", "a"]);
|
||||
});
|
||||
|
||||
test("invokes a sortKey function", async () => {
|
||||
const tree = {
|
||||
Alice: { age: 48 },
|
||||
Bob: { age: 36 },
|
||||
Carol: { age: 42 },
|
||||
};
|
||||
const sorted = await sort(tree, {
|
||||
sortKey: async (key, tree) => Tree.traverse(tree, key, "age"),
|
||||
});
|
||||
assert.deepEqual(Array.from(await sorted.keys()), [
|
||||
"Bob",
|
||||
"Carol",
|
||||
"Alice",
|
||||
]);
|
||||
});
|
||||
});
|
||||
20
node_modules/@weborigami/async-tree/test/operations/take.test.js
generated
vendored
Normal file
20
node_modules/@weborigami/async-tree/test/operations/take.test.js
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
import assert from "node:assert";
|
||||
import { describe, test } from "node:test";
|
||||
import { Tree } from "../../src/internal.js";
|
||||
import take from "../../src/operations/take.js";
|
||||
|
||||
describe("take", () => {
|
||||
test("limits the number of keys to the indicated count", async () => {
|
||||
const tree = {
|
||||
a: 1,
|
||||
b: 2,
|
||||
c: 3,
|
||||
d: 4,
|
||||
};
|
||||
const result = await take(tree, 2);
|
||||
assert.deepEqual(await Tree.plain(result), {
|
||||
a: 1,
|
||||
b: 2,
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user