Skip to content

Commit 87b1c50

Browse files
committed
feat: 🎸 trim blank lines, improve performance
1 parent 92e8f9b commit 87b1c50

File tree

3 files changed

+77
-7
lines changed

3 files changed

+77
-7
lines changed

β€Žsrc/__tests__/printTree.spec.tsβ€Ž

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,67 @@ test('renders two levels of nodes, with double tree line', () => {
4343
└─ baz`,
4444
);
4545
});
46+
47+
test('family tree example', () => {
48+
// prettier-ignore
49+
const str = 'Me' + printTree('', [
50+
(tab) => `Father` + printTree(tab, [
51+
(tab) => `Grandfather` + printTree(tab, [
52+
() => `Great-grandfather`,
53+
() => `Great-grandmother`,
54+
]),
55+
() => `Grandmother`,
56+
]),
57+
(tab) => `Mother` + printTree(tab, [
58+
() => `Grandfather`,
59+
() => `Grandmother`,
60+
]),
61+
]);
62+
63+
expect('\n' + str).toBe(
64+
`
65+
Me
66+
β”œβ”€ Father
67+
β”‚ β”œβ”€ Grandfather
68+
β”‚ β”‚ β”œβ”€ Great-grandfather
69+
β”‚ β”‚ └─ Great-grandmother
70+
β”‚ └─ Grandmother
71+
└─ Mother
72+
β”œβ”€ Grandfather
73+
└─ Grandmother`,
74+
);
75+
});
76+
77+
test('can add a blank line', () => {
78+
// prettier-ignore
79+
const str = 'start' + printTree('', [
80+
(tab) => 'line 1',
81+
() => '',
82+
(tab) => 'line 2',
83+
]);
84+
85+
expect('\n' + str).toBe(
86+
`
87+
start
88+
β”œβ”€ line 1
89+
β”‚
90+
└─ line 2`);
91+
});
92+
93+
test('can produce wide tabs', () => {
94+
// prettier-ignore
95+
const str = 'Array' + printTree('', [
96+
(tab) => '[5]: Object' + printTree(tab + ' '.repeat('[5]: '.length), [
97+
(tab) => 'item 1',
98+
(tab) => 'item 2',
99+
]),
100+
]);
101+
102+
expect('\n' + str).toBe(
103+
`
104+
Array
105+
└─ [5]: Object
106+
β”œβ”€ item 1
107+
└─ item 2`);
108+
});
109+

β€Žsrc/printTree.tsβ€Ž

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
type Child = (tab: string) => string;
22

33
export const printTree = (tab = '', children: (Child | null)[]): string => {
4-
children = children.filter(Boolean);
54
let str = '';
6-
for (let i = 0; i < children.length; i++) {
7-
const isLast = i >= children.length - 1;
5+
const length = children.length;
6+
const last = length - 1;
7+
for (let i = 0; i < length; i++) {
88
const fn = children[i];
99
if (!fn) continue;
10-
const child = fn(tab + `${isLast ? ' ' : 'β”‚'} `);
11-
const branch = child ? (isLast ? '└─' : 'β”œβ”€') : 'β”‚ ';
12-
str += `\n${tab}${branch} ${child}`;
10+
const isLast = i === last;
11+
const child = fn(tab + (isLast ? ' ' : 'β”‚') + ' ');
12+
const branch = child ? (isLast ? '└─' : 'β”œβ”€') : 'β”‚';
13+
str += '\n' + tab + branch + (child ? ' ' + child : '');
1314
}
1415
return str;
1516
};

β€Žsrc/types.tsβ€Ž

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1+
/**
2+
* A resource that has `.toString()` with a tabbable output support. Which
3+
* allows to chain the output of multiple objects in a tree-like structure.
4+
*/
15
export interface Printable {
26
/**
3-
* Returns a human-readable tabbed string representation of the object as a tree.
7+
* Returns a human-readable tabbed string representation of the object as a
8+
* tree.
49
*
510
* @param tab String to use for indentation.
611
*/

0 commit comments

Comments
Β (0)