Skip to content

Commit 2f40694

Browse files
committed
feat: 🎸 add print utils
1 parent 903f9e6 commit 2f40694

File tree

5 files changed

+121
-0
lines changed

5 files changed

+121
-0
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import {printBinary} from '../printBinary';
2+
3+
test('renders a single left child', () => {
4+
const str = 'Node' + printBinary('', [() => `foo`]);
5+
expect(str).toBe(
6+
`Node
7+
← foo`,
8+
);
9+
});
10+
11+
test('renders a single right child', () => {
12+
const str = 'Node' + printBinary('', [null, () => `foo`]);
13+
expect(str).toBe(
14+
`Node
15+
β†’ foo`,
16+
);
17+
});
18+
19+
test('renders one level of left and right children', () => {
20+
const str = 'Node' + printBinary('', [() => 'left', () => 'right']);
21+
expect(str).toBe(
22+
`Node
23+
← left
24+
β†’ right`,
25+
);
26+
});
27+
28+
test('renders two levels of left and right children', () => {
29+
const str =
30+
'Node' +
31+
printBinary('', [
32+
(tab) => 'left' + printBinary(tab, [() => 'left', () => 'right']),
33+
(tab) => 'right' + printBinary(tab, [() => 'left', () => 'right']),
34+
]);
35+
expect(str).toBe(
36+
`Node
37+
← left
38+
← left
39+
β†’ right
40+
β†’ right
41+
← left
42+
β†’ right`,
43+
);
44+
});
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import {printTree} from '../printTree';
2+
3+
test('renders a single child node', () => {
4+
const str = 'Node' + printTree('', [() => `foo`]);
5+
6+
expect(str).toBe(
7+
`Node
8+
└─ foo`,
9+
);
10+
});
11+
12+
test('renders two children node', () => {
13+
const str = 'Node' + printTree('', [() => `foo`, () => `bar`]);
14+
15+
expect(str).toBe(
16+
`Node
17+
β”œβ”€ foo
18+
└─ bar`,
19+
);
20+
});
21+
22+
test('renders two levels of nodes', () => {
23+
const str = 'Node' + printTree('', [() => `foo`, (tab) => `bar` + printTree(tab, [() => `baz`])]);
24+
25+
expect(str).toBe(
26+
`Node
27+
β”œβ”€ foo
28+
└─ bar
29+
└─ baz`,
30+
);
31+
});
32+
33+
test('renders two levels of nodes, with double tree line', () => {
34+
const str =
35+
'Node' +
36+
printTree('', [(tab) => `foo` + printTree(tab, [() => `baz`]), (tab) => `bar` + printTree(tab, [() => `baz`])]);
37+
38+
expect(str).toBe(
39+
`Node
40+
β”œβ”€ foo
41+
β”‚ └─ baz
42+
└─ bar
43+
└─ baz`,
44+
);
45+
});

β€Žsrc/print/printBinary.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
type Child = (tab: string) => string;
2+
3+
export const printBinary = (tab = '', children: [left?: null | Child, right?: null | Child]): string => {
4+
const [left, right] = children;
5+
let str = '';
6+
if (left) str += `\n${tab}← ${left(tab + ' ')}`;
7+
if (right) str += `\n${tab}β†’ ${right(tab + ' ')}`;
8+
return str;
9+
};

β€Žsrc/print/printTree.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
type Child = (tab: string) => string;
2+
3+
export const printTree = (tab = '', children: (Child | null)[]): string => {
4+
children = children.filter(Boolean);
5+
let str = '';
6+
for (let i = 0; i < children.length; i++) {
7+
const isLast = i >= children.length - 1;
8+
const fn = children[i];
9+
if (!fn) continue;
10+
const child = fn(tab + `${isLast ? ' ' : 'β”‚'} `);
11+
const branch = child ? (isLast ? '└─' : 'β”œβ”€') : 'β”‚ ';
12+
str += `\n${tab}${branch} ${child}`;
13+
}
14+
return str;
15+
};

β€Žsrc/print/types.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export interface Printable {
2+
/**
3+
* Returns a human-readable tabbed string representation of the object as a tree.
4+
*
5+
* @param tab String to use for indentation.
6+
*/
7+
toString(tab?: string): string;
8+
}

0 commit comments

Comments
Β (0)