Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
410 changes: 209 additions & 201 deletions package-lock.json

Large diffs are not rendered by default.

62 changes: 59 additions & 3 deletions src/core/dir.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { describe, test, expect, beforeEach, afterEach } from 'vitest';
import { Directory } from './dir.js';

import { TestFilesystemHelper } from '../../test/helpers/testFilesystemHelper.js';
import { File } from './file.js';
import { LoomFile } from './file.js';

describe('Test Directory Service', () => {
test('Create Instance and set path', () => {
Expand All @@ -18,6 +18,18 @@ describe('Test Directory Service', () => {
expect(dir.relativePath(dir2)).toBe('data');
});

test('exists', async () => {
const dir = new Directory('./test/data/');
const exists = await dir.exists();
expect(exists).toBeTruthy();
});

test('not exists', async () => {
const dir = new Directory('./test/data-not-exists');
const exists = await dir.exists();
expect(exists).toBeFalsy();
});

test('path', () => {
const testPath = 'test/data';
const dir = new Directory(`./${testPath}`);
Expand Down Expand Up @@ -54,8 +66,52 @@ describe('Test Directory Service', () => {
testHelper.destroy();
});

test('create', async () => {
const dir = new Directory(testHelper.getBasePath(), 'to_delete');
await dir.create();
const exists = await dir.exists();
expect(exists).toBeTruthy();
});

describe('delete', () => {

test('create and delete a file non recursive', async () => {
const dir = new Directory(testHelper.getBasePath(), 'to_delete');
await dir.create();
expect(await dir.exists()).toBeTruthy();
await dir.delete();
expect(await dir.exists()).toBeFalsy();
});

test('delete a non existing file', async () => {
const dir = new Directory(testHelper.getBasePath(), 'to_delete');
await dir.delete();
expect(await dir.exists()).toBeFalsy();
});

test('try to delete a non existing file with strict mode', async () => {
const dir = new Directory(testHelper.getBasePath(), 'to_delete');
dir.strict();
await expect(dir.delete()).rejects.toThrow();
});

test('delete a non empty directory', async () => {
const dir = new Directory(testHelper.getBasePath(), 'to_delete');
await dir.create();
await testHelper.createFile('some content', {path: 'to_delete/test.txt'});
await expect(dir.delete()).rejects.toThrow();
await expect(dir.exists()).resolves.toBeTruthy();
});

test('delete a non empty directory recursive', async () => {
const dir = new Directory(testHelper.getBasePath(), 'to_delete');
await dir.create();
await testHelper.createFile('some content', {path: 'to_delete/test_some_other'});
await dir.delete(true);
expect(await dir.exists()).toBeFalsy();
});

});
describe('list method', () => {

test('list directory amount', async () => {
Expand Down Expand Up @@ -131,7 +187,7 @@ describe('Test Directory Service', () => {

for(const f of files) {
expect(f).toBeInstanceOf;
expect(await (f as File).text()).toBe('lorem');
expect(await (f as LoomFile).text()).toBe('lorem');
}


Expand All @@ -150,7 +206,7 @@ describe('Test Directory Service', () => {

for(const f of files) {
expect(f).toBeInstanceOf;
expect(await (f as File).text()).toBe('lorem');
expect(await (f as LoomFile).text()).toBe('lorem');
}
});

Expand Down
50 changes: 37 additions & 13 deletions src/core/dir.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,22 @@ import * as fs from 'node:fs/promises';
import { join as joinPath, relative as relativePath, resolve as resolvePath} from 'node:path';
import { LoomFile } from './file.js';
import { List } from './list.js';


import { isErrnoException } from './helper/typechecks.js';

export class Directory {

protected readonly _path: string;
protected _strict: boolean = false;

constructor(
path: string = process.cwd()
path: string = process.cwd(), ...paths: string[]
) {
this._path = resolvePath(path);
this._path = resolvePath(path, ...(paths || []));
}

strict(strictMode: boolean = true) {
this._strict = strictMode;
return this;
}

get path() {
Expand All @@ -26,17 +31,36 @@ export class Directory {
return new Directory(`/${split.join('/')}`);
}

subDir(name: string) {
return new Directory(joinPath(this.path, name));
async exists(): Promise<boolean> {
try {
await fs.access(this.path, fs.constants.R_OK);
return true;
} catch {
return false;
}
}

/**
* @deprecated use subDir
* @param subDir
* @returns
*/
subdir(subDir: string) {
return this.subDir(subDir);
async create(): Promise<void> {
await fs.mkdir(this.path, {recursive: true});
}

async delete(recursive: boolean = false): Promise<void> {
try {
await fs.rmdir(this.path, {recursive});
} catch (err) {
if(this._strict){
throw err;
}
if(isErrnoException(err)) {
if((err as NodeJS.ErrnoException).code !== 'ENOENT' && (err as NodeJS.ErrnoException).errno !== -2) {
throw err;
}
}
}
}

subDir(name: string) {
return new Directory(joinPath(this.path, name));
}

async list(): Promise<List> {
Expand Down
5 changes: 5 additions & 0 deletions src/core/file.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ describe('Test File Service', () => {
const exists = await file.exists();
expect(exists).toBeTruthy();
});
test('If File exists on Object', async () => {
const file = LoomFile.from('./test/data/notexists.json');
const exists = await file.exists();
expect(exists).toBeFalsy();
});

test('Register plugins', async () => {
const plugins = FileTest.getConvertPlugins();
Expand Down
11 changes: 6 additions & 5 deletions src/core/file.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as fs from 'node:fs/promises';
import { existsSync } from 'node:fs';
import { PLUGIN_TYPE, type LoomFSFileConverter, FILE_SIZE_UNIT } from './types.js';
import { FileConvertException, PluginNotFoundException } from './exceptions.js';
import { Directory } from './dir.js';
Expand Down Expand Up @@ -36,10 +35,12 @@ export class LoomFile {
? dirOrPath
: joinPath((dirOrPath as Directory).path, name);

return new Promise((resolve) => {
const exists = existsSync(path);
resolve(exists);
});
try {
await fs.access(path, fs.constants.F_OK);
return true;
} catch {
return false;
}
}

constructor(
Expand Down
3 changes: 3 additions & 0 deletions src/core/helper/typechecks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function isErrnoException(obj: unknown): obj is NodeJS.ErrnoException {
return obj instanceof Error && 'code' in obj && 'errno' in obj;
}
60 changes: 60 additions & 0 deletions src/core/wrapper/dirent.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { describe, test, expect, beforeAll } from 'vitest';
import * as fs from 'fs/promises';
import type { Dirent } from 'fs';
import { DirentWrapper } from './dirent.js';
import { Directory } from '../dir';
import { TestFilesystemHelper } from '../../../test/helpers/testFilesystemHelper';

describe('Test Dirent Service', () => {

let dir: Directory;
let dirent: Dirent;

beforeAll(async () => {
const testHelper = TestFilesystemHelper.init();
(await testHelper).createDir('test');
dir = new Directory((await testHelper).getBasePath());
dirent = (await fs.readdir(dir.path, { withFileTypes: true }))[0];
});

test('Create Instance and set path', async () => {
const direntWrapper = new DirentWrapper(dir, dirent);
expect(direntWrapper).toBeInstanceOf(DirentWrapper);
});

test('isDirectory', async () => {
const direntWrapper = new DirentWrapper(dir, dirent);
expect(direntWrapper.isDirectory()).toBeTruthy();
});

test('isFile', async () => {
const direntWrapper = new DirentWrapper(dir, dirent);
expect(direntWrapper.isFile()).toBeFalsy();
});

test('dirent', async () => {
const direntWrapper = new DirentWrapper(dir, dirent);
expect(direntWrapper.dirent).toBe(dirent);
});

test('dir', async () => {
const direntWrapper = new DirentWrapper(dir, dirent);
expect(direntWrapper.dir).toBe(dir);
});

test('name', async () => {
const direntWrapper = new DirentWrapper(dir, dirent);
expect(direntWrapper.name).toBe('test');
});

test('parentPath', async () => {
const direntWrapper = new DirentWrapper(dir, dirent);
expect(direntWrapper.parentPath).toBe(dir.path);
});

test('path', async () => {
const direntWrapper = new DirentWrapper(dir, dirent);
expect(direntWrapper.path).toBe(`${dir.path}/test`);
});

});