From 9b78f0d41c78916af2e7cf0115535e517b700b92 Mon Sep 17 00:00:00 2001 From: wancat Date: Wed, 16 Aug 2023 17:06:21 +0800 Subject: [PATCH] feat: create FileNode class, addChild method --- packages/file-graph/file.js | 16 +++++++ packages/file-graph/fileNode.js | 41 ++++++++++++++++++ packages/file-graph/fileNode.test.js | 64 ++++++++++++++++++++++++++++ packages/file-graph/package.json | 10 +++++ 4 files changed, 131 insertions(+) create mode 100644 packages/file-graph/file.js create mode 100644 packages/file-graph/fileNode.js create mode 100644 packages/file-graph/fileNode.test.js create mode 100644 packages/file-graph/package.json diff --git a/packages/file-graph/file.js b/packages/file-graph/file.js new file mode 100644 index 0000000..3b1feed --- /dev/null +++ b/packages/file-graph/file.js @@ -0,0 +1,16 @@ +export default class File { + constructor({ path, name, type, discovered }) { + this.path = path + this.name = name + this.type = type + this.discovered = discovered + } + + isDirectory() { + return this.type === 'folder' + } + + contains(file) { + return this.isDirectory() && file.path.startsWith(this.path) + } +} diff --git a/packages/file-graph/fileNode.js b/packages/file-graph/fileNode.js new file mode 100644 index 0000000..8b4ec8d --- /dev/null +++ b/packages/file-graph/fileNode.js @@ -0,0 +1,41 @@ +import path from 'path' +import File from './file.js' + +export default class FileNode extends File { + constructor(file) { + super(file) + this.children = [] + } + + addChild(fileInput) { + const file = new File(fileInput) + if (file.path === this.path) { + throw new Error('File already exists in the tree') + } + + const parentPath = path.dirname(file.path) + if (parentPath === this.path) { + // Direct child of this node + this.children.push(new FileNode(file)) + } else { + // Recursively call addChild on the correct child node + const childNode = this.children.find((child) => child.contains(file)) + if (childNode) { + childNode.addChild(file) + } else { + console.log(fileInput, this) + throw new Error('Parent path not found in the tree') + } + } + } + + toString() { + const indent = ' '.repeat(this.path.split('/').length - 1) + const childrenString = this.children + .map((child) => child.toString()) + .join('') + return `${indent}${this.name}${ + this.isDirectory() ? '/' : '' + }\n${childrenString}` + } +} diff --git a/packages/file-graph/fileNode.test.js b/packages/file-graph/fileNode.test.js new file mode 100644 index 0000000..fdb9ec0 --- /dev/null +++ b/packages/file-graph/fileNode.test.js @@ -0,0 +1,64 @@ +import FileNode from './fileNode.js' + +test('addChild method adds a child node to the tree', () => { + const files = [ + { + path: '/home/rudeus', + name: 'rudeus', + type: 'folder', + discovered: 'test', + }, + { + path: '/home/rudeus/.bash_history', + name: '.bash_history', + type: 'file', + discovered: 'test', + }, + { + path: '/home/rudeus/.viminfo', + name: '.viminfo', + type: 'file', + discovered: 'test', + }, + { + path: '/home/rudeus/.zshrc', + name: '.zshrc', + type: 'file', + discovered: 'test', + }, + { + path: '/home/rudeus/forgotten_scroll.txt', + name: 'forgotten_scroll.txt', + type: 'file', + discovered: 'test', + }, + { + path: '/home/rudeus/test', + name: 'test', + type: 'folder', + discovered: 'test', + }, + { + path: '/home/rudeus/test/.b', + name: '.b', + type: 'file', + discovered: false, + }, + { + path: '/home/rudeus/test/a', + name: 'a', + type: 'file', + discovered: false, + }, + ] + + const root = new FileNode(files[0]) + + files.slice(1).forEach((file) => { + root.addChild(file) + }) + + console.log(root.toString()) + + expect(root.children.length).toBe(5) +}) diff --git a/packages/file-graph/package.json b/packages/file-graph/package.json new file mode 100644 index 0000000..69b2535 --- /dev/null +++ b/packages/file-graph/package.json @@ -0,0 +1,10 @@ +{ + "name": "file-graph", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "type": "module", + "scripts": { + "test": "yarn node --experimental-vm-modules $(yarn bin jest)" + } +}