Skip to content

Commit 0497d16

Browse files
Add tests for buildFolderTree and create utility functions for test data
1 parent b799188 commit 0497d16

File tree

3 files changed

+136
-39
lines changed

3 files changed

+136
-39
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { describe, expect, it } from 'vitest';
2+
import {
3+
createNestedTreeNodes,
4+
createSimpleTreeNodes,
5+
} from '../../test-utils/bookmarkFactory';
6+
import { buildFolderTree } from '../useFolderTree';
7+
8+
describe('buildFolderTree', () => {
9+
it('filters out bookmarks and returns only folders', () => {
10+
const nodes = createSimpleTreeNodes();
11+
12+
const tree = buildFolderTree(nodes);
13+
14+
expect(tree).toHaveLength(2);
15+
expect(tree[0].title).toBe('Work');
16+
expect(tree[1].title).toBe('Personal');
17+
});
18+
19+
it('sets empty path for root-level folders', () => {
20+
const nodes = createSimpleTreeNodes();
21+
22+
const tree = buildFolderTree(nodes);
23+
24+
expect(tree[0].path).toBe('');
25+
expect(tree[1].path).toBe('');
26+
});
27+
28+
it('builds hierarchical paths using " > " separator', () => {
29+
const nodes = createNestedTreeNodes();
30+
31+
const tree = buildFolderTree(nodes);
32+
33+
expect(tree.find((f) => f.id === '1')?.path).toBe('');
34+
expect(tree.find((f) => f.id === '2')?.path).toBe('Books');
35+
expect(tree.find((f) => f.id === '3')?.path).toBe('Books > Fiction');
36+
});
37+
38+
it('assigns children array to parent folders', () => {
39+
const nodes = createNestedTreeNodes();
40+
41+
const tree = buildFolderTree(nodes);
42+
const books = tree.find((f) => f.id === '1');
43+
const fiction = tree.find((f) => f.id === '2');
44+
45+
expect(books?.children).toHaveLength(1);
46+
expect(books?.children?.[0].id).toBe('2');
47+
expect(fiction?.children).toHaveLength(1);
48+
expect(fiction?.children?.[0].id).toBe('3');
49+
});
50+
51+
it('flattens all folders into a single array', () => {
52+
const nodes = createNestedTreeNodes();
53+
54+
const tree = buildFolderTree(nodes);
55+
56+
// Books + Fiction + Sci-Fi = 3 folders
57+
expect(tree).toHaveLength(3);
58+
expect(tree.map((f) => f.title)).toEqual(['Books', 'Fiction', 'Sci-Fi']);
59+
});
60+
});

src/composables/useFolderTree.ts

Lines changed: 37 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -11,48 +11,46 @@ export interface BookmarkFolder {
1111
children?: BookmarkFolder[];
1212
}
1313

14-
export function useFolderTree() {
15-
const allFolders = ref<BookmarkFolder[]>([]);
16-
const folderMap = ref<Map<string, BookmarkFolder>>(new Map());
14+
export const buildFolderTree = (
15+
nodes: BookmarkTreeNode[],
16+
parentPath = '',
17+
): BookmarkFolder[] => {
18+
const folders: BookmarkFolder[] = [];
1719

18-
const buildFolderTree = (
19-
nodes: BookmarkTreeNode[],
20-
parentPath = '',
21-
level = 0,
22-
): BookmarkFolder[] => {
23-
const folders: BookmarkFolder[] = [];
24-
25-
for (const node of nodes) {
26-
if (!node.url) {
27-
const folder: BookmarkFolder = {
28-
id: node.id,
29-
title: node.title,
30-
path: parentPath,
31-
parentId: node.parentId,
32-
children: [],
33-
};
34-
35-
folders.push(folder);
36-
37-
if (node.children) {
38-
const currentPath = parentPath
39-
? `${parentPath} > ${node.title}`
40-
: node.title;
41-
const childFolders = buildFolderTree(
42-
node.children,
43-
currentPath,
44-
level + 1,
45-
);
46-
folder.children = childFolders.filter(
47-
(child) => child.parentId === node.id,
48-
);
49-
folders.push(...childFolders);
50-
}
51-
}
20+
for (const node of nodes) {
21+
if (node.url) continue;
22+
23+
const folder: BookmarkFolder = {
24+
id: node.id,
25+
title: node.title,
26+
path: parentPath,
27+
parentId: node.parentId,
28+
children: [],
29+
};
30+
31+
folders.push(folder);
32+
33+
if (node.children && node.children.length > 0) {
34+
const currentPath = parentPath
35+
? `${parentPath} > ${node.title}`
36+
: node.title;
37+
38+
const childFolders = buildFolderTree(node.children, currentPath);
39+
40+
folder.children = childFolders.filter(
41+
(child) => child.parentId === node.id,
42+
);
43+
44+
folders.push(...childFolders);
5245
}
46+
}
5347

54-
return folders;
55-
};
48+
return folders;
49+
};
50+
51+
export function useFolderTree() {
52+
const folderMap = ref<Map<string, BookmarkFolder>>(new Map());
53+
const allFolders = ref<BookmarkFolder[]>([]);
5654

5755
const loadFolders = async () => {
5856
try {

src/test-utils/bookmarkFactory.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,3 +155,42 @@ export function createEdgeCaseFolders(): BookmarkFolder[] {
155155
createFolder({ title: 'a' }), // Lowercase single char
156156
];
157157
}
158+
159+
/**
160+
* Preset: Simple tree structure for testing buildFolderTree
161+
*/
162+
export function createSimpleTreeNodes(): BookmarkTreeNode[] {
163+
return [
164+
createNode({ id: '1', title: 'Work', parentId: '0' }),
165+
createNode({ id: '2', title: 'Personal', parentId: '0' }),
166+
createNode({ title: 'Bookmark', url: 'https://example.com' }),
167+
];
168+
}
169+
170+
/**
171+
* Preset: Nested tree structure for testing buildFolderTree
172+
*/
173+
export function createNestedTreeNodes(): BookmarkTreeNode[] {
174+
return [
175+
createNode({
176+
id: '1',
177+
title: 'Books',
178+
parentId: '0',
179+
children: [
180+
createNode({
181+
id: '2',
182+
title: 'Fiction',
183+
parentId: '1',
184+
children: [
185+
createNode({
186+
id: '3',
187+
title: 'Sci-Fi',
188+
parentId: '2',
189+
}),
190+
],
191+
}),
192+
createNode({ title: 'Book URL', url: 'https://example.com' }),
193+
],
194+
}),
195+
];
196+
}

0 commit comments

Comments
 (0)