this repo has no description
1import assert from 'node:assert/strict'
2import { describe, test } from 'node:test'
3import { type TreeInput, treeify } from './index.js'
4
5describe('treeify utility', () => {
6 test('basic tree with root and children', () => {
7 const input: TreeInput = ['root', ['child1', 'child2', 'child3']]
8 const expected = `root
9├─ child1
10├─ child2
11└─ child3`
12
13 const result = treeify(input)
14 console.log('\nBasic tree with root and children:')
15 console.log(result)
16 assert.strictEqual(result, expected)
17 })
18
19 test('tree with nested children', () => {
20 const input: TreeInput = [
21 'foo',
22 ['bar', 'baz', 'corge', ['qux', ['qui', 'grault', 'garply']]],
23 ]
24 const expected = `foo
25├─ bar
26├─ baz
27└─ corge
28 └─ qux
29 ├─ qui
30 ├─ grault
31 └─ garply`
32
33 const result = treeify(input)
34 console.log('\nTree with nested children:')
35 console.log(result)
36 assert.strictEqual(result, expected)
37 })
38
39 test('deeply nested tree', () => {
40 const input: TreeInput = [
41 'root',
42 [
43 'level1-1',
44 [
45 'level2-1',
46 'level2-2',
47 ['level3-1', 'level3-2', ['level4-1', 'level4-2']],
48 ],
49 'level1-2',
50 ],
51 ]
52 const expected = `root
53├─ level1-1
54│ ├─ level2-1
55│ └─ level2-2
56│ ├─ level3-1
57│ └─ level3-2
58│ ├─ level4-1
59│ └─ level4-2
60└─ level1-2`
61
62 const result = treeify(input)
63 console.log('\nDeeply nested tree:')
64 console.log(result)
65 assert.strictEqual(result, expected)
66 })
67
68 test('tree with multiple deep branches', () => {
69 const input: TreeInput = [
70 'root',
71 [
72 'branch1',
73 ['leaf2-1', ['leaf3-1', 'leaf3-2']],
74 'branch2',
75 ['leaf2-1', ['leaf3-1', ['leaf4-1', 'leaf4-2']]],
76 'leaf1',
77 ],
78 ]
79 const expected = `root
80├─ branch1
81│ └─ leaf2-1
82│ ├─ leaf3-1
83│ └─ leaf3-2
84├─ branch2
85│ └─ leaf2-1
86│ └─ leaf3-1
87│ ├─ leaf4-1
88│ └─ leaf4-2
89└─ leaf1`
90
91 const result = treeify(input)
92 console.log('\nTree with multiple deep branches:')
93 console.log(result)
94 assert.strictEqual(result, expected)
95 })
96
97 test('empty array returns empty string', () => {
98 assert.strictEqual(treeify([] as unknown as TreeInput), '')
99 })
100
101 test('array with only a root returns only the root', () => {
102 assert.strictEqual(treeify(['root'] as TreeInput), 'root')
103 })
104
105 test('multiple strings at root level', () => {
106 const input: TreeInput = ['root', 'second', ['child1', 'child2']]
107 const expected = `root
108second
109├─ child1
110└─ child2`
111
112 const result = treeify(input)
113 console.log('\nMultiple strings at root level:')
114 console.log(result)
115 assert.strictEqual(result, expected)
116 })
117
118 test('consumer-friendly without type annotations', () => {
119 // These don't need type annotations anymore - TypeScript can infer them
120 const input1 = ['root', ['child1', 'child2']]
121 const input2 = ['parent', 'sibling', ['child1', 'child2']]
122 const input3 = ['top', ['middle', ['bottom']]]
123
124 // All of these should work without type errors
125 assert.ok(treeify(input1).includes('root'))
126 assert.ok(treeify(input2).includes('sibling'))
127 assert.ok(treeify(input3).includes('middle'))
128
129 console.log('\nConsumer examples without type annotations:')
130 console.log(treeify(input1))
131 console.log(`\n${treeify(input2)}`)
132 console.log(`\n${treeify(input3)}`)
133 })
134
135 test('plain option uses whitespace instead of Unicode characters', () => {
136 const input: TreeInput = ['root', ['child1', 'child2', ['grandchild']]]
137 const expected = `root
138 child1
139 child2
140 grandchild`
141
142 const result = treeify(input, { plain: true })
143 console.log('\nPlain whitespace tree:')
144 console.log(result)
145 assert.strictEqual(result, expected)
146 })
147
148 test('custom characters can be provided', () => {
149 const input: TreeInput = ['root', ['child1', 'child2']]
150 const customChars = {
151 branch: '├• ',
152 lastBranch: '└• ',
153 pipe: '│ ',
154 space: ' ',
155 }
156 const expected = `root
157├• child1
158└• child2`
159
160 const result = treeify(input, { chars: customChars })
161 console.log('\nCustom character tree:')
162 console.log(result)
163 assert.strictEqual(result, expected)
164 })
165
166 test('custom characters take precedence over plain option', () => {
167 const input: TreeInput = ['root', ['child1', 'child2']]
168 const customChars = {
169 branch: '├• ',
170 lastBranch: '└• ',
171 pipe: '│ ',
172 space: ' ',
173 }
174 const expected = `root
175├• child1
176└• child2`
177
178 const result = treeify(input, { plain: true, chars: customChars })
179 console.log('\nCustom characters with plain option:')
180 console.log(result)
181 assert.strictEqual(result, expected)
182 })
183
184 test('first element must be a string', () => {
185 assert.throws(() => treeify([null, ['child']] as unknown as TreeInput), {
186 message: 'First element must be a string',
187 })
188 assert.throws(() => treeify([1, ['child']] as unknown as TreeInput), {
189 message: 'First element must be a string',
190 })
191 })
192
193 test('empty or invalid input returns empty string', () => {
194 assert.strictEqual(treeify([] as unknown as TreeInput), '')
195 assert.strictEqual(treeify([undefined] as unknown as TreeInput), '')
196 })
197})