import { describe, expect, it } from 'vitest'; import { filterTree, mapTree, traverseTreeValues } from './tree'; describe('traverseTreeValues', () => { interface Node { children?: Node[]; name: string; } type NodeValue = string; const sampleTree: Node[] = [ { name: 'A', children: [ { name: 'B' }, { name: 'C', children: [{ name: 'D' }, { name: 'E' }], }, ], }, { name: 'F', children: [ { name: 'G' }, { name: 'H', children: [{ name: 'I' }], }, ], }, ]; it('traverses tree and returns all node values', () => { const values = traverseTreeValues( sampleTree, (node) => node.name, { childProps: 'children', }, ); expect(values).toEqual(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']); }); it('handles empty tree', () => { const values = traverseTreeValues([], (node) => node.name); expect(values).toEqual([]); }); it('handles tree with only root node', () => { const rootNode = { name: 'A' }; const values = traverseTreeValues( [rootNode], (node) => node.name, ); expect(values).toEqual(['A']); }); it('handles tree with only leaf nodes', () => { const leafNodes = [{ name: 'A' }, { name: 'B' }, { name: 'C' }]; const values = traverseTreeValues( leafNodes, (node) => node.name, ); expect(values).toEqual(['A', 'B', 'C']); }); }); describe('filterTree', () => { const tree = [ { id: 1, children: [ { id: 2 }, { id: 3, children: [{ id: 4 }, { id: 5 }, { id: 6 }] }, { id: 7 }, ], }, { id: 8, children: [{ id: 9 }, { id: 10 }] }, { id: 11 }, ]; it('should return all nodes when condition is always true', () => { const result = filterTree(tree, () => true, { childProps: 'children' }); expect(result).toEqual(tree); }); it('should return only root nodes when condition is always false', () => { const result = filterTree(tree, () => false); expect(result).toEqual([]); }); it('should return nodes with even id values', () => { const result = filterTree(tree, (node) => node.id % 2 === 0); expect(result).toEqual([{ id: 8, children: [{ id: 10 }] }]); }); it('should return nodes with odd id values and their ancestors', () => { const result = filterTree(tree, (node) => node.id % 2 === 1); expect(result).toEqual([ { id: 1, children: [{ id: 3, children: [{ id: 5 }] }, { id: 7 }], }, { id: 11 }, ]); }); it('should return nodes with "leaf" in their name', () => { const tree = [ { name: 'root', children: [ { name: 'leaf 1' }, { name: 'branch', children: [{ name: 'leaf 2' }, { name: 'leaf 3' }], }, { name: 'leaf 4' }, ], }, ]; const result = filterTree( tree, (node) => node.name.includes('leaf') || node.name === 'root', ); expect(result).toEqual([ { name: 'root', children: [{ name: 'leaf 1' }, { name: 'leaf 4' }], }, ]); }); }); describe('mapTree', () => { it('map infinite depth tree using mapTree', () => { const tree = [ { id: 1, name: 'node1', children: [ { id: 2, name: 'node2' }, { id: 3, name: 'node3' }, { id: 4, name: 'node4', children: [ { id: 5, name: 'node5', children: [ { id: 6, name: 'node6' }, { id: 7, name: 'node7' }, ], }, { id: 8, name: 'node8' }, ], }, ], }, ]; const newTree = mapTree(tree, (node) => ({ ...node, name: `${node.name}-new`, })); expect(newTree).toEqual([ { id: 1, name: 'node1-new', children: [ { id: 2, name: 'node2-new' }, { id: 3, name: 'node3-new' }, { id: 4, name: 'node4-new', children: [ { id: 5, name: 'node5-new', children: [ { id: 6, name: 'node6-new' }, { id: 7, name: 'node7-new' }, ], }, { id: 8, name: 'node8-new' }, ], }, ], }, ]); }); });