Mirror of https://github.com/roostorg/coop
github.com/roostorg/coop
1import { faker } from '@faker-js/faker';
2
3import { Tree, type TreeNode } from './tree';
4
5function populateTree<T>(
6 tree: Tree<T>,
7 depth: number,
8 branches: number,
9 filterValue: string = '',
10 currentLevel = 0,
11 parentNodeKey: string = 'root',
12) {
13 if (currentLevel >= depth) return;
14
15 Array.from({ length: branches }).forEach((_, idx) => {
16 const key = faker.string.uuid();
17 const value =
18 idx % 2 === 0 ? faker.word.noun() : `${filterValue}${faker.word.noun()}`; // Random word
19 tree.insert(parentNodeKey, key, value as unknown as T);
20
21 // Recursively populate the tree
22 populateTree(tree, depth, branches, filterValue, currentLevel + 1, key);
23 });
24}
25
26function convertTreeToList<T>(tree: Tree<T>) {
27 const nodeList: TreeNode<T>[] = [];
28 const traverse = (node: TreeNode<T>) => {
29 nodeList.push(node);
30 node.children.forEach(traverse);
31 };
32
33 traverse(tree.root);
34 return nodeList;
35}
36
37describe('Tree tests', () => {
38 it('Should filter the tree appropriately', () => {
39 const filterString = 'Test-';
40 const tree = new Tree('root', 'rootValue');
41 populateTree(tree, 4, 3, filterString);
42
43 const filteredTree = tree.filterTree((node) => node.includes(filterString));
44
45 expect(filteredTree).not.toBeNull();
46
47 const filteredTreeValues = convertTreeToList(filteredTree!);
48 expect(
49 filteredTreeValues
50 // We only care about the leaves of the tree in this case, since for each
51 // matching node we want to preserve its ancestry line
52 .filter((it) => it.children.length === 0)
53 .every((it) => it.value.includes(filterString)),
54 ).toEqual(true);
55 });
56
57 it('Should return null if no search matches', () => {
58 const filterString = 'some-random-string';
59 const tree = new Tree('root', 'rootValue');
60 populateTree(tree, 4, 3);
61
62 const filteredTree = tree.filterTree((node) => node.includes(filterString));
63
64 expect(filteredTree).toBeNull();
65 });
66});