1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import * as Tree from './tree';
6 import { initTreeNode } from './tree';
7 import { pipe, isEqual } from 'lodash/fp';
9 describe('Tree', () => {
13 tree = Tree.createTree();
16 it('sets new node', () => {
17 const newTree = Tree.setNode(initTreeNode({ id: 'Node 1', value: 'Value 1' }))(tree);
18 expect(isEqual(Tree.getNode('Node 1')(newTree), initTreeNode({ id: 'Node 1', value: 'Value 1' }))).to.equal(true);
21 it('appends a subtree', () => {
22 const newTree = Tree.setNode(initTreeNode({ id: 'Node 1', value: 'Value 1' }))(tree);
23 const subtree = Tree.setNode(initTreeNode({ id: 'Node 2', value: 'Value 2' }))(Tree.createTree());
24 const mergedTree = Tree.appendSubtree('Node 1', subtree)(newTree);
25 expect(Tree.getNode('Node 1')(mergedTree)).to.not.equal('undefined');
26 expect(Tree.getNode('Node 2')(mergedTree)).to.not.equal('undefined');
29 it('adds new node reference to parent children', () => {
31 Tree.setNode(initTreeNode({ id: 'Node 1', parent: '', value: 'Value 1' })),
32 Tree.setNode(initTreeNode({ id: 'Node 2', parent: 'Node 1', value: 'Value 2' })),
35 expect(isEqual(Tree.getNode('Node 1')(newTree), {
36 ...initTreeNode({ id: 'Node 1', parent: '', value: 'Value 1' }),
41 it('gets node ancestors', () => {
43 initTreeNode({ id: 'Node 1', parent: '', value: 'Value 1' }),
44 initTreeNode({ id: 'Node 2', parent: 'Node 1', value: 'Value 1' }),
45 initTreeNode({ id: 'Node 3', parent: 'Node 2', value: 'Value 1' }),
46 ].reduce((tree, node) => Tree.setNode(node)(tree), tree);
47 expect(isEqual(Tree.getNodeAncestorsIds('Node 3')(newTree), ['Node 1', 'Node 2'])).to.equal(true);
50 it('gets node descendants', () => {
52 initTreeNode({ id: 'Node 1', parent: '', value: 'Value 1' }),
53 initTreeNode({ id: 'Node 2', parent: 'Node 1', value: 'Value 1' }),
54 initTreeNode({ id: 'Node 2.1', parent: 'Node 2', value: 'Value 1' }),
55 initTreeNode({ id: 'Node 3', parent: 'Node 1', value: 'Value 1' }),
56 initTreeNode({ id: 'Node 3.1', parent: 'Node 3', value: 'Value 1' }),
57 ].reduce((tree, node) => Tree.setNode(node)(tree), tree);
58 expect(isEqual(Tree.getNodeDescendantsIds('Node 1')(newTree), ['Node 2', 'Node 3', 'Node 2.1', 'Node 3.1'])).to.equal(true);
61 it('gets root descendants', () => {
63 initTreeNode({ id: 'Node 1', parent: '', value: 'Value 1' }),
64 initTreeNode({ id: 'Node 2', parent: 'Node 1', value: 'Value 1' }),
65 initTreeNode({ id: 'Node 2.1', parent: 'Node 2', value: 'Value 1' }),
66 initTreeNode({ id: 'Node 3', parent: 'Node 1', value: 'Value 1' }),
67 initTreeNode({ id: 'Node 3.1', parent: 'Node 3', value: 'Value 1' }),
68 ].reduce((tree, node) => Tree.setNode(node)(tree), tree);
69 expect(isEqual(Tree.getNodeDescendantsIds('')(newTree), ['Node 1', 'Node 2', 'Node 3', 'Node 2.1', 'Node 3.1'])).to.equal(true);
72 it('gets node children', () => {
74 initTreeNode({ id: 'Node 1', parent: '', value: 'Value 1' }),
75 initTreeNode({ id: 'Node 2', parent: 'Node 1', value: 'Value 1' }),
76 initTreeNode({ id: 'Node 2.1', parent: 'Node 2', value: 'Value 1' }),
77 initTreeNode({ id: 'Node 3', parent: 'Node 1', value: 'Value 1' }),
78 initTreeNode({ id: 'Node 3.1', parent: 'Node 3', value: 'Value 1' }),
79 ].reduce((tree, node) => Tree.setNode(node)(tree), tree);
80 expect(isEqual(Tree.getNodeChildrenIds('Node 1')(newTree), ['Node 2', 'Node 3'])).to.equal(true);
83 it('gets root children', () => {
85 initTreeNode({ id: 'Node 1', parent: '', value: 'Value 1' }),
86 initTreeNode({ id: 'Node 2', parent: 'Node 1', value: 'Value 1' }),
87 initTreeNode({ id: 'Node 2.1', parent: 'Node 2', value: 'Value 1' }),
88 initTreeNode({ id: 'Node 3', parent: '', value: 'Value 1' }),
89 initTreeNode({ id: 'Node 3.1', parent: 'Node 3', value: 'Value 1' }),
90 ].reduce((tree, node) => Tree.setNode(node)(tree), tree);
91 expect(isEqual(Tree.getNodeChildrenIds('')(newTree), ['Node 1', 'Node 3'])).to.equal(true);
94 it('maps tree', () => {
96 initTreeNode({ id: 'Node 1', parent: '', value: 'Value 1' }),
97 initTreeNode({ id: 'Node 2', parent: 'Node 1', value: 'Value 2' }),
98 ].reduce((tree, node) => Tree.setNode(node)(tree), tree);
99 const mappedTree = Tree.mapTreeValues(value => parseInt(value.split(' ')[1], 10))(newTree);
100 expect(isEqual(Tree.getNode('Node 2')(mappedTree), initTreeNode({ id: 'Node 2', parent: 'Node 1', value: 2 }))).to.equal(true);
103 it('expands node ancestor chains', () => {
105 initTreeNode({ id: 'Root Node 1', parent: '', value: 'Value 1' }),
106 initTreeNode({ id: 'Node 1.1', parent: 'Root Node 1', value: 'Value 1' }),
107 initTreeNode({ id: 'Node 1.1.1', parent: 'Node 1.1', value: 'Value 1' }),
108 initTreeNode({ id: 'Node 1.2', parent: 'Root Node 1', value: 'Value 1' }),
110 initTreeNode({ id: 'Root Node 2', parent: '', value: 'Value 1' }),
111 initTreeNode({ id: 'Node 2.1', parent: 'Root Node 2', value: 'Value 1' }),
112 initTreeNode({ id: 'Node 2.1.1', parent: 'Node 2.1', value: 'Value 1' }),
114 initTreeNode({ id: 'Root Node 3', parent: '', value: 'Value 1' }),
115 initTreeNode({ id: 'Node 3.1', parent: 'Root Node 3', value: 'Value 1' }),
116 ].reduce((tree, node) => Tree.setNode(node)(tree), tree);
118 const expandedTree = Tree.expandNodeAncestors(
119 'Node 1.1.1', // Expands 1.1 and 1
120 'Node 2.1', // Expands 2
123 expect(Tree.getNode('Root Node 1')(expandedTree)?.expanded).to.equal(true);
124 expect(Tree.getNode('Node 1.1')(expandedTree)?.expanded).to.equal(true);
125 expect(Tree.getNode('Node 1.1.1')(expandedTree)?.expanded).to.equal(false);
126 expect(Tree.getNode('Node 1.2')(expandedTree)?.expanded).to.equal(false);
127 expect(Tree.getNode('Root Node 2')(expandedTree)?.expanded).to.equal(true);
128 expect(Tree.getNode('Node 2.1')(expandedTree)?.expanded).to.equal(false);
129 expect(Tree.getNode('Node 2.1.1')(expandedTree)?.expanded).to.equal(false);
130 expect(Tree.getNode('Root Node 3')(expandedTree)?.expanded).to.equal(false);
131 expect(Tree.getNode('Node 3.1')(expandedTree)?.expanded).to.equal(false);