16
import { assert } from "chai"
17
import { TreeNode } from "../../src/tree/TreeNode"
19
class StringNode extends TreeNode {
20
readonly content: string
22
constructor(content: string, ...children: StringNode[]) {
24
this.content = content
25
this.appendChildren(...children)
33
function contentOf(node: TreeNode) {
34
return (node as StringNode)?.content
37
function assertContent(node: TreeNode, content: string) {
38
assert.equal(contentOf(node), content)
41
function assertRoot(node: TreeNode) {
42
assert.isUndefined(node.parent)
43
assert.equal(node.depth, 0)
44
assert.equal(node.index, -1)
47
function assertLeaf(node: TreeNode) {
48
assert.equal(node.childrenCount, 0)
51
function assertNoChildAt(parent: TreeNode, index: number) {
52
assert.isUndefined(parent.childAt(index))
55
function assertChildAt(parent: TreeNode, index: number): TreeNode {
56
let child = parent.childAt(index)
57
assert.isDefined(child)
58
assert.equal(child?.parent, parent)
59
assert.equal(child?.index, index)
63
function assertToString(root: TreeNode, expected: string) {
64
assert.equal(root.toHierarchy(), expected)
67
function assertRemoveChildrenAt(root: TreeNode, index: number, count: number, expected: number) {
68
let childrenCount = root.childrenCount
69
let children = root.removeChildrenAt(index, count)
70
assert.equal(children.length, expected)
71
assert.equal(root.childrenCount, childrenCount - expected)
72
for (let i = 0; i < expected; i++) {
73
assertRoot(children[i])
77
function createRoot() {
78
return new StringNode("root",
79
new StringNode("first"),
80
new StringNode("second"),
81
new StringNode("third"))
84
function createDigitsRoot() {
85
return new StringNode("digits",
98
suite("TreeNode", () => {
99
test("single node", () => {
100
let node = new StringNode("node")
101
assertContent(node, "node")
105
test("simple root", () => {
106
let root = createRoot()
107
assertContent(root, "root")
109
assert.equal(root.childrenCount, 3)
110
assertNoChildAt(root, Number.MIN_VALUE)
111
assertNoChildAt(root, Number.MAX_VALUE)
112
assertNoChildAt(root, Number.MIN_SAFE_INTEGER)
113
assertNoChildAt(root, Number.MAX_SAFE_INTEGER)
114
assertNoChildAt(root, -1)
115
assertNoChildAt(root, 3)
116
assertNoChildAt(root, 0.1)
117
assertNoChildAt(root, 2.9)
118
let node0 = assertChildAt(root, 0)
119
assertContent(node0, "first")
121
let node1 = assertChildAt(root, 1)
122
assertContent(node1, "second")
124
let node2 = assertChildAt(root, 2)
125
assertContent(node2, "third")
127
const children = root.children.slice()
128
assert.equal(children.length, 3)
129
assert.equal(children[0], node0)
130
assert.equal(children[1], node1)
131
assert.equal(children[2], node2)
138
test("iterate for each child", () => {
139
let root = createRoot()
141
let children = ["first", "second", "third"]
142
root.forEach(node => {
143
assert.equal(children[count], contentOf(node))
146
assert.equal(count, 3)
148
test("iterate for each child with index", () => {
149
let root = createRoot()
151
root.forEach((node, index) => {
152
assert.equal(index, count)
155
assert.equal(count, 3)
157
test("iterate through not every child", () => {
158
let root = createRoot()
160
assert(!root.every(node => {
162
return contentOf(node).length == 5
164
assert.equal(count, 2)
166
test("iterate through every child with index", () => {
167
let root = createRoot()
169
let children = ["first", "second", "third"]
170
assert(root.every((node, index) => {
171
assert.equal(index, count)
173
return children[index] === contentOf(node)
175
assert.equal(count, 3)
177
test("iterate through some children", () => {
178
let root = createRoot()
180
assert(root.some(node => {
182
let size = contentOf(node).length
183
return contentOf(node).length == 6
185
assert.equal(count, 2)
187
test("iterate through some children with index", () => {
188
let root = createRoot()
190
assert(root.some((node, index) => {
191
assert.equal(index, count)
195
assert.equal(count, 1)
197
test("find child by content", () => {
198
let root = createRoot()
199
assert.equal(root.find((node):TreeNode|undefined => contentOf(node) == "second" ? node : undefined), assertChildAt(root, 1))
201
test("find child by index", () => {
202
let root = createRoot()
203
assert.equal(root.find((node, index):TreeNode|undefined => index == 1 ? node : undefined), assertChildAt(root, 1))
205
test("insert, move and remove children", () => {
206
let root = createRoot()
207
assert(!root.removeChild(new StringNode("second")))
213
let second = assertChildAt(root, 1)
214
second.appendChildren(new StringNode("1"), new StringNode("2"), new StringNode("3"))
223
second.removeFromParent()
225
assertToString(second,
234
assert(!root.removeChild(second))
235
assert(root.insertChildAt(0, second))
244
let first = root.removeChildAt(1)
245
assert.isDefined(first)
247
assertContent(first!, "first")
248
root.appendChild(first!)
258
test("insert several children at once", () => {
259
let root = createRoot()
260
let children = [new StringNode("second.1"), new StringNode("second.2"), new StringNode("second.3")]
261
assert(!root.insertChildrenAt(Number.MIN_VALUE, ...children))
262
assert(!root.insertChildrenAt(Number.MAX_VALUE, ...children))
263
assert(!root.insertChildrenAt(Number.MIN_SAFE_INTEGER, ...children))
264
assert(!root.insertChildrenAt(Number.MAX_SAFE_INTEGER, ...children))
265
assert(!root.insertChildrenAt(-1, ...children))
266
assert(!root.insertChildrenAt(4, ...children))
267
assert(!root.insertChildrenAt(0.1, ...children))
268
assert(!root.insertChildrenAt(2.9, ...children))
269
assert(root.insertChildrenAt(2, ...children))
278
assert(root.insertChildrenAt(0, new StringNode("zero")))
288
assert(root.insertChildrenAt(root.childrenCount, new StringNode("third.A"), new StringNode("third.B")))
301
test("remove several children at once", () => {
302
let root = createDigitsRoot()
315
assertRemoveChildrenAt(root, Number.MIN_VALUE, 1, 0)
316
assertRemoveChildrenAt(root, Number.MAX_VALUE, 1, 0)
317
assertRemoveChildrenAt(root, Number.MIN_SAFE_INTEGER, 1, 0)
318
assertRemoveChildrenAt(root, Number.MAX_SAFE_INTEGER, 1, 0)
319
assertRemoveChildrenAt(root, -1, 1, 0)
320
assertRemoveChildrenAt(root, root.childrenCount, 1, 0)
321
assertRemoveChildrenAt(root, 0.1, 1, 0)
322
assertRemoveChildrenAt(root, 2.9, 1, 0)
324
assertRemoveChildrenAt(root, 0, 1 + root.childrenCount, 0)
325
assertRemoveChildrenAt(root, 0, 2, 2)
337
assertRemoveChildrenAt(root, root.childrenCount - 1, 2, 0)
338
assertRemoveChildrenAt(root, root.childrenCount - 2, 2, 2)
348
assertRemoveChildrenAt(root, 1, root.childrenCount, 0)
349
assertRemoveChildrenAt(root, 1, 4, 4)
355
test("remove trailing children at once", () => {
356
let root = createDigitsRoot()
357
assert.equal(root.childrenCount, 10)
358
assert.equal(root.removeChildrenAt(Number.MIN_VALUE).length, 0)
359
assert.equal(root.removeChildrenAt(Number.MAX_VALUE).length, 0)
360
assert.equal(root.removeChildrenAt(Number.MIN_SAFE_INTEGER).length, 0)
361
assert.equal(root.removeChildrenAt(Number.MAX_SAFE_INTEGER).length, 0)
362
assert.equal(root.removeChildrenAt(-1).length, 0)
363
assert.equal(root.removeChildrenAt(root.childrenCount).length, 0)
364
assert.equal(root.removeChildrenAt(0.1).length, 0)
365
assert.equal(root.removeChildrenAt(2.9).length, 0)
366
assert.equal(root.childrenCount, 10)
367
assert.equal(root.removeChildrenAt(7).length, 3)
368
assert.equal(root.childrenCount, 7)
369
assert.equal(root.removeChildrenAt(6).length, 1)
370
assert.equal(root.childrenCount, 6)
371
assert.equal(root.removeChildrenAt(1).length, 5)
372
assert.equal(root.childrenCount, 1)
373
assert.equal(root.removeChildrenAt(0).length, 1)
374
assert.equal(root.childrenCount, 0)