diff --git a/packages/file-graph/fileGraph.js b/packages/file-graph/fileGraph.js index baab3a7..7860a00 100644 --- a/packages/file-graph/fileGraph.js +++ b/packages/file-graph/fileGraph.js @@ -1,5 +1,4 @@ import FileNode from './fileNode.js' -import { FileNotExistsError } from './errors.js' export default class FileGraph { constructor(root) { @@ -22,32 +21,7 @@ export default class FileGraph { // If the file node doesn't exist, throw an error files.forEach((file) => { - const pathFolders = file.path - .split('/') - .filter((folder) => folder.length > 0) - const fileName = pathFolders.pop() - let currentNode = this.root - - for (const folder of pathFolders) { - currentNode = currentNode.children.find( - (child) => child.name === folder - ) - if (!currentNode) { - throw new FileNotExistsError( - `File not found: ${fileToFind.path}, ${this.toString()}` - ) - } - } - - if (!currentNode.children.some((child) => child.name === fileName)) { - throw new FileNotExistsError( - `File not found: ${file.path}, ${this.toString()}` - ) - } else { - currentNode.children = currentNode.children.filter( - (child) => child.name !== fileName - ) - } + this.root.removeChild(file) }) } @@ -56,20 +30,13 @@ export default class FileGraph { // Overwrite the file graph with the provided files // Remove file nodes that don't exist anymore and add new ones - const newRoot = new FileNode({ - path: '/', - type: 'folder', - discovered: true, - }) - eventFiles.forEach((file) => { - newRoot.addChild(file, { makeParents: true }) + this.root.merge(file) }) - - this.root = newRoot } handleEvent(event) { + // eslint-disable-next-line default-case switch (true) { case !!event.add: this.add(event.add) diff --git a/packages/file-graph/fileNode.js b/packages/file-graph/fileNode.js index 1529976..96fc60c 100644 --- a/packages/file-graph/fileNode.js +++ b/packages/file-graph/fileNode.js @@ -52,6 +52,26 @@ export default class FileNode extends File { } } + removeChild(fileToRemove) { + const file = new FileNode(fileToRemove) + const parentPath = dirname(file.path) + + if (parentPath === this.path) { + // Direct child of this node + this.children = this.children.filter((child) => child.path !== file.path) + } else { + // Recursively call removeChild on the correct child node + const childNode = this.children.find((child) => child.contains(file)) + if (childNode) { + childNode.removeChild(file) + } else { + throw new FileNotExistsError( + `File ${file.path} does not exist in the tree: ${this.toString()}` + ) + } + } + } + merge(fileNode) { // Merge the children of the provided file node into this node // If a child already exists, merge the children of that child diff --git a/packages/file-graph/fileNode.test.js b/packages/file-graph/fileNode.test.js index 2b200b6..b58e38f 100644 --- a/packages/file-graph/fileNode.test.js +++ b/packages/file-graph/fileNode.test.js @@ -23,6 +23,15 @@ function mergeTest(files1, files2, expectedFiles) { expect(node1.toString()).toBe(expectedNode.toString()) } +function removeChildTest(files, fileToRemove, expectedFiles) { + const node = createNodeFromFiles(files) + const expectedNode = createNodeFromFiles(expectedFiles) + + node.removeChild(fileToRemove) + + expect(node.toString()).toBe(expectedNode.toString()) +} + describe('FileNode', () => { let rootNode @@ -183,4 +192,30 @@ describe('FileNode', () => { mergeTest(files1, files2, expected) }) + + test('remove-child', () => { + const root = { + path: '/', + type: 'folder', + } + const files = [ + root, + { path: '/a', type: 'file' }, + { path: '/b', type: 'folder' }, + { path: '/b/c', type: 'folder' }, + { path: '/b/d', type: 'file' }, + { path: '/b/c/f', type: 'file' }, + ] + + const fileToRemove = { path: '/b/c', type: 'folder' } + + const expected = [ + root, + { path: '/a', type: 'file' }, + { path: '/b', type: 'folder' }, + { path: '/b/d', type: 'file' }, + ] + + removeChildTest(files, fileToRemove, expected) + }) })